LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/9] Move xparameters.h into xilinx virtex device specific path
From: Grant C. Likely @ 2006-01-19  8:12 UTC (permalink / raw)
  To: linuxppc-embedded, akonovalov, peter.ryser

xparameters should not be needed by anything but virtex platform code.
Move it from include/asm-ppc/ to platforms/4xx/xparameters/

This is preparing for work to remove xparameters from the dependancy tree
for most c files.  xparam changes should not cause a recompile of the world.
Instead, drivers should get device info from the platform bus (populated
by the boot code)

Signed-off-by: Grant C. Likely <grant.likely@secretlab.ca>

---

 arch/ppc/platforms/4xx/virtex-ii_pro.h           |    2 +-
 arch/ppc/platforms/4xx/xparameters/xparameters.h |   18 ++++++++++++++++++
 arch/ppc/syslib/xilinx_pic.c                     |    2 +-
 include/asm-ppc/xparameters.h                    |   18 ------------------
 4 files changed, 20 insertions(+), 20 deletions(-)
 create mode 100644 arch/ppc/platforms/4xx/xparameters/xparameters.h
 delete mode 100644 include/asm-ppc/xparameters.h

3b475f82b10443acded7497a62a9d1dec46f4046
diff --git a/arch/ppc/platforms/4xx/virtex-ii_pro.h b/arch/ppc/platforms/4xx/virtex-ii_pro.h
index 9014c48..026130c 100644
--- a/arch/ppc/platforms/4xx/virtex-ii_pro.h
+++ b/arch/ppc/platforms/4xx/virtex-ii_pro.h
@@ -16,7 +16,7 @@
 #define __ASM_VIRTEXIIPRO_H__
 
 #include <linux/config.h>
-#include <asm/xparameters.h>
+#include <platforms/4xx/xparameters/xparameters.h>
 
 /* serial defines */
 
diff --git a/arch/ppc/platforms/4xx/xparameters/xparameters.h b/arch/ppc/platforms/4xx/xparameters/xparameters.h
new file mode 100644
index 0000000..fe4eac6
--- /dev/null
+++ b/arch/ppc/platforms/4xx/xparameters/xparameters.h
@@ -0,0 +1,18 @@
+/*
+ * include/asm-ppc/xparameters.h
+ *
+ * This file includes the correct xparameters.h for the CONFIG'ed board
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * 2004 (c) MontaVista Software, Inc.  This file is licensed under the terms
+ * of the GNU General Public License version 2.  This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+#include <linux/config.h>
+
+#if defined(CONFIG_XILINX_ML300)
+#include <platforms/4xx/xparameters/xparameters_ml300.h>
+#endif
diff --git a/arch/ppc/syslib/xilinx_pic.c b/arch/ppc/syslib/xilinx_pic.c
index 47f04c7..848fb51 100644
--- a/arch/ppc/syslib/xilinx_pic.c
+++ b/arch/ppc/syslib/xilinx_pic.c
@@ -15,7 +15,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <asm/io.h>
-#include <asm/xparameters.h>
+#include <platforms/4xx/xparameters/xparameters.h>
 #include <asm/ibm4xx.h>
 #include <asm/machdep.h>
 
diff --git a/include/asm-ppc/xparameters.h b/include/asm-ppc/xparameters.h
deleted file mode 100644
index fe4eac6..0000000
--- a/include/asm-ppc/xparameters.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * include/asm-ppc/xparameters.h
- *
- * This file includes the correct xparameters.h for the CONFIG'ed board
- *
- * Author: MontaVista Software, Inc.
- *         source@mvista.com
- *
- * 2004 (c) MontaVista Software, Inc.  This file is licensed under the terms
- * of the GNU General Public License version 2.  This program is licensed
- * "as is" without any warranty of any kind, whether express or implied.
- */
-
-#include <linux/config.h>
-
-#if defined(CONFIG_XILINX_ML300)
-#include <platforms/4xx/xparameters/xparameters_ml300.h>
-#endif
-- 
1.1.GIT

^ permalink raw reply related

* [PATCH 0/9] Xilinx Virtex ML300 & ML403 platform bus support
From: Grant C. Likely @ 2006-01-19  8:11 UTC (permalink / raw)
  To: linuxppc-embedded, akonovalov, peter.ryser

New set of virtex support patches.  Major change here is that the
changes have reverted to using the EDK generated "Linux redefines"
instead of custom #define value.

^ permalink raw reply

* Re: [PATCH 00/10] Updated ML300 & ML403 patches
From: Peter Ryser @ 2006-01-19  7:29 UTC (permalink / raw)
  To: jeffer; +Cc: David H. Lynch Jr., linuxppc-embedded
In-Reply-To: <98d249d60601182314g774ad2bes@mail.gmail.com>

You need to apply a patch to the 2.4 Linux kernel to make it work with 
U-Boot for the MLxxx boards. You can find that patch as part of Xilinx 
Application Note 542 (XAPP542, 
http://direct.xilinx.com/bvdocs/appnotes/xapp542.pdf, 
http://direct.xilinx.com/bvdocs/appnotes/xapp542.zip)

The process on how to apply the patch is described in that application note.

- Peter

PS: The application note is out of date for EDK tools newer than 6.2. 
The patch still works, though.


jeffer wrote:

> Hi at all
>
>
> Since two week I have this Problem and can't solve it. I allready read 
> DULG and search in
> Mailinglists but I can't run linux. Perhaps had the same problem and 
> can help me.
> My Problem:
> After I load the uImage (uImage at 0x00400000 )
> from server, I try to run in with command bootm.
> => bootm 00400000
>  Booting image at  00400000...
>    Image Name:   Linux-2.4.24-pre2
>    Created:      2006-01-19   6:25:03 UTC
>    Image Type:   PowerPC Linux Kernel Image (gzip compressed)
>    Data Size:    700730 Bytes = 684.3 kB
>    Load Address: 00000000
>    Entry Point:  00000000
>    Verifying Checksum ... OK
>    Uncompressing Kernel Image ... OK
>  
>  don't  start kernel
>   my board  :
>   sdram  16m  0----ffffff
>   flash     4m   ffc00000 ---fffffff
>  
>
>     routing, so my current assumption is
>     that I either have VIRTEX_UART defined improperly or I have the
>     ppc_sys
>     data structure created wrong.
>
>
>     >
>     >
>
>            It would be really nice if the was either some comments in
>     xparameters.h or in the Documents directory explaining what the Linux
>     xparameters values are so that it it would be easy to know what items
>     from xparameters_xxx.h have to be mapped or redefined.
>
>
>
>     > This really isn't a big deal anyway; most of this discussion
>     will become
>     > moot in short order.  Sometime in the next few releases,
>     linuxppc will
>     > flip over to using a flattened device tree to pass device
>     information
>     > from the boot loader to the kernel.  xparameters will drop out
>     of the
>     > kernel proper entirely except for the edk-generated device drivers
>     > (which is another issue entirely).  All the xparam stuff will be
>     > extracted into a device tree by u-boot or the zImage wrapper.  The
>     > kernel just won't care.  :)
>            Where can we get more information on what is happening here ?
>     I started the E12 port with most info in xparameters, but I have been
>     moving towards getting things passed in board_info. I am not using
>     u-boot as the E12 has a general purpose elf loader, and it was
>     easier to
>     add a fee lines for Linux. Regardless I would like to be
>     compatible with
>     whatever is coming - maybe even ahead fo the curve. The e12 is
>     just the
>     first of a family of products - the e14 already exists. There maybe
>     revisions of each at different speeds with different memory.
>
>
>     _______________________________________________
>     Linuxppc-embedded mailing list
>     Linuxppc-embedded@ozlabs.org <mailto:Linuxppc-embedded@ozlabs.org>
>     https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>
>------------------------------------------------------------------------
>
>_______________________________________________
>Linuxppc-embedded mailing list
>Linuxppc-embedded@ozlabs.org
>https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>

^ permalink raw reply

* Re: [PATCH 00/10] Updated ML300 & ML403 patches
From: jeffer @ 2006-01-19  7:14 UTC (permalink / raw)
  To: David H. Lynch Jr.; +Cc: linuxppc-embedded
In-Reply-To: <43CEDCE4.5020903@dlasys.net>

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

Hi at all


Since two week I have this Problem and can't solve it. I allready read DULG
and search in
Mailinglists but I can't run linux. Perhaps had the same problem and can
help me.
My Problem:
After I load the uImage (uImage at 0x00400000 )
from server, I try to run in with command bootm.
=> bootm 00400000
 Booting image at  00400000...
   Image Name:   Linux-2.4.24-pre2
   Created:      2006-01-19   6:25:03 UTC
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    700730 Bytes = 684.3 kB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK

 don't  start kernel
  my board  :
  sdram  16m  0----ffffff
  flash     4m   ffc00000 ---fffffff


> routing, so my current assumption is
> that I either have VIRTEX_UART defined improperly or I have the ppc_sys
> data structure created wrong.
>
>
> >
> >
>
>        It would be really nice if the was either some comments in
> xparameters.h or in the Documents directory explaining what the Linux
> xparameters values are so that it it would be easy to know what items
> from xparameters_xxx.h have to be mapped or redefined.
>
>
>
> > This really isn't a big deal anyway; most of this discussion will become
> > moot in short order.  Sometime in the next few releases, linuxppc will
> > flip over to using a flattened device tree to pass device information
> > from the boot loader to the kernel.  xparameters will drop out of the
> > kernel proper entirely except for the edk-generated device drivers
> > (which is another issue entirely).  All the xparam stuff will be
> > extracted into a device tree by u-boot or the zImage wrapper.  The
> > kernel just won't care.  :)
>        Where can we get more information on what is happening here ?
> I started the E12 port with most info in xparameters, but I have been
> moving towards getting things passed in board_info. I am not using
> u-boot as the E12 has a general purpose elf loader, and it was easier to
> add a fee lines for Linux. Regardless I would like to be compatible with
> whatever is coming - maybe even ahead fo the curve. The e12 is just the
> first of a family of products - the e14 already exists. There maybe
> revisions of each at different speeds with different memory.
>
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>

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

^ permalink raw reply

* [PATCH] powerpc: remove useless spinlock from mpc83xx watchdog
From: Kumar Gala @ 2006-01-19  6:58 UTC (permalink / raw)
  To: Andrew Morton, wim; +Cc: linux-kernel, linuxppc-embedded

Since we can only open the watchdog once having a spinlock to protect
multiple access is pointless.

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

---
commit 8852c088c0624f5534b08a769b5887c42a211694
tree 04ad05af51efb90604ff86af48197b6b7b45f77a
parent 1161d00ace361999d5b98bbe3082da4c8d457ba3
author Kumar Gala <galak@kernel.crashing.org> Thu, 19 Jan 2006 01:03:09 -0600
committer Kumar Gala <galak@kernel.crashing.org> Thu, 19 Jan 2006 01:03:09 -0600

 drivers/char/watchdog/mpc83xx_wdt.c |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/drivers/char/watchdog/mpc83xx_wdt.c b/drivers/char/watchdog/mpc83xx_wdt.c
index 5d6f506..b310144 100644
--- a/drivers/char/watchdog/mpc83xx_wdt.c
+++ b/drivers/char/watchdog/mpc83xx_wdt.c
@@ -57,15 +57,12 @@ static int prescale = 1;
 static unsigned int timeout_sec;
 
 static unsigned long wdt_is_open;
-static spinlock_t wdt_spinlock;
 
 static void mpc83xx_wdt_keepalive(void)
 {
 	/* Ping the WDT */
-	spin_lock(&wdt_spinlock);
 	out_be16(&wd_base->swsrr, 0x556c);
 	out_be16(&wd_base->swsrr, 0xaa39);
-	spin_unlock(&wdt_spinlock);
 }
 
 static ssize_t mpc83xx_wdt_write(struct file *file, const char __user *buf,
@@ -184,8 +181,6 @@ static int __devinit mpc83xx_wdt_probe(s
 		"mode:%s timeout=%d (%d seconds)\n",
 		reset ? "reset":"interrupt", timeout, timeout_sec);
 
-	spin_lock_init(&wdt_spinlock);
-
 	return 0;
 
 err_unmap:

^ permalink raw reply related

* Re: [PATCH 00/10] Updated ML300 & ML403 patches
From: Grant Likely @ 2006-01-19  5:11 UTC (permalink / raw)
  To: Peter Ryser
  Cc: Grant Likely, Andrei Konovalov, Rick Moleres, linuxppc-embedded
In-Reply-To: <43CECEA4.4050908@xilinx.com>

Peter Ryser wrote:
> 
>> Yeah, the head of Linus' tree is busted.  Doing a cg-seek 
>> 67daf5f11f06b9b15f8320de1d237ccc2e74fe43 will work, but you first need 
>> to remove the following line from arch/ppc/kernel/ppc_ksyms.c
>>
>> EXPORT_SYMBOL(get_wchan);
>>
> After applying your patches to the branch-point you mention above, 
> removing that symbol, and configuring for the ML403 I can get to a boot 
> prompt. Good.
> 
> Doing the same for the ML300, though, does not work, i.e. I get a single 
> line saying:
> "Data machine check in kernel mode."

update you git to 2.6.16-rc1, and apply this patch:

http://www.ussg.iu.edu/hypermail/linux/kernel/0601.2/0301.html

Then apply the patches and try again.


-- 
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
(403) 663-0761

^ permalink raw reply

* Re: [PATCH] dtc: add bus-frequency prop to SOC node
From: David Gibson @ 2006-01-19  1:29 UTC (permalink / raw)
  To: Becky Bruce; +Cc: linuxppc-dev
In-Reply-To: <Pine.LNX.4.61.0601180917080.11236@cde-tx32-ldt329.sps.mot.com>

On Wed, Jan 18, 2006 at 09:20:58AM -0600, Becky Bruce wrote:
> Updated SOC node definition in documentation to include bus-frequency
> property. Also extended mdio example to match specification.
> 
> Signed-off-by: Becky Bruce <becky.bruce@freescale.com>

Looks sane enough to me, but I don't think I'm the right person to be
assessing changes to this document merely because it's hosted in the
dtc git tree for now.  I'll apply if I get an Ack from Paulus or BenH.

Had a brief chat to Paulus - we might look at moving this document to
Documentation/ in the kernel tree, arguably a better place for it.

-- 
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

* RFC: [PATCH] snd-pmac-gpio interface
From: Ben Collins @ 2006-01-18 23:46 UTC (permalink / raw)
  To: linuxppc-dev

Attached are the patches I've come up with for a central snd-pmac-gpio
interface (for toonie and tumbler). This was BenH's suggestion.

It uses platform functions, but falls back on direct gpio. I had to
guess some of the tumbler/toonie consolidation for direct gpio fallback,
and I can't test tumbler.

Anyway, the first patch adds the snd-pmac-gpio.[ch] to the build. The
second and third patches are toonie and tumbler conversions to this
interface.

BenH, these patches are against 2.6.15, and so depend on the patches I
sent you previously to backport the pmac_pfunc interfaces. They should
apply and work with current 2.6.16-git without those patches.

I've tested the toonie on my G4 PB 17" (PowerBook5,9). You'll need to
add 0x54 to the toonie list in pmac.c for that to work (BenH, you might
want to just do that one-liner by hand, but I can send an actual diff if
you need). I still have an issue with toonie on this PB, in that it
doesn't work initially until I cause a headphone/lineout interrupt
(plug/unplug headphones). I might have fixed this in the below patch,
but I haven't rebooted to see if it comes up correctly or not.


diff -urN linux-2.6/sound/ppc/Makefile linux-source-2.6.15-2.6.15/sound/ppc/Makefile
--- linux-2.6/sound/ppc/Makefile	2006-01-17 20:19:28.000000000 -0500
+++ linux-source-2.6.15-2.6.15/sound/ppc/Makefile	2006-01-17 20:30:40.000000000 -0500
@@ -3,7 +3,8 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o toonie.o keywest.o beep.o
+snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o \
+	toonie.o keywest.o beep.o snd-pmac-gpio.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o
diff -urN linux-2.6/sound/ppc/snd-pmac-gpio.c linux-source-2.6.15-2.6.15/sound/ppc/snd-pmac-gpio.c
--- linux-2.6/sound/ppc/snd-pmac-gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-source-2.6.15-2.6.15/sound/ppc/snd-pmac-gpio.c	2006-01-18 17:56:26.000000000 -0500
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2005 by Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * Copyright (c) 2006 by Ben Collins <bcollins@ubuntu.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <asm/pmac_feature.h>
+#include "snd-pmac-gpio.h"
+#include "pmac.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+
+static struct pmf_function *get_audio_pfunc(const char *name, const char *altname)
+{
+	struct device_node *np;
+	struct pmf_function *pfunc = NULL;
+
+	if (! (np = find_devices("i2s-a")))
+		return NULL;
+
+	pfunc = pmf_find_function(np, name);
+	if (pfunc == NULL && altname != NULL)
+		pfunc = pmf_find_function(np, altname);
+
+	return pfunc;
+}
+
+static struct device_node *find_audio_device(const char *name,
+					     const char *altname)
+{
+	struct device_node *np;
+
+	if (! (np = find_devices("gpio")))
+		return NULL;
+
+	for (np = np->child; np; np = np->sibling) {
+		char *property = get_property(np, "audio-gpio", NULL);
+		if (property && (strcmp(property, name) == 0 ||
+		    strcmp(property, altname) == 0))
+			break;
+		if (device_is_compatible(np, name) ||
+		    device_is_compatible(np, altname))
+			break;
+        }
+
+	return np;
+}
+
+static int get_audio_gpio(const char *name, const char *altname,
+			  snd_pmac_gpio_t *gp)
+{
+	struct device_node *np;
+	u32 *base, addr;
+
+	if (!(np = find_audio_device(name, altname)))
+		return -ENODEV;
+
+	base = (u32 *)get_property(np, "AAPL,address", NULL);
+	if (! base) {
+		base = (u32 *)get_property(np, "reg", NULL);
+		if (!base) {
+			DBG("(E) cannot find address for device %s !\n", name);
+			return -ENODEV;
+		}
+		addr = *base;
+		if (addr < 0x50)
+			addr += 0x50;
+	} else
+		addr = *base;
+
+	gp->addr = addr & 0x0000ffff;
+
+	/* Try to find the active state, default to 0 ! */
+	base = (u32 *)get_property(np, "audio-gpio-active-state", NULL);
+	if (base) {
+		gp->active_state = *base;
+		gp->active_val = (*base) ? 0x5 : 0x4;
+		gp->inactive_val = (*base) ? 0x4 : 0x5;
+	} else {
+		/* Don't expect this to work. If platform-do isn't
+		 * available (pmac_pfunc), and the above didn't work, then
+		 * these are probably wrong.
+		 */
+		gp->active_state = 0;
+		gp->active_val = 0x4;
+		gp->inactive_val = 0x5;
+	}
+
+	DBG("(I) GPIO device %s found, offset: %x, active state: %d !\n",
+	    name, gp->addr, gp->active_state);
+
+	gp->irq = (np->n_intrs > 0) ? np->intrs[0].line : 0;
+
+	return 0;
+}
+
+int snd_pmac_get_gpio(const char *name, const char *altname,
+                            snd_pmac_gpio_t *gp)
+{
+        memset(gp, 0, sizeof(*gp));
+
+	gp->name = name;
+	gp->altname = altname;
+
+        /* Platform functions are prefered */
+        if ((gp->pfunc = get_audio_pfunc(name, altname)))
+                return 0;
+
+	/* Else, fallback to direct gpio */
+	return get_audio_gpio(name, altname, gp);
+}
+
+void snd_pmac_free_gpio(snd_pmac_gpio_t *gp)
+{
+	if (gp->pfunc != NULL) {
+		if (gp->irq_client.owner == THIS_MODULE) {
+			/* XXX: pmf_unregister_irq_client doesn't use its
+			 * first two arguments. We only need to send it
+			 * the irq_client. WATCH FOR THIS CHANGING!
+			 */
+			pmf_unregister_irq_client(NULL, NULL, &gp->irq_client);
+			gp->irq_client.owner = NULL;
+		}
+
+		pmf_put_function(gp->pfunc);
+		gp->pfunc = NULL;
+	} else if (gp->addr) {
+		if (gp->irq > 0) {
+			free_irq(gp->irq, gp);
+			gp->irq = 0;
+		}
+		gp->addr = 0;
+	}
+}
+
+int snd_pmac_write_gpio(snd_pmac_gpio_t *gp, u32 val)
+{
+	int ret = -ENODEV;
+
+	if (gp->pfunc) {
+		struct pmf_args args;
+
+		args.count = 1;
+		args.u[0].v = val;
+
+		ret = pmf_call_one(gp->pfunc, &args);
+	} else if (gp->addr) {
+		val = val ? gp->active_val : gp->inactive_val;
+
+		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gp->addr, val);
+
+		ret = 0;
+	}
+
+	if (!ret)
+		gp->state = val;
+
+	return -EINVAL;
+}
+
+int snd_pmac_read_gpio(snd_pmac_gpio_t *gp, u32 *val)
+{
+	int ret = -EINVAL;
+
+	if (gp->pfunc) {
+		struct pmf_args args;
+
+		args.count = 1;
+		args.u[0].p = val;
+
+		ret = pmf_call_one(gp->pfunc, &args);
+	} else if (gp->addr) {
+		int ret = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL,
+					    gp->addr, 0);
+
+		ret = ((ret & 0x02) != 0);
+		*val = ret == gp->active_state;
+
+		ret = 0;
+	}
+
+	return -EINVAL;
+}
+
+u32 snd_pmac_gpio_internal_state(snd_pmac_gpio_t *gp)
+{
+	return gp->state;
+}
+
+static irqreturn_t snd_pmac_intr(int irq, void *data, struct pt_regs *regs)
+{
+	snd_pmac_gpio_t *gp = data;
+
+	gp->irq_client.handler(gp->irq_client.data);
+
+	return IRQ_HANDLED;
+}
+
+int snd_pmac_request_irq(snd_pmac_gpio_t *gp, void (*handler)(void *),
+			 void *data)
+{
+	int ret = -ENODEV;
+	struct device_node *np;
+
+	gp->irq_client.handler = handler;
+	gp->irq_client.data = data;
+	gp->irq_client.owner = NULL;
+
+	if (gp->pfunc) {
+		gp->irq_client.owner = THIS_MODULE;
+
+		if ((np = find_devices("i2s-a"))) {
+			ret = pmf_register_irq_client(np, gp->name, &gp->irq_client);
+			if (ret < 0)
+				ret = pmf_register_irq_client(np, gp->altname, &gp->irq_client);
+		}
+		if (ret < 0)
+			gp->irq_client.owner = NULL;
+	} else if (gp->irq > 0) {
+		ret = request_irq(gp->irq, snd_pmac_intr, 0, gp->name, gp);
+		if (ret < 0)
+			gp->irq = 0;
+	}
+
+	return ret;
+}
diff -urN linux-2.6/sound/ppc/snd-pmac-gpio.h linux-source-2.6.15-2.6.15/sound/ppc/snd-pmac-gpio.h
--- linux-2.6/sound/ppc/snd-pmac-gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-source-2.6.15-2.6.15/sound/ppc/snd-pmac-gpio.h	2006-01-18 17:56:07.000000000 -0500
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005 by Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * Copyright (c) 2006 by Ben Collins <bcollins@ubuntu.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef SND_PMAC_GPIO_H
+#define SND_PMAC_GPIO_H 1
+
+#include <asm/pmac_pfunc.h>
+
+typedef struct snd_pmac_gpio {
+	struct pmf_function *pfunc;
+        unsigned int addr;
+        u8 active_val;
+        u8 inactive_val;
+        u8 active_state;
+	u32 state;
+
+	/* Used by irq functions */
+	int irq;
+	struct pmf_irq_client irq_client;
+	const char *name;
+	const char *altname;
+} snd_pmac_gpio_t;
+
+/* Return a handle for access to the named gpio */
+int snd_pmac_get_gpio(const char *name, const char *altname,
+		      snd_pmac_gpio_t *gp);
+
+/* Frees resources related to the gpio handle */
+void snd_pmac_free_gpio(snd_pmac_gpio_t *gp);
+
+/* GPIO Operations */
+int snd_pmac_write_gpio(snd_pmac_gpio_t *gp, u32 val);
+int snd_pmac_read_gpio(snd_pmac_gpio_t *gp, u32 *val);
+
+/* Used to get the internal state of a write only gpio */
+u32 snd_pmac_gpio_internal_state(snd_pmac_gpio_t *gp);
+
+/* Register an irq for a previously allocated gpio. This is automaticlly
+ * freed in snd_pmac_free_cpio. */
+int snd_pmac_request_irq(snd_pmac_gpio_t *gp, void (*handler)(void *),
+			 void *data);
+
+static inline int snd_pmac_gpio_valid(snd_pmac_gpio_t *gp)
+{
+	return (gp->pfunc || gp->addr) ? 1 : 0;
+}
+#endif /* SND_PMAC_GPIO_H */


diff -urN linux-2.6/sound/ppc/toonie.c linux-source-2.6.15-2.6.15/sound/ppc/toonie.c
--- linux-2.6/sound/ppc/toonie.c	2006-01-17 20:19:28.000000000 -0500
+++ linux-source-2.6.15-2.6.15/sound/ppc/toonie.c	2006-01-18 18:07:50.000000000 -0500
@@ -31,7 +31,9 @@
 #include <asm/irq.h>
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
+
 #include "pmac.h"
+#include "snd-pmac-gpio.h"
 
 #undef DEBUG
 
@@ -41,61 +43,34 @@
 #define DBG(fmt...)
 #endif
 
-struct pmac_gpio {
-	unsigned int addr;
-	u8 active_val;
-	u8 inactive_val;
-	u8 active_state;
-};
-
 struct pmac_toonie
 {
-	struct pmac_gpio	hp_detect_gpio;
-	struct pmac_gpio	hp_mute_gpio;
-	struct pmac_gpio	amp_mute_gpio;
-	int			hp_detect_irq;
+	snd_pmac_gpio_t		hp_detect_gpio;
+	snd_pmac_gpio_t		hp_mute_gpio;
+	snd_pmac_gpio_t		amp_mute_gpio;
+
 	int			auto_mute_notify;
 	struct work_struct	detect_work;
 };
 
 
-/*
- * gpio access
- */
-#define do_gpio_write(gp, val) \
-	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, (gp)->addr, val)
-#define do_gpio_read(gp) \
-	pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, (gp)->addr, 0)
-#define tumbler_gpio_free(gp) /* NOP */
-
-static void write_audio_gpio(struct pmac_gpio *gp, int active)
+static void toonie_reset_audio(pmac_t *chip)
 {
-	if (! gp->addr)
-		return;
-	active = active ? gp->active_val : gp->inactive_val;
-	do_gpio_write(gp, active);
-	DBG("(I) gpio %x write %d\n", gp->addr, active);
-}
+	snd_pmac_gpio_t gpio;
 
-static int check_audio_gpio(struct pmac_gpio *gp)
-{
-	int ret;
+	if (snd_pmac_get_gpio("audio-hw-reset", "hw-reset", &gpio))
+		return;
 
-	if (! gp->addr)
-		return 0;
+	DBG("(I) codec normal reset !\n");
 
-	ret = do_gpio_read(gp);
+	snd_pmac_write_gpio(&gpio, 0);
+	msleep(200);
+	snd_pmac_write_gpio(&gpio, 1);
+	msleep(100);
+	snd_pmac_write_gpio(&gpio, 0);
+	msleep(100);
 
-	return (ret & 0xd) == (gp->active_val & 0xd);
-}
-
-static int read_audio_gpio(struct pmac_gpio *gp)
-{
-	int ret;
-	if (! gp->addr)
-		return 0;
-	ret = ((do_gpio_read(gp) & 0x02) !=0);
-	return ret == gp->active_state;
+	snd_pmac_free_gpio(&gpio);
 }
 
 
@@ -106,10 +81,11 @@
 {
 	pmac_t *chip = snd_kcontrol_chip(kcontrol);
 	struct pmac_toonie *mix = chip->mixer_data;
-	struct pmac_gpio *gp;
+	snd_pmac_gpio_t *gp;
 
 	if (mix == NULL)
 		return -ENODEV;
+
 	switch(kcontrol->private_value) {
 	case TOONIE_MUTE_HP:
 		gp = &mix->hp_mute_gpio;
@@ -120,7 +96,7 @@
 	default:
 		return -EINVAL;;
 	}
-	ucontrol->value.integer.value[0] = !check_audio_gpio(gp);
+	ucontrol->value.integer.value[0] = !snd_pmac_gpio_internal_state(gp);
 	return 0;
 }
 
@@ -129,8 +105,7 @@
 {
 	pmac_t *chip = snd_kcontrol_chip(kcontrol);
 	struct pmac_toonie *mix = chip->mixer_data;
-	struct pmac_gpio *gp;
-	int val;
+	snd_pmac_gpio_t *gp;
 
 	if (chip->update_automute && chip->auto_mute)
 		return 0; /* don't touch in the auto-mute mode */
@@ -148,9 +123,8 @@
 	default:
 		return -EINVAL;;
 	}
-	val = ! check_audio_gpio(gp);
-	if (val != ucontrol->value.integer.value[0]) {
-		write_audio_gpio(gp, ! ucontrol->value.integer.value[0]);
+	if (snd_pmac_gpio_internal_state(gp) != ucontrol->value.integer.value[0]) {
+		snd_pmac_write_gpio(gp, ! ucontrol->value.integer.value[0]);
 		return 1;
 	}
 	return 0;
@@ -181,20 +155,21 @@
 	struct pmac_toonie *mix = chip->mixer_data;
 	int detect = 0;
 
-	if (mix->hp_detect_gpio.addr)
-		detect |= read_audio_gpio(&mix->hp_detect_gpio);
+	snd_pmac_read_gpio(&mix->hp_detect_gpio, &detect);
+
 	return detect;
 }
 
-static void toonie_check_mute(pmac_t *chip, struct pmac_gpio *gp, int val,
-			      int do_notify, snd_kcontrol_t *sw)
+static int toonie_do_mute(pmac_t *chip, snd_pmac_gpio_t *gp, int val,
+			   int do_notify, snd_kcontrol_t *sw)
 {
-	if (check_audio_gpio(gp) != val) {
-		write_audio_gpio(gp, val);
-		if (do_notify)
-			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
-				       &sw->id);
-	}
+	snd_pmac_write_gpio(gp, val);
+
+	if (do_notify)
+		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &sw->id);
+
+	return val;
 }
 
 static void toonie_detect_handler(void *self)
@@ -211,20 +186,20 @@
 
 	headphone = toonie_detect_headphone(chip);
 
-	DBG("headphone: %d, lineout: %d\n", headphone, lineout);
+	DBG("headphone: %d\n", headphone);
 
 	if (headphone) {
 		/* unmute headphone/lineout & mute speaker */
-		toonie_check_mute(chip, &mix->hp_mute_gpio, 0,
-				  mix->auto_mute_notify, chip->master_sw_ctl);
-		toonie_check_mute(chip, &mix->amp_mute_gpio, 1,
-				  mix->auto_mute_notify, chip->speaker_sw_ctl);
+		toonie_do_mute(chip, &mix->hp_mute_gpio, 0,
+			       mix->auto_mute_notify, chip->master_sw_ctl);
+		toonie_do_mute(chip, &mix->amp_mute_gpio, 1,
+			       mix->auto_mute_notify, chip->speaker_sw_ctl);
 	} else {
 		/* unmute speaker, mute others */
-		toonie_check_mute(chip, &mix->amp_mute_gpio, 0,
-				  mix->auto_mute_notify, chip->speaker_sw_ctl);
-		toonie_check_mute(chip, &mix->hp_mute_gpio, 1,
-				  mix->auto_mute_notify, chip->master_sw_ctl);
+		toonie_do_mute(chip, &mix->amp_mute_gpio, 0,
+			       mix->auto_mute_notify, chip->speaker_sw_ctl);
+		toonie_do_mute(chip, &mix->hp_mute_gpio, 1,
+			       mix->auto_mute_notify, chip->master_sw_ctl);
 	}
 	if (mix->auto_mute_notify) {
 		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
@@ -244,85 +219,12 @@
 }
 
 /* interrupt - headphone plug changed */
-static irqreturn_t toonie_hp_intr(int irq, void *devid, struct pt_regs *regs)
+static void toonie_hp_intr(void *devid)
 {
 	pmac_t *chip = devid;
 
-	if (chip->update_automute && chip->initialized) {
+	if (chip->update_automute && chip->initialized)
 		chip->update_automute(chip, 1);
-		return IRQ_HANDLED;
-	}
-	return IRQ_NONE;
-}
-
-/* look for audio gpio device */
-static int find_audio_gpio(const char *name, const char *platform,
-			   struct pmac_gpio *gp)
-{
-	struct device_node *np;
-  	u32 *base, addr;
-
-	if (! (np = find_devices("gpio")))
-		return -ENODEV;
-
-	for (np = np->child; np; np = np->sibling) {
-		char *property = get_property(np, "audio-gpio", NULL);
-		if (property && strcmp(property, name) == 0)
-			break;
-		if (device_is_compatible(np, name))
-			break;
-	}
-	if (np == NULL)
-		return -ENODEV;
-
-	base = (u32 *)get_property(np, "AAPL,address", NULL);
-	if (! base) {
-		base = (u32 *)get_property(np, "reg", NULL);
-		if (!base) {
-			DBG("(E) cannot find address for device %s !\n", name);
-			return -ENODEV;
-		}
-		addr = *base;
-		if (addr < 0x50)
-			addr += 0x50;
-	} else
-		addr = *base;
-
-	gp->addr = addr & 0x0000ffff;
-
-	/* Try to find the active state, default to 0 ! */
-	base = (u32 *)get_property(np, "audio-gpio-active-state", NULL);
-	if (base) {
-		gp->active_state = *base;
-		gp->active_val = (*base) ? 0x5 : 0x4;
-		gp->inactive_val = (*base) ? 0x4 : 0x5;
-	} else {
-		u32 *prop = NULL;
-		gp->active_state = 0;
-		gp->active_val = 0x4;
-		gp->inactive_val = 0x5;
-		/* Here are some crude hacks to extract the GPIO polarity and
-		 * open collector informations out of the do-platform script
-		 * as we don't yet have an interpreter for these things
-		 */
-		if (platform)
-			prop = (u32 *)get_property(np, platform, NULL);
-		if (prop) {
-			if (prop[3] == 0x9 && prop[4] == 0x9) {
-				gp->active_val = 0xd;
-				gp->inactive_val = 0xc;
-			}
-			if (prop[3] == 0x1 && prop[4] == 0x1) {
-				gp->active_val = 0x5;
-				gp->inactive_val = 0x4;
-			}
-		}
-	}
-
-	DBG("(I) GPIO device %s found, offset: %x, active state: %d !\n",
-	    name, gp->addr, gp->active_state);
-
-	return (np->n_intrs > 0) ? np->intrs[0].line : 0;
 }
 
 static void toonie_cleanup(pmac_t *chip)
@@ -330,8 +232,11 @@
 	struct pmac_toonie *mix = chip->mixer_data;
 	if (! mix)
 		return;
-	if (mix->hp_detect_irq >= 0)
-		free_irq(mix->hp_detect_irq, chip);
+
+	snd_pmac_free_gpio(&mix->hp_mute_gpio);
+	snd_pmac_free_gpio(&mix->amp_mute_gpio);
+	snd_pmac_free_gpio(&mix->hp_detect_gpio);
+
 	kfree(mix);
 	chip->mixer_data = NULL;
 }
@@ -340,17 +245,20 @@
 {
 	struct pmac_toonie *mix;
 
-	mix = kmalloc(sizeof(*mix), GFP_KERNEL);
+	mix = kzalloc(sizeof(*mix), GFP_KERNEL);
 	if (! mix)
 		return -ENOMEM;
 
 	chip->mixer_data = mix;
 	chip->mixer_free = toonie_cleanup;
 
-	find_audio_gpio("headphone-mute", NULL, &mix->hp_mute_gpio);
-	find_audio_gpio("amp-mute", NULL, &mix->amp_mute_gpio);
-	mix->hp_detect_irq = find_audio_gpio("headphone-detect",
-					     NULL, &mix->hp_detect_gpio);
+	/* Atleast have to have these two */
+	if (snd_pmac_get_gpio("headphone-mute", "lineout-mute",
+			      &mix->hp_mute_gpio) ||
+	    snd_pmac_get_gpio("amp-mute", NULL,
+			      &mix->amp_mute_gpio)) {
+		return -ENODEV;
+	}
 
 	strcpy(chip->card->mixername, "PowerMac Toonie");
 
@@ -362,18 +270,24 @@
 
 	INIT_WORK(&mix->detect_work, toonie_detect_handler, (void *)chip);
 
-	if (mix->hp_detect_irq >= 0) {
+	if (!snd_pmac_get_gpio("headphone-detect", "lineout-detect",
+			       &mix->hp_detect_gpio)) {
+		u32 val;
+
 		snd_pmac_add_automute(chip);
 
 		chip->detect_headphone = toonie_detect_headphone;
 		chip->update_automute = toonie_update_automute;
 		toonie_update_automute(chip, 0);
 
-		if (request_irq(mix->hp_detect_irq, toonie_hp_intr, 0,
-				"Sound Headphone Detection", chip) < 0)
-			mix->hp_detect_irq = -1;
-	}
+		snd_pmac_request_irq(&mix->hp_detect_gpio, toonie_hp_intr, chip);
+
+		/* Activate headphone status interrupts */
+		snd_pmac_read_gpio(&mix->hp_detect_gpio, &val);
+		snd_pmac_write_gpio(&mix->hp_detect_gpio, val | 0x80);
+		}
+
+	toonie_reset_audio(chip);
 
 	return 0;
 }
-


diff -urN linux-2.6/sound/ppc/tumbler.c linux-source-2.6.15-2.6.15/sound/ppc/tumbler.c
--- linux-2.6/sound/ppc/tumbler.c	2006-01-17 20:19:28.000000000 -0500
+++ linux-source-2.6.15-2.6.15/sound/ppc/tumbler.c	2006-01-18 17:57:56.000000000 -0500
@@ -37,7 +37,9 @@
 #include <asm/irq.h>
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
+
 #include "pmac.h"
+#include "snd-pmac-gpio.h"
 #include "tumbler_volume.h"
 
 #undef DEBUG
@@ -82,23 +84,15 @@
 	VOL_IDX_LAST_MIX
 };
 
-typedef struct pmac_gpio {
-	unsigned int addr;
-	u8 active_val;
-	u8 inactive_val;
-	u8 active_state;
-} pmac_gpio_t;
-
 typedef struct pmac_tumbler_t {
 	pmac_keywest_t i2c;
-	pmac_gpio_t audio_reset;
-	pmac_gpio_t amp_mute;
-	pmac_gpio_t line_mute;
-	pmac_gpio_t line_detect;
-	pmac_gpio_t hp_mute;
-	pmac_gpio_t hp_detect;
-	int headphone_irq;
-	int lineout_irq;
+	snd_pmac_gpio_t audio_reset;
+	snd_pmac_gpio_t amp_mute;
+	snd_pmac_gpio_t line_mute;
+	snd_pmac_gpio_t line_detect;
+	snd_pmac_gpio_t hp_mute;
+	snd_pmac_gpio_t hp_detect;
+
 	unsigned int save_master_vol[2];
 	unsigned int master_vol[2];
 	unsigned int save_master_switch[2];
@@ -163,45 +157,6 @@
 	DBG("(I) snapper init client\n");
 	return send_init_client(i2c, regs);
 }
-	
-/*
- * gpio access
- */
-#define do_gpio_write(gp, val) \
-	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, (gp)->addr, val)
-#define do_gpio_read(gp) \
-	pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, (gp)->addr, 0)
-#define tumbler_gpio_free(gp) /* NOP */
-
-static void write_audio_gpio(pmac_gpio_t *gp, int active)
-{
-	if (! gp->addr)
-		return;
-	active = active ? gp->active_val : gp->inactive_val;
-	do_gpio_write(gp, active);
-	DBG("(I) gpio %x write %d\n", gp->addr, active);
-}
-
-static int check_audio_gpio(pmac_gpio_t *gp)
-{
-	int ret;
-
-	if (! gp->addr)
-		return 0;
-
-	ret = do_gpio_read(gp);
-
-	return (ret & 0xd) == (gp->active_val & 0xd);
-}
-
-static int read_audio_gpio(pmac_gpio_t *gp)
-{
-	int ret;
-	if (! gp->addr)
-		return 0;
-	ret = ((do_gpio_read(gp) & 0x02) !=0);
-	return ret == gp->active_state;
-}
 
 /*
  * update master volume
@@ -680,7 +635,9 @@
 {
 	pmac_t *chip = snd_kcontrol_chip(kcontrol);
 	pmac_tumbler_t *mix;
-	pmac_gpio_t *gp;
+	snd_pmac_gpio_t *gp;
+	int cur;
+
 	if (! (mix = chip->mixer_data))
 		return -ENODEV;
 	switch(kcontrol->private_value) {
@@ -695,7 +652,9 @@
 	}
 	if (gp == NULL)
 		return -EINVAL;
-	ucontrol->value.integer.value[0] = !check_audio_gpio(gp);
+
+	snd_pmac_read_gpio(gp, &cur);
+	ucontrol->value.integer.value[0] = !cur;
 	return 0;
 }
 
@@ -703,7 +662,7 @@
 {
 	pmac_t *chip = snd_kcontrol_chip(kcontrol);
 	pmac_tumbler_t *mix;
-	pmac_gpio_t *gp;
+	snd_pmac_gpio_t *gp;
 	int val;
 #ifdef PMAC_SUPPORT_AUTOMUTE
 	if (chip->update_automute && chip->auto_mute)
@@ -723,9 +682,11 @@
 	}
 	if (gp == NULL)
 		return -EINVAL;
-	val = ! check_audio_gpio(gp);
+
+	snd_pmac_read_gpio(gp, &val);
+	val = !val;
 	if (val != ucontrol->value.integer.value[0]) {
-		write_audio_gpio(gp, ! ucontrol->value.integer.value[0]);
+		snd_pmac_write_gpio(gp, ! ucontrol->value.integer.value[0]);
 		return 1;
 	}
 	return 0;
@@ -893,7 +854,7 @@
 	int detect = 0;
 
 	if (mix->hp_detect.addr)
-		detect |= read_audio_gpio(&mix->hp_detect);
+		snd_pmac_read_gpio(&mix->hp_detect, &detect);
 	return detect;
 }
 
@@ -903,14 +864,17 @@
 	int detect = 0;
 
 	if (mix->line_detect.addr)
-		detect |= read_audio_gpio(&mix->line_detect);
+		snd_pmac_read_gpio(&mix->line_detect, &detect);
 	return detect;
 }
 
-static void check_mute(pmac_t *chip, pmac_gpio_t *gp, int val, int do_notify, snd_kcontrol_t *sw)
+static void check_mute(pmac_t *chip, snd_pmac_gpio_t *gp, int val, int do_notify, snd_kcontrol_t *sw)
 {
-	if (check_audio_gpio(gp) != val) {
-		write_audio_gpio(gp, val);
+	int cur;
+	snd_pmac_read_gpio(gp, &cur);
+
+	if (cur != val) {
+		snd_pmac_write_gpio(gp, val);
 		if (do_notify)
 			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
 				       &sw->id);
@@ -993,111 +957,11 @@
 
 
 /* interrupt - headphone plug changed */
-static irqreturn_t headphone_intr(int irq, void *devid, struct pt_regs *regs)
+static void headphone_intr(void *devid)
 {
 	pmac_t *chip = devid;
-	if (chip->update_automute && chip->initialized) {
+	if (chip->update_automute && chip->initialized)
 		chip->update_automute(chip, 1);
-		return IRQ_HANDLED;
-	}
-	return IRQ_NONE;
-}
-
-/* look for audio-gpio device */
-static struct device_node *find_audio_device(const char *name)
-{
-	struct device_node *np;
-  
-	if (! (np = find_devices("gpio")))
-		return NULL;
-  
-	for (np = np->child; np; np = np->sibling) {
-		char *property = get_property(np, "audio-gpio", NULL);
-		if (property && strcmp(property, name) == 0)
-			return np;
-	}  
-	return NULL;
-}
-
-/* look for audio-gpio device */
-static struct device_node *find_compatible_audio_device(const char *name)
-{
-	struct device_node *np;
-  
-	if (! (np = find_devices("gpio")))
-		return NULL;
-  
-	for (np = np->child; np; np = np->sibling) {
-		if (device_is_compatible(np, name))
-			return np;
-	}  
-	return NULL;
-}
-
-/* find an audio device and get its address */
-static long tumbler_find_device(const char *device, const char *platform, pmac_gpio_t *gp, int is_compatible)
-{
-	struct device_node *node;
-	u32 *base, addr;
-
-	if (is_compatible)
-		node = find_compatible_audio_device(device);
-	else
-		node = find_audio_device(device);
-	if (! node) {
-		DBG("(W) cannot find audio device %s !\n", device);
-		snd_printdd("cannot find device %s\n", device);
-		return -ENODEV;
-	}
-
-	base = (u32 *)get_property(node, "AAPL,address", NULL);
-	if (! base) {
-		base = (u32 *)get_property(node, "reg", NULL);
-		if (!base) {
-			DBG("(E) cannot find address for device %s !\n", device);
-			snd_printd("cannot find address for device %s\n", device);
-			return -ENODEV;
-		}
-		addr = *base;
-		if (addr < 0x50)
-			addr += 0x50;
-	} else
-		addr = *base;
-
-	gp->addr = addr & 0x0000ffff;
-	/* Try to find the active state, default to 0 ! */
-	base = (u32 *)get_property(node, "audio-gpio-active-state", NULL);
-	if (base) {
-		gp->active_state = *base;
-		gp->active_val = (*base) ? 0x5 : 0x4;
-		gp->inactive_val = (*base) ? 0x4 : 0x5;
-	} else {
-		u32 *prop = NULL;
-		gp->active_state = 0;
-		gp->active_val = 0x4;
-		gp->inactive_val = 0x5;
-		/* Here are some crude hacks to extract the GPIO polarity and
-		 * open collector informations out of the do-platform script
-		 * as we don't yet have an interpreter for these things
-		 */
-		if (platform)
-			prop = (u32 *)get_property(node, platform, NULL);
-		if (prop) {
-			if (prop[3] == 0x9 && prop[4] == 0x9) {
-				gp->active_val = 0xd;
-				gp->inactive_val = 0xc;
-			}
-			if (prop[3] == 0x1 && prop[4] == 0x1) {
-				gp->active_val = 0x5;
-				gp->inactive_val = 0x4;
-			}
-		}
-	}
-
-	DBG("(I) GPIO device %s found, offset: %x, active state: %d !\n",
-	    device, gp->addr, gp->active_state);
-
-	return (node->n_intrs > 0) ? node->intrs[0].line : 0;
 }
 
 /* reset audio */
@@ -1107,23 +971,23 @@
 
 	if (mix->anded_reset) {
 		DBG("(I) codec anded reset !\n");
-		write_audio_gpio(&mix->hp_mute, 0);
-		write_audio_gpio(&mix->amp_mute, 0);
+		snd_pmac_write_gpio(&mix->hp_mute, 0);
+		snd_pmac_write_gpio(&mix->amp_mute, 0);
 		msleep(200);
-		write_audio_gpio(&mix->hp_mute, 1);
-		write_audio_gpio(&mix->amp_mute, 1);
+		snd_pmac_write_gpio(&mix->hp_mute, 1);
+		snd_pmac_write_gpio(&mix->amp_mute, 1);
 		msleep(100);
-		write_audio_gpio(&mix->hp_mute, 0);
-		write_audio_gpio(&mix->amp_mute, 0);
+		snd_pmac_write_gpio(&mix->hp_mute, 0);
+		snd_pmac_write_gpio(&mix->amp_mute, 0);
 		msleep(100);
 	} else {
 		DBG("(I) codec normal reset !\n");
 
-		write_audio_gpio(&mix->audio_reset, 0);
+		snd_pmac_write_gpio(&mix->audio_reset, 0);
 		msleep(200);
-		write_audio_gpio(&mix->audio_reset, 1);
+		snd_pmac_write_gpio(&mix->audio_reset, 1);
 		msleep(100);
-		write_audio_gpio(&mix->audio_reset, 0);
+		snd_pmac_write_gpio(&mix->audio_reset, 0);
 		msleep(100);
 	}
 }
@@ -1134,10 +998,6 @@
 {
 	pmac_tumbler_t *mix = chip->mixer_data;
 
-	if (mix->headphone_irq >= 0)
-		disable_irq(mix->headphone_irq);
-	if (mix->lineout_irq >= 0)
-		disable_irq(mix->lineout_irq);
 	mix->save_master_switch[0] = mix->master_switch[0];
 	mix->save_master_switch[1] = mix->master_switch[1];
 	mix->save_master_vol[0] = mix->master_vol[0];
@@ -1145,18 +1005,18 @@
 	mix->master_switch[0] = mix->master_switch[1] = 0;
 	tumbler_set_master_volume(mix);
 	if (!mix->anded_reset) {
-		write_audio_gpio(&mix->amp_mute, 1);
-		write_audio_gpio(&mix->hp_mute, 1);
+		snd_pmac_write_gpio(&mix->amp_mute, 1);
+		snd_pmac_write_gpio(&mix->hp_mute, 1);
 	}
 	if (chip->model == PMAC_SNAPPER) {
 		mix->acs |= 1;
 		i2c_smbus_write_byte_data(mix->i2c.client, TAS_REG_ACS, mix->acs);
 	}
 	if (mix->anded_reset) {
-		write_audio_gpio(&mix->amp_mute, 1);
-		write_audio_gpio(&mix->hp_mute, 1);
+		snd_pmac_write_gpio(&mix->amp_mute, 1);
+		snd_pmac_write_gpio(&mix->hp_mute, 1);
 	} else
-		write_audio_gpio(&mix->audio_reset, 1);
+		snd_pmac_write_gpio(&mix->audio_reset, 1);
 }
 
 /* resume mixer */
@@ -1194,69 +1054,39 @@
 	tumbler_set_master_volume(mix);
 	if (chip->update_automute)
 		chip->update_automute(chip, 0);
-	if (mix->headphone_irq >= 0) {
-		unsigned char val;
+	if (snd_pmac_gpio_valid(&mix->hp_detect)) {
+		int val;
 
-		enable_irq(mix->headphone_irq);
 		/* activate headphone status interrupts */
-		val = do_gpio_read(&mix->hp_detect);
-		do_gpio_write(&mix->hp_detect, val | 0x80);
+		snd_pmac_read_gpio(&mix->hp_detect, &val);
+		snd_pmac_write_gpio(&mix->hp_detect, val | 0x80);
 	}
-	if (mix->lineout_irq >= 0)
-		enable_irq(mix->lineout_irq);
 }
 #endif
 
 /* initialize tumbler */
 static int __init tumbler_init(pmac_t *chip)
 {
-	int irq;
+	int ret = 0;
+
 	pmac_tumbler_t *mix = chip->mixer_data;
 	snd_assert(mix, return -EINVAL);
 
-	if (tumbler_find_device("audio-hw-reset",
-				"platform-do-hw-reset",
-				&mix->audio_reset, 0) < 0)
-		tumbler_find_device("hw-reset",
-				    "platform-do-hw-reset",
-				    &mix->audio_reset, 1);
-	if (tumbler_find_device("amp-mute",
-				"platform-do-amp-mute",
-				&mix->amp_mute, 0) < 0)
-		tumbler_find_device("amp-mute",
-				    "platform-do-amp-mute",
-				    &mix->amp_mute, 1);
-	if (tumbler_find_device("headphone-mute",
-				"platform-do-headphone-mute",
-				&mix->hp_mute, 0) < 0)
-		tumbler_find_device("headphone-mute",
-				    "platform-do-headphone-mute",
-				    &mix->hp_mute, 1);
-	if (tumbler_find_device("line-output-mute",
-				"platform-do-lineout-mute",
-				&mix->line_mute, 0) < 0)
-		tumbler_find_device("line-output-mute",
-				   "platform-do-lineout-mute",
-				    &mix->line_mute, 1);
-	irq = tumbler_find_device("headphone-detect",
-				  NULL, &mix->hp_detect, 0);
-	if (irq < 0)
-		irq = tumbler_find_device("headphone-detect",
-					  NULL, &mix->hp_detect, 1);
-	if (irq < 0)
-		irq = tumbler_find_device("keywest-gpio15",
-					  NULL, &mix->hp_detect, 1);
-	mix->headphone_irq = irq;
- 	irq = tumbler_find_device("line-output-detect",
-				  NULL, &mix->line_detect, 0);
- 	if (irq < 0)
-		irq = tumbler_find_device("line-output-detect",
-					  NULL, &mix->line_detect, 1);
-	mix->lineout_irq = irq;
+	ret |= snd_pmac_get_gpio("audio-hw-reset", "hw-reset",
+				 &mix->audio_reset);
+	ret |= snd_pmac_get_gpio("amp-mute", NULL, &mix->amp_mute);
+	ret |= snd_pmac_get_gpio("headphone-mute", NULL, &mix->hp_mute);
+	ret |= snd_pmac_get_gpio("line-output-mute", "lineout-mute",
+				 &mix->line_mute);
+
+	snd_pmac_get_gpio("headphone-detect", "keywest-gpio15",
+			  &mix->hp_detect);
+	snd_pmac_get_gpio("line-output-detect", "lineout-detect",
+			  &mix->line_detect);
 
 	tumbler_reset_audio(chip);
   
-	return 0;
+	return ret;
 }
 
 static void tumbler_cleanup(pmac_t *chip)
@@ -1265,15 +1095,14 @@
 	if (! mix)
 		return;
 
-	if (mix->headphone_irq >= 0)
-		free_irq(mix->headphone_irq, chip);
-	if (mix->lineout_irq >= 0)
-		free_irq(mix->lineout_irq, chip);
-	tumbler_gpio_free(&mix->audio_reset);
-	tumbler_gpio_free(&mix->amp_mute);
-	tumbler_gpio_free(&mix->hp_mute);
-	tumbler_gpio_free(&mix->hp_detect);
+	snd_pmac_free_gpio(&mix->audio_reset);
+	snd_pmac_free_gpio(&mix->amp_mute);
+	snd_pmac_free_gpio(&mix->hp_mute);
+	snd_pmac_free_gpio(&mix->hp_detect);
+	snd_pmac_free_gpio(&mix->line_detect);
+
 	snd_pmac_keywest_cleanup(&mix->i2c);
+
 	kfree(mix);
 	chip->mixer_data = NULL;
 }
@@ -1296,7 +1125,6 @@
 	if (! mix)
 		return -ENOMEM;
 	memset(mix, 0, sizeof(*mix));
-	mix->headphone_irq = -1;
 
 	chip->mixer_data = mix;
 	chip->mixer_free = tumbler_cleanup;
@@ -1395,7 +1223,7 @@
 	INIT_WORK(&device_change, device_change_handler, (void *)chip);
 
 #ifdef PMAC_SUPPORT_AUTOMUTE
-	if ((mix->headphone_irq >=0 || mix->lineout_irq >= 0)
+	if ((snd_pmac_gpio_valid(&mix->hp_detect) || snd_pmac_gpio_valid(&mix->line_detect))
 	    && (err = snd_pmac_add_automute(chip)) < 0)
 		return err;
 	chip->detect_headphone = tumbler_detect_headphone;
@@ -1403,23 +1231,25 @@
 	tumbler_update_automute(chip, 0); /* update the status only */
 
 	/* activate headphone status interrupts */
-  	if (mix->headphone_irq >= 0) {
-		unsigned char val;
-		if ((err = request_irq(mix->headphone_irq, headphone_intr, 0,
-				       "Sound Headphone Detection", chip)) < 0)
+  	if (snd_pmac_gpio_valid(&mix->hp_detect)) {
+		u32 val;
+
+		if (snd_pmac_request_irq(&mix->hp_detect, headphone_intr, chip) < 0)
 			return 0;
+
 		/* activate headphone status interrupts */
-		val = do_gpio_read(&mix->hp_detect);
-		do_gpio_write(&mix->hp_detect, val | 0x80);
+		snd_pmac_read_gpio(&mix->hp_detect, &val);
+		snd_pmac_write_gpio(&mix->hp_detect, val | 0x80);
 	}
-  	if (mix->lineout_irq >= 0) {
-		unsigned char val;
-		if ((err = request_irq(mix->lineout_irq, headphone_intr, 0,
-				       "Sound Lineout Detection", chip)) < 0)
+  	if (snd_pmac_gpio_valid(&mix->line_detect)) {
+		u32 val;
+
+		if (snd_pmac_request_irq(&mix->line_detect, headphone_intr, chip) < 0)
 			return 0;
+
 		/* activate headphone status interrupts */
-		val = do_gpio_read(&mix->line_detect);
-		do_gpio_write(&mix->line_detect, val | 0x80);
+		snd_pmac_read_gpio(&mix->line_detect, &val);
+		snd_pmac_write_gpio(&mix->line_detect, val | 0x80);
 	}
 #endif
 


--
Ben Collins
Kernel Developer
Ubuntu Linux

^ permalink raw reply

* Re: [PATCH 00/10] Updated ML300 & ML403 patches
From: David H. Lynch Jr. @ 2006-01-19  0:27 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <43CC9F35.8010305@secretlab.ca>

Grant Likely wrote:
> Let's keep this conversation on the mailing list.
> 
> Peter Ryser wrote:
> 
>>Hi Grant and Andrei,
>>
>>I'm glad to see some activity on the linuxppc email alias for the MLxxx 
>>boards and appreciate the work put into moving the 2.4 support to 2.6.
>>
>>I just tried to boot the 2.6 kernel with Grant's patches applied to 
>>Linus' latest tree on both the ML300 and the ML403 and in both cases end 
>>up with the PLB Error LED lit up. Both boards print the messages from 
>>the bootloader, print "Now booting the kernel" and then nothing (but the 
>>error LED). Anything you can think of that is going wrong?

	I am getting the same problem when I use Grant's patches. In my
instance I have isolated the problem to hanging in
ppc_sys_get_pdata(VIRTEX_UART).
This appears to be a fairly trivial routing, so my current assumption is
that I either have VIRTEX_UART defined improperly or I have the ppc_sys
data structure created wrong.


>>Anyway, there is another issue that I would like to bring up and it has 
>>to do with xparameters.h. The xparameters.h file, or more exactly, the 
>>xparameters_* file, is automatically generated by EDK and is then used 
>>to configure the devices in the Linux kernel at compile time. While I 
>>understand the desire to get away from a static device definition to 
>>device enumeration at run-time, the current set of patches is a step 
>>backwards for users from a useability point of view. Users will now have 
>>to modify xparameters*.h by hand which is an error-prone process. 
> 
> 
> Actually, users should *never* modifiy generated files.  The intent is 
> that board specific fixups go directly into the top level xparameters.h 
> so that newly generated files don't have to be touched.  But yes, I 
> understand what you mean.
> 
> 

	It would be really nice if the was either some comments in
xparameters.h or in the Documents directory explaining what the Linux
xparameters values are so that it it would be easy to know what items
from xparameters_xxx.h have to be mapped or redefined.



> This really isn't a big deal anyway; most of this discussion will become 
> moot in short order.  Sometime in the next few releases, linuxppc will 
> flip over to using a flattened device tree to pass device information 
> from the boot loader to the kernel.  xparameters will drop out of the 
> kernel proper entirely except for the edk-generated device drivers 
> (which is another issue entirely).  All the xparam stuff will be 
> extracted into a device tree by u-boot or the zImage wrapper.  The 
> kernel just won't care.  :)
	Where can we get more information on what is happening here ?
I started the E12 port with most info in xparameters, but I have been
moving towards getting things passed in board_info. I am not using
u-boot as the E12 has a general purpose elf loader, and it was easier to
add a fee lines for Linux. Regardless I would like to be compatible with
whatever is coming - maybe even ahead fo the curve. The e12 is just the
first of a family of products - the e14 already exists. There maybe
revisions of each at different speeds with different memory.

^ permalink raw reply

* RFC: [PATCH Upated]: snd-pmac-gpio interfaces for snd-powermac
From: Ben Collins @ 2006-01-19  0:28 UTC (permalink / raw)
  To: Linuxppc-dev

This corrects a problem in the tumbler and toonie conversion. Also fixes
a small naming change requested by BenH in snd-pmac-gpio.c

diff -urN linux-2.6/sound/ppc/Makefile linux-source-2.6.15-2.6.15/sound/ppc/Makefile
--- linux-2.6/sound/ppc/Makefile	2006-01-17 20:19:28.000000000 -0500
+++ linux-source-2.6.15-2.6.15/sound/ppc/Makefile	2006-01-17 20:30:40.000000000 -0500
@@ -3,7 +3,8 @@
 # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
 #
 
-snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o toonie.o keywest.o beep.o
+snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o \
+	toonie.o keywest.o beep.o snd-pmac-gpio.o
 
 # Toplevel Module Dependency
 obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o
diff -urN linux-2.6/sound/ppc/snd-pmac-gpio.c linux-source-2.6.15-2.6.15/sound/ppc/snd-pmac-gpio.c
--- linux-2.6/sound/ppc/snd-pmac-gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-source-2.6.15-2.6.15/sound/ppc/snd-pmac-gpio.c	2006-01-18 19:08:17.000000000 -0500
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2005 by Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * Copyright (c) 2006 by Ben Collins <bcollins@ubuntu.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <asm/pmac_feature.h>
+#include "snd-pmac-gpio.h"
+#include "pmac.h"
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+
+static struct pmf_function *get_audio_pfunc(const char *name, const char *altname)
+{
+	struct device_node *np;
+	struct pmf_function *pfunc = NULL;
+
+	if (! (np = find_devices("i2s-a")))
+		return NULL;
+
+	pfunc = pmf_find_function(np, name);
+	if (pfunc == NULL && altname != NULL)
+		pfunc = pmf_find_function(np, altname);
+
+	return pfunc;
+}
+
+static struct device_node *find_audio_gpio(const char *name,
+					   const char *altname)
+{
+	struct device_node *np;
+
+	if (! (np = find_devices("gpio")))
+		return NULL;
+
+	for (np = np->child; np; np = np->sibling) {
+		char *property = get_property(np, "audio-gpio", NULL);
+		if (property && (strcmp(property, name) == 0 ||
+		    strcmp(property, altname) == 0))
+			break;
+		if (device_is_compatible(np, name) ||
+		    device_is_compatible(np, altname))
+			break;
+        }
+
+	return np;
+}
+
+static int get_audio_gpio(const char *name, const char *altname,
+			  snd_pmac_gpio_t *gp)
+{
+	struct device_node *np;
+	u32 *base, addr;
+
+	if (!(np = find_audio_gpio(name, altname)))
+		return -ENODEV;
+
+	base = (u32 *)get_property(np, "AAPL,address", NULL);
+	if (! base) {
+		base = (u32 *)get_property(np, "reg", NULL);
+		if (!base) {
+			DBG("(E) cannot find address for device %s !\n", name);
+			return -ENODEV;
+		}
+		addr = *base;
+		if (addr < 0x50)
+			addr += 0x50;
+	} else
+		addr = *base;
+
+	gp->addr = addr & 0x0000ffff;
+
+	/* Try to find the active state, default to 0 ! */
+	base = (u32 *)get_property(np, "audio-gpio-active-state", NULL);
+	if (base) {
+		gp->active_state = *base;
+		gp->active_val = (*base) ? 0x5 : 0x4;
+		gp->inactive_val = (*base) ? 0x4 : 0x5;
+	} else {
+		/* Don't expect this to work. If platform-do isn't
+		 * available (pmac_pfunc), and the above didn't work, then
+		 * these are probably wrong.
+		 */
+		gp->active_state = 0;
+		gp->active_val = 0x4;
+		gp->inactive_val = 0x5;
+	}
+
+	DBG("(I) GPIO device %s found, offset: %x, active state: %d !\n",
+	    name, gp->addr, gp->active_state);
+
+	gp->irq = (np->n_intrs > 0) ? np->intrs[0].line : 0;
+
+	return 0;
+}
+
+int snd_pmac_get_gpio(const char *name, const char *altname,
+                            snd_pmac_gpio_t *gp)
+{
+        memset(gp, 0, sizeof(*gp));
+
+	gp->name = name;
+	gp->altname = altname;
+
+        /* Platform functions are prefered */
+        if ((gp->pfunc = get_audio_pfunc(name, altname)))
+                return 0;
+
+	/* Else, fallback to direct gpio */
+	return get_audio_gpio(name, altname, gp);
+}
+
+void snd_pmac_free_gpio(snd_pmac_gpio_t *gp)
+{
+	if (gp->pfunc != NULL) {
+		if (gp->irq_client.owner == THIS_MODULE) {
+			/* XXX: pmf_unregister_irq_client doesn't use its
+			 * first two arguments. We only need to send it
+			 * the irq_client. WATCH FOR THIS CHANGING!
+			 */
+			pmf_unregister_irq_client(NULL, NULL, &gp->irq_client);
+			gp->irq_client.owner = NULL;
+		}
+
+		pmf_put_function(gp->pfunc);
+		gp->pfunc = NULL;
+	} else if (gp->addr) {
+		if (gp->irq > 0) {
+			free_irq(gp->irq, gp);
+			gp->irq = 0;
+		}
+		gp->addr = 0;
+	}
+}
+
+int snd_pmac_write_gpio(snd_pmac_gpio_t *gp, u32 val)
+{
+	int ret = -ENODEV;
+
+	if (gp->pfunc) {
+		struct pmf_args args;
+
+		args.count = 1;
+		args.u[0].v = val;
+
+		ret = pmf_call_one(gp->pfunc, &args);
+	} else if (gp->addr) {
+		val = val ? gp->active_val : gp->inactive_val;
+
+		pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gp->addr, val);
+
+		ret = 0;
+	}
+
+	if (!ret)
+		gp->state = val;
+
+	return -EINVAL;
+}
+
+int snd_pmac_read_gpio(snd_pmac_gpio_t *gp, u32 *val)
+{
+	int ret = -EINVAL;
+
+	if (gp->pfunc) {
+		struct pmf_args args;
+
+		args.count = 1;
+		args.u[0].p = val;
+
+		ret = pmf_call_one(gp->pfunc, &args);
+	} else if (gp->addr) {
+		int ret = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL,
+					    gp->addr, 0);
+
+		ret = ((ret & 0x02) != 0);
+		*val = ret == gp->active_state;
+
+		ret = 0;
+	}
+
+	return -EINVAL;
+}
+
+u32 snd_pmac_gpio_internal_state(snd_pmac_gpio_t *gp)
+{
+	return gp->state;
+}
+
+static irqreturn_t snd_pmac_intr(int irq, void *data, struct pt_regs *regs)
+{
+	snd_pmac_gpio_t *gp = data;
+
+	gp->irq_client.handler(gp->irq_client.data);
+
+	return IRQ_HANDLED;
+}
+
+int snd_pmac_request_irq(snd_pmac_gpio_t *gp, void (*handler)(void *),
+			 void *data)
+{
+	int ret = -ENODEV;
+	struct device_node *np;
+
+	gp->irq_client.handler = handler;
+	gp->irq_client.data = data;
+	gp->irq_client.owner = NULL;
+
+	if (gp->pfunc) {
+		gp->irq_client.owner = THIS_MODULE;
+
+		if ((np = find_devices("i2s-a"))) {
+			ret = pmf_register_irq_client(np, gp->name, &gp->irq_client);
+			if (ret < 0)
+				ret = pmf_register_irq_client(np, gp->altname, &gp->irq_client);
+		}
+		if (ret < 0)
+			gp->irq_client.owner = NULL;
+	} else if (gp->irq > 0) {
+		ret = request_irq(gp->irq, snd_pmac_intr, 0, gp->name, gp);
+		if (ret < 0)
+			gp->irq = 0;
+	}
+
+	return ret;
+}
diff -urN linux-2.6/sound/ppc/snd-pmac-gpio.h linux-source-2.6.15-2.6.15/sound/ppc/snd-pmac-gpio.h
--- linux-2.6/sound/ppc/snd-pmac-gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-source-2.6.15-2.6.15/sound/ppc/snd-pmac-gpio.h	2006-01-18 17:56:07.000000000 -0500
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005 by Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ * Copyright (c) 2006 by Ben Collins <bcollins@ubuntu.com>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#ifndef SND_PMAC_GPIO_H
+#define SND_PMAC_GPIO_H 1
+
+#include <asm/pmac_pfunc.h>
+
+typedef struct snd_pmac_gpio {
+	struct pmf_function *pfunc;
+        unsigned int addr;
+        u8 active_val;
+        u8 inactive_val;
+        u8 active_state;
+	u32 state;
+
+	/* Used by irq functions */
+	int irq;
+	struct pmf_irq_client irq_client;
+	const char *name;
+	const char *altname;
+} snd_pmac_gpio_t;
+
+/* Return a handle for access to the named gpio */
+int snd_pmac_get_gpio(const char *name, const char *altname,
+		      snd_pmac_gpio_t *gp);
+
+/* Frees resources related to the gpio handle */
+void snd_pmac_free_gpio(snd_pmac_gpio_t *gp);
+
+/* GPIO Operations */
+int snd_pmac_write_gpio(snd_pmac_gpio_t *gp, u32 val);
+int snd_pmac_read_gpio(snd_pmac_gpio_t *gp, u32 *val);
+
+/* Used to get the internal state of a write only gpio */
+u32 snd_pmac_gpio_internal_state(snd_pmac_gpio_t *gp);
+
+/* Register an irq for a previously allocated gpio. This is automaticlly
+ * freed in snd_pmac_free_cpio. */
+int snd_pmac_request_irq(snd_pmac_gpio_t *gp, void (*handler)(void *),
+			 void *data);
+
+static inline int snd_pmac_gpio_valid(snd_pmac_gpio_t *gp)
+{
+	return (gp->pfunc || gp->addr) ? 1 : 0;
+}
+#endif /* SND_PMAC_GPIO_H */


diff -urN linux-2.6/sound/ppc/toonie.c linux-source-2.6.15-2.6.15/sound/ppc/toonie.c
--- linux-2.6/sound/ppc/toonie.c	2006-01-17 20:19:28.000000000 -0500
+++ linux-source-2.6.15-2.6.15/sound/ppc/toonie.c	2006-01-18 19:18:33.000000000 -0500
@@ -31,7 +31,9 @@
 #include <asm/irq.h>
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
+
 #include "pmac.h"
+#include "snd-pmac-gpio.h"
 
 #undef DEBUG
 
@@ -41,61 +43,34 @@
 #define DBG(fmt...)
 #endif
 
-struct pmac_gpio {
-	unsigned int addr;
-	u8 active_val;
-	u8 inactive_val;
-	u8 active_state;
-};
-
 struct pmac_toonie
 {
-	struct pmac_gpio	hp_detect_gpio;
-	struct pmac_gpio	hp_mute_gpio;
-	struct pmac_gpio	amp_mute_gpio;
-	int			hp_detect_irq;
+	snd_pmac_gpio_t		hp_detect_gpio;
+	snd_pmac_gpio_t		hp_mute_gpio;
+	snd_pmac_gpio_t		amp_mute_gpio;
+
 	int			auto_mute_notify;
 	struct work_struct	detect_work;
 };
 
 
-/*
- * gpio access
- */
-#define do_gpio_write(gp, val) \
-	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, (gp)->addr, val)
-#define do_gpio_read(gp) \
-	pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, (gp)->addr, 0)
-#define tumbler_gpio_free(gp) /* NOP */
-
-static void write_audio_gpio(struct pmac_gpio *gp, int active)
-{
-	if (! gp->addr)
-		return;
-	active = active ? gp->active_val : gp->inactive_val;
-	do_gpio_write(gp, active);
-	DBG("(I) gpio %x write %d\n", gp->addr, active);
-}
-
-static int check_audio_gpio(struct pmac_gpio *gp)
+static void toonie_reset_audio(pmac_t *chip)
 {
-	int ret;
+	snd_pmac_gpio_t gpio;
 
-	if (! gp->addr)
-		return 0;
+	if (snd_pmac_get_gpio("audio-hw-reset", "hw-reset", &gpio))
+		return;
 
-	ret = do_gpio_read(gp);
+	DBG("(I) codec normal reset !\n");
 
-	return (ret & 0xd) == (gp->active_val & 0xd);
-}
+	snd_pmac_write_gpio(&gpio, 0);
+	msleep(200);
+	snd_pmac_write_gpio(&gpio, 1);
+	msleep(100);
+	snd_pmac_write_gpio(&gpio, 0);
+	msleep(100);
 
-static int read_audio_gpio(struct pmac_gpio *gp)
-{
-	int ret;
-	if (! gp->addr)
-		return 0;
-	ret = ((do_gpio_read(gp) & 0x02) !=0);
-	return ret == gp->active_state;
+	snd_pmac_free_gpio(&gpio);
 }
 
 
@@ -106,10 +81,11 @@
 {
 	pmac_t *chip = snd_kcontrol_chip(kcontrol);
 	struct pmac_toonie *mix = chip->mixer_data;
-	struct pmac_gpio *gp;
+	snd_pmac_gpio_t *gp;
 
 	if (mix == NULL)
 		return -ENODEV;
+
 	switch(kcontrol->private_value) {
 	case TOONIE_MUTE_HP:
 		gp = &mix->hp_mute_gpio;
@@ -120,7 +96,7 @@
 	default:
 		return -EINVAL;;
 	}
-	ucontrol->value.integer.value[0] = !check_audio_gpio(gp);
+	ucontrol->value.integer.value[0] = !snd_pmac_gpio_internal_state(gp);
 	return 0;
 }
 
@@ -129,8 +105,7 @@
 {
 	pmac_t *chip = snd_kcontrol_chip(kcontrol);
 	struct pmac_toonie *mix = chip->mixer_data;
-	struct pmac_gpio *gp;
-	int val;
+	snd_pmac_gpio_t *gp;
 
 	if (chip->update_automute && chip->auto_mute)
 		return 0; /* don't touch in the auto-mute mode */
@@ -148,9 +123,8 @@
 	default:
 		return -EINVAL;;
 	}
-	val = ! check_audio_gpio(gp);
-	if (val != ucontrol->value.integer.value[0]) {
-		write_audio_gpio(gp, ! ucontrol->value.integer.value[0]);
+	if (!snd_pmac_gpio_internal_state(gp) != ucontrol->value.integer.value[0]) {
+		snd_pmac_write_gpio(gp, ! ucontrol->value.integer.value[0]);
 		return 1;
 	}
 	return 0;
@@ -181,20 +155,21 @@
 	struct pmac_toonie *mix = chip->mixer_data;
 	int detect = 0;
 
-	if (mix->hp_detect_gpio.addr)
-		detect |= read_audio_gpio(&mix->hp_detect_gpio);
+	snd_pmac_read_gpio(&mix->hp_detect_gpio, &detect);
+
 	return detect;
 }
 
-static void toonie_check_mute(pmac_t *chip, struct pmac_gpio *gp, int val,
-			      int do_notify, snd_kcontrol_t *sw)
+static int toonie_do_mute(pmac_t *chip, snd_pmac_gpio_t *gp, int val,
+			   int do_notify, snd_kcontrol_t *sw)
 {
-	if (check_audio_gpio(gp) != val) {
-		write_audio_gpio(gp, val);
-		if (do_notify)
-			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
-				       &sw->id);
-	}
+	snd_pmac_write_gpio(gp, val);
+
+	if (do_notify)
+		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+			       &sw->id);
+
+	return val;
 }
 
 static void toonie_detect_handler(void *self)
@@ -211,20 +186,20 @@
 
 	headphone = toonie_detect_headphone(chip);
 
-	DBG("headphone: %d, lineout: %d\n", headphone, lineout);
+	DBG("headphone: %d\n", headphone);
 
 	if (headphone) {
 		/* unmute headphone/lineout & mute speaker */
-		toonie_check_mute(chip, &mix->hp_mute_gpio, 0,
-				  mix->auto_mute_notify, chip->master_sw_ctl);
-		toonie_check_mute(chip, &mix->amp_mute_gpio, 1,
-				  mix->auto_mute_notify, chip->speaker_sw_ctl);
+		toonie_do_mute(chip, &mix->hp_mute_gpio, 0,
+			       mix->auto_mute_notify, chip->master_sw_ctl);
+		toonie_do_mute(chip, &mix->amp_mute_gpio, 1,
+			       mix->auto_mute_notify, chip->speaker_sw_ctl);
 	} else {
 		/* unmute speaker, mute others */
-		toonie_check_mute(chip, &mix->amp_mute_gpio, 0,
-				  mix->auto_mute_notify, chip->speaker_sw_ctl);
-		toonie_check_mute(chip, &mix->hp_mute_gpio, 1,
-				  mix->auto_mute_notify, chip->master_sw_ctl);
+		toonie_do_mute(chip, &mix->amp_mute_gpio, 0,
+			       mix->auto_mute_notify, chip->speaker_sw_ctl);
+		toonie_do_mute(chip, &mix->hp_mute_gpio, 1,
+			       mix->auto_mute_notify, chip->master_sw_ctl);
 	}
 	if (mix->auto_mute_notify) {
 		snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
@@ -244,85 +219,12 @@
 }
 
 /* interrupt - headphone plug changed */
-static irqreturn_t toonie_hp_intr(int irq, void *devid, struct pt_regs *regs)
+static void toonie_hp_intr(void *devid)
 {
 	pmac_t *chip = devid;
 
-	if (chip->update_automute && chip->initialized) {
+	if (chip->update_automute && chip->initialized)
 		chip->update_automute(chip, 1);
-		return IRQ_HANDLED;
-	}
-	return IRQ_NONE;
-}
-
-/* look for audio gpio device */
-static int find_audio_gpio(const char *name, const char *platform,
-			   struct pmac_gpio *gp)
-{
-	struct device_node *np;
-  	u32 *base, addr;
-
-	if (! (np = find_devices("gpio")))
-		return -ENODEV;
-
-	for (np = np->child; np; np = np->sibling) {
-		char *property = get_property(np, "audio-gpio", NULL);
-		if (property && strcmp(property, name) == 0)
-			break;
-		if (device_is_compatible(np, name))
-			break;
-	}
-	if (np == NULL)
-		return -ENODEV;
-
-	base = (u32 *)get_property(np, "AAPL,address", NULL);
-	if (! base) {
-		base = (u32 *)get_property(np, "reg", NULL);
-		if (!base) {
-			DBG("(E) cannot find address for device %s !\n", name);
-			return -ENODEV;
-		}
-		addr = *base;
-		if (addr < 0x50)
-			addr += 0x50;
-	} else
-		addr = *base;
-
-	gp->addr = addr & 0x0000ffff;
-
-	/* Try to find the active state, default to 0 ! */
-	base = (u32 *)get_property(np, "audio-gpio-active-state", NULL);
-	if (base) {
-		gp->active_state = *base;
-		gp->active_val = (*base) ? 0x5 : 0x4;
-		gp->inactive_val = (*base) ? 0x4 : 0x5;
-	} else {
-		u32 *prop = NULL;
-		gp->active_state = 0;
-		gp->active_val = 0x4;
-		gp->inactive_val = 0x5;
-		/* Here are some crude hacks to extract the GPIO polarity and
-		 * open collector informations out of the do-platform script
-		 * as we don't yet have an interpreter for these things
-		 */
-		if (platform)
-			prop = (u32 *)get_property(np, platform, NULL);
-		if (prop) {
-			if (prop[3] == 0x9 && prop[4] == 0x9) {
-				gp->active_val = 0xd;
-				gp->inactive_val = 0xc;
-			}
-			if (prop[3] == 0x1 && prop[4] == 0x1) {
-				gp->active_val = 0x5;
-				gp->inactive_val = 0x4;
-			}
-		}
-	}
-
-	DBG("(I) GPIO device %s found, offset: %x, active state: %d !\n",
-	    name, gp->addr, gp->active_state);
-
-	return (np->n_intrs > 0) ? np->intrs[0].line : 0;
 }
 
 static void toonie_cleanup(pmac_t *chip)
@@ -330,8 +232,11 @@
 	struct pmac_toonie *mix = chip->mixer_data;
 	if (! mix)
 		return;
-	if (mix->hp_detect_irq >= 0)
-		free_irq(mix->hp_detect_irq, chip);
+
+	snd_pmac_free_gpio(&mix->hp_mute_gpio);
+	snd_pmac_free_gpio(&mix->amp_mute_gpio);
+	snd_pmac_free_gpio(&mix->hp_detect_gpio);
+
 	kfree(mix);
 	chip->mixer_data = NULL;
 }
@@ -340,17 +245,20 @@
 {
 	struct pmac_toonie *mix;
 
-	mix = kmalloc(sizeof(*mix), GFP_KERNEL);
+	mix = kzalloc(sizeof(*mix), GFP_KERNEL);
 	if (! mix)
 		return -ENOMEM;
 
 	chip->mixer_data = mix;
 	chip->mixer_free = toonie_cleanup;
 
-	find_audio_gpio("headphone-mute", NULL, &mix->hp_mute_gpio);
-	find_audio_gpio("amp-mute", NULL, &mix->amp_mute_gpio);
-	mix->hp_detect_irq = find_audio_gpio("headphone-detect",
-					     NULL, &mix->hp_detect_gpio);
+	/* Atleast have to have these two */
+	if (snd_pmac_get_gpio("headphone-mute", "lineout-mute",
+			      &mix->hp_mute_gpio) ||
+	    snd_pmac_get_gpio("amp-mute", NULL,
+			      &mix->amp_mute_gpio)) {
+		return -ENODEV;
+	}
 
 	strcpy(chip->card->mixername, "PowerMac Toonie");
 
@@ -362,18 +270,18 @@
 
 	INIT_WORK(&mix->detect_work, toonie_detect_handler, (void *)chip);
 
-	if (mix->hp_detect_irq >= 0) {
+	if (!snd_pmac_get_gpio("headphone-detect", "lineout-detect",
+			       &mix->hp_detect_gpio)) {
 		snd_pmac_add_automute(chip);
 
 		chip->detect_headphone = toonie_detect_headphone;
 		chip->update_automute = toonie_update_automute;
 		toonie_update_automute(chip, 0);
 
-		if (request_irq(mix->hp_detect_irq, toonie_hp_intr, 0,
-				"Sound Headphone Detection", chip) < 0)
-			mix->hp_detect_irq = -1;
+		snd_pmac_request_irq(&mix->hp_detect_gpio, toonie_hp_intr, chip);
 	}
 
+	toonie_reset_audio(chip);
+
 	return 0;
 }
-


diff -urN linux-2.6/sound/ppc/tumbler.c linux-source-2.6.15-2.6.15/sound/ppc/tumbler.c
--- linux-2.6/sound/ppc/tumbler.c	2006-01-17 20:19:28.000000000 -0500
+++ linux-source-2.6.15-2.6.15/sound/ppc/tumbler.c	2006-01-18 19:19:00.000000000 -0500
@@ -37,7 +37,9 @@
 #include <asm/irq.h>
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
+
 #include "pmac.h"
+#include "snd-pmac-gpio.h"
 #include "tumbler_volume.h"
 
 #undef DEBUG
@@ -82,23 +84,15 @@
 	VOL_IDX_LAST_MIX
 };
 
-typedef struct pmac_gpio {
-	unsigned int addr;
-	u8 active_val;
-	u8 inactive_val;
-	u8 active_state;
-} pmac_gpio_t;
-
 typedef struct pmac_tumbler_t {
 	pmac_keywest_t i2c;
-	pmac_gpio_t audio_reset;
-	pmac_gpio_t amp_mute;
-	pmac_gpio_t line_mute;
-	pmac_gpio_t line_detect;
-	pmac_gpio_t hp_mute;
-	pmac_gpio_t hp_detect;
-	int headphone_irq;
-	int lineout_irq;
+	snd_pmac_gpio_t audio_reset;
+	snd_pmac_gpio_t amp_mute;
+	snd_pmac_gpio_t line_mute;
+	snd_pmac_gpio_t line_detect;
+	snd_pmac_gpio_t hp_mute;
+	snd_pmac_gpio_t hp_detect;
+
 	unsigned int save_master_vol[2];
 	unsigned int master_vol[2];
 	unsigned int save_master_switch[2];
@@ -163,45 +157,6 @@
 	DBG("(I) snapper init client\n");
 	return send_init_client(i2c, regs);
 }
-	
-/*
- * gpio access
- */
-#define do_gpio_write(gp, val) \
-	pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, (gp)->addr, val)
-#define do_gpio_read(gp) \
-	pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, (gp)->addr, 0)
-#define tumbler_gpio_free(gp) /* NOP */
-
-static void write_audio_gpio(pmac_gpio_t *gp, int active)
-{
-	if (! gp->addr)
-		return;
-	active = active ? gp->active_val : gp->inactive_val;
-	do_gpio_write(gp, active);
-	DBG("(I) gpio %x write %d\n", gp->addr, active);
-}
-
-static int check_audio_gpio(pmac_gpio_t *gp)
-{
-	int ret;
-
-	if (! gp->addr)
-		return 0;
-
-	ret = do_gpio_read(gp);
-
-	return (ret & 0xd) == (gp->active_val & 0xd);
-}
-
-static int read_audio_gpio(pmac_gpio_t *gp)
-{
-	int ret;
-	if (! gp->addr)
-		return 0;
-	ret = ((do_gpio_read(gp) & 0x02) !=0);
-	return ret == gp->active_state;
-}
 
 /*
  * update master volume
@@ -680,7 +635,8 @@
 {
 	pmac_t *chip = snd_kcontrol_chip(kcontrol);
 	pmac_tumbler_t *mix;
-	pmac_gpio_t *gp;
+	snd_pmac_gpio_t *gp;
+
 	if (! (mix = chip->mixer_data))
 		return -ENODEV;
 	switch(kcontrol->private_value) {
@@ -695,7 +651,8 @@
 	}
 	if (gp == NULL)
 		return -EINVAL;
-	ucontrol->value.integer.value[0] = !check_audio_gpio(gp);
+
+	ucontrol->value.integer.value[0] = !snd_pmac_gpio_internal_state(gp);
 	return 0;
 }
 
@@ -703,8 +660,7 @@
 {
 	pmac_t *chip = snd_kcontrol_chip(kcontrol);
 	pmac_tumbler_t *mix;
-	pmac_gpio_t *gp;
-	int val;
+	snd_pmac_gpio_t *gp;
 #ifdef PMAC_SUPPORT_AUTOMUTE
 	if (chip->update_automute && chip->auto_mute)
 		return 0; /* don't touch in the auto-mute mode */
@@ -723,9 +679,9 @@
 	}
 	if (gp == NULL)
 		return -EINVAL;
-	val = ! check_audio_gpio(gp);
-	if (val != ucontrol->value.integer.value[0]) {
-		write_audio_gpio(gp, ! ucontrol->value.integer.value[0]);
+
+	if (!snd_pmac_gpio_internal_state(gp) != ucontrol->value.integer.value[0]) {
+		snd_pmac_write_gpio(gp, ! ucontrol->value.integer.value[0]);
 		return 1;
 	}
 	return 0;
@@ -893,7 +849,7 @@
 	int detect = 0;
 
 	if (mix->hp_detect.addr)
-		detect |= read_audio_gpio(&mix->hp_detect);
+		snd_pmac_read_gpio(&mix->hp_detect, &detect);
 	return detect;
 }
 
@@ -903,14 +859,14 @@
 	int detect = 0;
 
 	if (mix->line_detect.addr)
-		detect |= read_audio_gpio(&mix->line_detect);
+		snd_pmac_read_gpio(&mix->line_detect, &detect);
 	return detect;
 }
 
-static void check_mute(pmac_t *chip, pmac_gpio_t *gp, int val, int do_notify, snd_kcontrol_t *sw)
+static void check_mute(pmac_t *chip, snd_pmac_gpio_t *gp, int val, int do_notify, snd_kcontrol_t *sw)
 {
-	if (check_audio_gpio(gp) != val) {
-		write_audio_gpio(gp, val);
+	if (snd_pmac_gpio_internal_state(gp) != val) {
+		snd_pmac_write_gpio(gp, val);
 		if (do_notify)
 			snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
 				       &sw->id);
@@ -941,7 +897,7 @@
 		if (headphone)
 			check_mute(chip, &mix->hp_mute, 0, mix->auto_mute_notify,
 				   chip->master_sw_ctl);
-		if (lineout && mix->line_mute.addr != 0)
+		if (lineout && snd_pmac_gpio_valid(&mix->line_mute))
 			check_mute(chip, &mix->line_mute, 0, mix->auto_mute_notify,
 				   chip->lineout_sw_ctl);
 		if (mix->anded_reset)
@@ -956,7 +912,7 @@
 			msleep(10);
 		check_mute(chip, &mix->hp_mute, 1, mix->auto_mute_notify,
 			   chip->master_sw_ctl);
-		if (mix->line_mute.addr != 0)
+		if (snd_pmac_gpio_valid(&mix->line_mute))
 			check_mute(chip, &mix->line_mute, 1, mix->auto_mute_notify,
 				   chip->lineout_sw_ctl);
 	}
@@ -993,111 +949,11 @@
 
 
 /* interrupt - headphone plug changed */
-static irqreturn_t headphone_intr(int irq, void *devid, struct pt_regs *regs)
+static void headphone_intr(void *devid)
 {
 	pmac_t *chip = devid;
-	if (chip->update_automute && chip->initialized) {
+	if (chip->update_automute && chip->initialized)
 		chip->update_automute(chip, 1);
-		return IRQ_HANDLED;
-	}
-	return IRQ_NONE;
-}
-
-/* look for audio-gpio device */
-static struct device_node *find_audio_device(const char *name)
-{
-	struct device_node *np;
-  
-	if (! (np = find_devices("gpio")))
-		return NULL;
-  
-	for (np = np->child; np; np = np->sibling) {
-		char *property = get_property(np, "audio-gpio", NULL);
-		if (property && strcmp(property, name) == 0)
-			return np;
-	}  
-	return NULL;
-}
-
-/* look for audio-gpio device */
-static struct device_node *find_compatible_audio_device(const char *name)
-{
-	struct device_node *np;
-  
-	if (! (np = find_devices("gpio")))
-		return NULL;
-  
-	for (np = np->child; np; np = np->sibling) {
-		if (device_is_compatible(np, name))
-			return np;
-	}  
-	return NULL;
-}
-
-/* find an audio device and get its address */
-static long tumbler_find_device(const char *device, const char *platform, pmac_gpio_t *gp, int is_compatible)
-{
-	struct device_node *node;
-	u32 *base, addr;
-
-	if (is_compatible)
-		node = find_compatible_audio_device(device);
-	else
-		node = find_audio_device(device);
-	if (! node) {
-		DBG("(W) cannot find audio device %s !\n", device);
-		snd_printdd("cannot find device %s\n", device);
-		return -ENODEV;
-	}
-
-	base = (u32 *)get_property(node, "AAPL,address", NULL);
-	if (! base) {
-		base = (u32 *)get_property(node, "reg", NULL);
-		if (!base) {
-			DBG("(E) cannot find address for device %s !\n", device);
-			snd_printd("cannot find address for device %s\n", device);
-			return -ENODEV;
-		}
-		addr = *base;
-		if (addr < 0x50)
-			addr += 0x50;
-	} else
-		addr = *base;
-
-	gp->addr = addr & 0x0000ffff;
-	/* Try to find the active state, default to 0 ! */
-	base = (u32 *)get_property(node, "audio-gpio-active-state", NULL);
-	if (base) {
-		gp->active_state = *base;
-		gp->active_val = (*base) ? 0x5 : 0x4;
-		gp->inactive_val = (*base) ? 0x4 : 0x5;
-	} else {
-		u32 *prop = NULL;
-		gp->active_state = 0;
-		gp->active_val = 0x4;
-		gp->inactive_val = 0x5;
-		/* Here are some crude hacks to extract the GPIO polarity and
-		 * open collector informations out of the do-platform script
-		 * as we don't yet have an interpreter for these things
-		 */
-		if (platform)
-			prop = (u32 *)get_property(node, platform, NULL);
-		if (prop) {
-			if (prop[3] == 0x9 && prop[4] == 0x9) {
-				gp->active_val = 0xd;
-				gp->inactive_val = 0xc;
-			}
-			if (prop[3] == 0x1 && prop[4] == 0x1) {
-				gp->active_val = 0x5;
-				gp->inactive_val = 0x4;
-			}
-		}
-	}
-
-	DBG("(I) GPIO device %s found, offset: %x, active state: %d !\n",
-	    device, gp->addr, gp->active_state);
-
-	return (node->n_intrs > 0) ? node->intrs[0].line : 0;
 }
 
 /* reset audio */
@@ -1107,23 +963,23 @@
 
 	if (mix->anded_reset) {
 		DBG("(I) codec anded reset !\n");
-		write_audio_gpio(&mix->hp_mute, 0);
-		write_audio_gpio(&mix->amp_mute, 0);
+		snd_pmac_write_gpio(&mix->hp_mute, 0);
+		snd_pmac_write_gpio(&mix->amp_mute, 0);
 		msleep(200);
-		write_audio_gpio(&mix->hp_mute, 1);
-		write_audio_gpio(&mix->amp_mute, 1);
+		snd_pmac_write_gpio(&mix->hp_mute, 1);
+		snd_pmac_write_gpio(&mix->amp_mute, 1);
 		msleep(100);
-		write_audio_gpio(&mix->hp_mute, 0);
-		write_audio_gpio(&mix->amp_mute, 0);
+		snd_pmac_write_gpio(&mix->hp_mute, 0);
+		snd_pmac_write_gpio(&mix->amp_mute, 0);
 		msleep(100);
 	} else {
 		DBG("(I) codec normal reset !\n");
 
-		write_audio_gpio(&mix->audio_reset, 0);
+		snd_pmac_write_gpio(&mix->audio_reset, 0);
 		msleep(200);
-		write_audio_gpio(&mix->audio_reset, 1);
+		snd_pmac_write_gpio(&mix->audio_reset, 1);
 		msleep(100);
-		write_audio_gpio(&mix->audio_reset, 0);
+		snd_pmac_write_gpio(&mix->audio_reset, 0);
 		msleep(100);
 	}
 }
@@ -1134,10 +990,6 @@
 {
 	pmac_tumbler_t *mix = chip->mixer_data;
 
-	if (mix->headphone_irq >= 0)
-		disable_irq(mix->headphone_irq);
-	if (mix->lineout_irq >= 0)
-		disable_irq(mix->lineout_irq);
 	mix->save_master_switch[0] = mix->master_switch[0];
 	mix->save_master_switch[1] = mix->master_switch[1];
 	mix->save_master_vol[0] = mix->master_vol[0];
@@ -1145,18 +997,32 @@
 	mix->master_switch[0] = mix->master_switch[1] = 0;
 	tumbler_set_master_volume(mix);
 	if (!mix->anded_reset) {
-		write_audio_gpio(&mix->amp_mute, 1);
-		write_audio_gpio(&mix->hp_mute, 1);
+		snd_pmac_write_gpio(&mix->amp_mute, 1);
+		snd_pmac_write_gpio(&mix->hp_mute, 1);
 	}
 	if (chip->model == PMAC_SNAPPER) {
 		mix->acs |= 1;
 		i2c_smbus_write_byte_data(mix->i2c.client, TAS_REG_ACS, mix->acs);
 	}
 	if (mix->anded_reset) {
-		write_audio_gpio(&mix->amp_mute, 1);
-		write_audio_gpio(&mix->hp_mute, 1);
+		snd_pmac_write_gpio(&mix->amp_mute, 1);
+		snd_pmac_write_gpio(&mix->hp_mute, 1);
 	} else
-		write_audio_gpio(&mix->audio_reset, 1);
+		snd_pmac_write_gpio(&mix->audio_reset, 1);
+}
+
+static void activate_status_interrupts(snd_pmac_gpio_t *gp)
+{
+	int val;
+
+	/* XXX: This is broken with platform functions. We can't write a a
+	 * read function, and this will actuall fail (oops). */
+	return;
+
+	if (snd_pmac_gpio_valid(gp)) {
+		snd_pmac_read_gpio(gp, &val);
+		snd_pmac_write_gpio(gp, val | 0x80);
+	}
 }
 
 /* resume mixer */
@@ -1194,69 +1060,34 @@
 	tumbler_set_master_volume(mix);
 	if (chip->update_automute)
 		chip->update_automute(chip, 0);
-	if (mix->headphone_irq >= 0) {
-		unsigned char val;
 
-		enable_irq(mix->headphone_irq);
-		/* activate headphone status interrupts */
-		val = do_gpio_read(&mix->hp_detect);
-		do_gpio_write(&mix->hp_detect, val | 0x80);
-	}
-	if (mix->lineout_irq >= 0)
-		enable_irq(mix->lineout_irq);
+	activate_status_interrupts(&mix->hp_detect);
 }
 #endif
 
 /* initialize tumbler */
 static int __init tumbler_init(pmac_t *chip)
 {
-	int irq;
+	int ret = 0;
+
 	pmac_tumbler_t *mix = chip->mixer_data;
 	snd_assert(mix, return -EINVAL);
 
-	if (tumbler_find_device("audio-hw-reset",
-				"platform-do-hw-reset",
-				&mix->audio_reset, 0) < 0)
-		tumbler_find_device("hw-reset",
-				    "platform-do-hw-reset",
-				    &mix->audio_reset, 1);
-	if (tumbler_find_device("amp-mute",
-				"platform-do-amp-mute",
-				&mix->amp_mute, 0) < 0)
-		tumbler_find_device("amp-mute",
-				    "platform-do-amp-mute",
-				    &mix->amp_mute, 1);
-	if (tumbler_find_device("headphone-mute",
-				"platform-do-headphone-mute",
-				&mix->hp_mute, 0) < 0)
-		tumbler_find_device("headphone-mute",
-				    "platform-do-headphone-mute",
-				    &mix->hp_mute, 1);
-	if (tumbler_find_device("line-output-mute",
-				"platform-do-lineout-mute",
-				&mix->line_mute, 0) < 0)
-		tumbler_find_device("line-output-mute",
-				   "platform-do-lineout-mute",
-				    &mix->line_mute, 1);
-	irq = tumbler_find_device("headphone-detect",
-				  NULL, &mix->hp_detect, 0);
-	if (irq < 0)
-		irq = tumbler_find_device("headphone-detect",
-					  NULL, &mix->hp_detect, 1);
-	if (irq < 0)
-		irq = tumbler_find_device("keywest-gpio15",
-					  NULL, &mix->hp_detect, 1);
-	mix->headphone_irq = irq;
- 	irq = tumbler_find_device("line-output-detect",
-				  NULL, &mix->line_detect, 0);
- 	if (irq < 0)
-		irq = tumbler_find_device("line-output-detect",
-					  NULL, &mix->line_detect, 1);
-	mix->lineout_irq = irq;
+	ret |= snd_pmac_get_gpio("audio-hw-reset", "hw-reset",
+				 &mix->audio_reset);
+	ret |= snd_pmac_get_gpio("amp-mute", NULL, &mix->amp_mute);
+	ret |= snd_pmac_get_gpio("headphone-mute", NULL, &mix->hp_mute);
+	ret |= snd_pmac_get_gpio("line-output-mute", "lineout-mute",
+				 &mix->line_mute);
+
+	snd_pmac_get_gpio("headphone-detect", "keywest-gpio15",
+			  &mix->hp_detect);
+	snd_pmac_get_gpio("line-output-detect", "lineout-detect",
+			  &mix->line_detect);
 
 	tumbler_reset_audio(chip);
   
-	return 0;
+	return ret;
 }
 
 static void tumbler_cleanup(pmac_t *chip)
@@ -1265,15 +1096,14 @@
 	if (! mix)
 		return;
 
-	if (mix->headphone_irq >= 0)
-		free_irq(mix->headphone_irq, chip);
-	if (mix->lineout_irq >= 0)
-		free_irq(mix->lineout_irq, chip);
-	tumbler_gpio_free(&mix->audio_reset);
-	tumbler_gpio_free(&mix->amp_mute);
-	tumbler_gpio_free(&mix->hp_mute);
-	tumbler_gpio_free(&mix->hp_detect);
+	snd_pmac_free_gpio(&mix->audio_reset);
+	snd_pmac_free_gpio(&mix->amp_mute);
+	snd_pmac_free_gpio(&mix->hp_mute);
+	snd_pmac_free_gpio(&mix->hp_detect);
+	snd_pmac_free_gpio(&mix->line_detect);
+
 	snd_pmac_keywest_cleanup(&mix->i2c);
+
 	kfree(mix);
 	chip->mixer_data = NULL;
 }
@@ -1296,7 +1126,6 @@
 	if (! mix)
 		return -ENOMEM;
 	memset(mix, 0, sizeof(*mix));
-	mix->headphone_irq = -1;
 
 	chip->mixer_data = mix;
 	chip->mixer_free = tumbler_cleanup;
@@ -1367,7 +1196,7 @@
 	chip->speaker_sw_ctl = snd_ctl_new1(&tumbler_speaker_sw, chip);
 	if ((err = snd_ctl_add(chip->card, chip->speaker_sw_ctl)) < 0)
 		return err;
-	if (mix->line_mute.addr != 0) {
+	if (snd_pmac_gpio_valid(&mix->line_mute)) {
 		chip->lineout_sw_ctl = snd_ctl_new1(&tumbler_lineout_sw, chip);
 		if ((err = snd_ctl_add(chip->card, chip->lineout_sw_ctl)) < 0)
 			return err;
@@ -1395,7 +1224,7 @@
 	INIT_WORK(&device_change, device_change_handler, (void *)chip);
 
 #ifdef PMAC_SUPPORT_AUTOMUTE
-	if ((mix->headphone_irq >=0 || mix->lineout_irq >= 0)
+	if ((snd_pmac_gpio_valid(&mix->hp_detect) || snd_pmac_gpio_valid(&mix->line_detect))
 	    && (err = snd_pmac_add_automute(chip)) < 0)
 		return err;
 	chip->detect_headphone = tumbler_detect_headphone;
@@ -1403,23 +1232,15 @@
 	tumbler_update_automute(chip, 0); /* update the status only */
 
 	/* activate headphone status interrupts */
-  	if (mix->headphone_irq >= 0) {
-		unsigned char val;
-		if ((err = request_irq(mix->headphone_irq, headphone_intr, 0,
-				       "Sound Headphone Detection", chip)) < 0)
+  	if (snd_pmac_gpio_valid(&mix->hp_detect)) {
+		if (snd_pmac_request_irq(&mix->hp_detect, headphone_intr, chip) < 0)
 			return 0;
-		/* activate headphone status interrupts */
-		val = do_gpio_read(&mix->hp_detect);
-		do_gpio_write(&mix->hp_detect, val | 0x80);
-	}
-  	if (mix->lineout_irq >= 0) {
-		unsigned char val;
-		if ((err = request_irq(mix->lineout_irq, headphone_intr, 0,
-				       "Sound Lineout Detection", chip)) < 0)
+		activate_status_interrupts(&mix->hp_detect);
+	}
+  	if (snd_pmac_gpio_valid(&mix->line_detect)) {
+		if (snd_pmac_request_irq(&mix->line_detect, headphone_intr, chip) < 0)
 			return 0;
-		/* activate headphone status interrupts */
-		val = do_gpio_read(&mix->line_detect);
-		do_gpio_write(&mix->line_detect, val | 0x80);
+		activate_status_interrupts(&mix->line_detect);
 	}
 #endif
 

^ permalink raw reply

* Re: [PATCH] Add support for Freescale 83xx Host Mode USB
From: Kumar Gala @ 2006-01-19  0:18 UTC (permalink / raw)
  To: Randy Vinson; +Cc: linuxppc-dev
In-Reply-To: <43CE8EEF.2050409@mvista.com>

Thanks for the patch.  I'm going to hold off on asking Paul to pull  
this into powerpc.git and will work on an arch/powerpc version of  
this.  However, its good that the patch is on the list for anyone who  
wants to use it with and older kernel.

- kumar

On Jan 18, 2006, at 12:54 PM, Randy Vinson wrote:

> Greetings,
>     I've attached a patch (based on 2.6.16-rc1) which adds Host mode
> support for the Dual-Role(DR) and Multi-Port-Host (MPH) USB  
> controllers
> found in the Freescale 8349. Note that this patch only provides the
> platform-specific code that sets up the external hardware and pin
> configuration. The actual DR and MPH controller driver is being posted
> on the linux-usb-devel mailing list.
>
>     Using a Freescale 8349CDS reference board, the DR controller was
> successfully tested using a USB 2.0 high speed FLASH drive, a USB 1.1
> full speed 4-port hub and a Siemens SpeedStream USB to Ethernet  
> adapter.
> The MPH controller has been successfully tested with a USB 2.0 high
> speed FLASH drive. Attempts to run USB 1.1 devices with the MPH
> controller have proven unsuccessful.
>
>
>           Randy Vinson
>           MontaVista Software
>
>
> Adding platform support for the 834x Host Mode USB controller.
>
> This patch provides the platform-specific hardware setup required  
> by the
> 83xx Host Mode USB controller on the Freescale 8349CDS reference  
> system.
>
> Signed-off-by: Randy Vinson <rvinson@mvista.com>
>
> ---
> commit 30b1d2d35237f0367aeceb1bc9f62c9fdc46dbff
> tree 64af0c1897f30bb1adb72ecbb6f4c4d0ef619639
> parent 2581e186c343cd26802279bd80e420307037fbc6
> author Randy Vinson <rvinson@linuxbox.(none)> Tue, 17 Jan 2006  
> 16:32:23 -0700
> committer Randy Vinson <rvinson@linuxbox.(none)> Tue, 17 Jan 2006  
> 16:32:23 -0700
>
>  arch/ppc/Kconfig                      |    2 +
>  arch/ppc/platforms/83xx/Kconfig       |   28 +++++++++
>  arch/ppc/platforms/83xx/mpc834x_sys.c |  100 ++++++++++++++++++++++ 
> +++++++++++
>  arch/ppc/platforms/83xx/mpc834x_sys.h |    3 +
>  arch/ppc/syslib/mpc83xx_devices.c     |   16 +++++
>  include/asm-ppc/mpc83xx.h             |   17 ++++++
>  6 files changed, 166 insertions(+), 0 deletions(-)
>
> diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
> index 11899f0..b33b0eb 100644
> --- a/arch/ppc/Kconfig
> +++ b/arch/ppc/Kconfig
> @@ -681,6 +681,8 @@ config EV64360
>  	  platform.
>  endchoice
>
> +source arch/ppc/platforms/83xx/Kconfig
> +
>  config PQ2ADS
>  	bool
>  	depends on ADS8272
> diff --git a/arch/ppc/platforms/83xx/Kconfig b/arch/ppc/platforms/ 
> 83xx/Kconfig
> new file mode 100644
> index 0000000..90bc67a
> --- /dev/null
> +++ b/arch/ppc/platforms/83xx/Kconfig
> @@ -0,0 +1,28 @@
> +config 834x_USB_SUPPORT
> +	bool "834x USB Support"
> +	depends on MPC834x_SYS
> +	default y
> +	---help---
> +	  Enables support for the USB controllers on the MPC834x chip.  
> The 834x
> +	  reference board is wired for only one USB port. That port may be
> +	  used by either the MPH or DR USB controller.
> +	  Requires USB Host EHCI support.
> +	  If unsure, say Y.
> +choice
> +	prompt "834x USB Controller Selection"
> +	depends on 834x_USB_SUPPORT
> +	default 834x_DR_USB_SUPPORT
> +
> +config 834x_DR_USB_SUPPORT
> +	bool "DR Controller"
> +	select USB_EHCI_ROOT_HUB_TT
> +	---help---
> +	  Select if using the Dual-Role (DR) USB controller.
> +
> +config 834x_MPH_USB_SUPPORT
> +	bool "MPH Controller"
> +	---help---
> +	  Select if using the Multi-Port-Host (MPH) USB controller.
> +
> +endchoice
> +
> diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/ 
> platforms/83xx/mpc834x_sys.c
> index 012e1e6..6f23909 100644
> --- a/arch/ppc/platforms/83xx/mpc834x_sys.c
> +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
> @@ -11,6 +11,9 @@
>   * 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.
> + *
> + * USB setup added by Randy Vinson <rvinson@mvista.com> based on  
> code from
> + * Hunter Wu.
>   */
>
>  #include <linux/config.h>
> @@ -93,6 +96,99 @@ mpc83xx_exclude_device(u_char bus, u_cha
>  }
>  #endif /* CONFIG_PCI */
>
> +/*
> + * Configure the on-chip USB controller. The MPC834xCDS only  
> supports the
> + * second USB interface (port 1). This code sets up the hardware  
> and then
> + * lets the platform driver take over device setup.
> + */
> +
> +#ifdef CONFIG_834x_USB_SUPPORT
> +void mpc834x_board_init(void)
> +{
> +	unsigned char __iomem *bcsr;
> +	volatile unsigned char *bcsr5_p;
> +
> +	/*
> +	 * if SYS board is plug into PIB board,
> +	 * force to use the PHY on SYS board
> +	 * */
> +	bcsr = ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
> +	bcsr5_p = bcsr + BCSR5_OFF;
> +	if ( (*bcsr5_p & BCSR5_INT_USB) == 0 )
> +		*bcsr5_p = (*bcsr5_p | BCSR5_INT_USB);
> +	iounmap(bcsr);
> +}
> +
> +void mpc834x_usb_clk_cfg(void)
> +{
> +	unsigned long sccr;
> +	volatile unsigned long *p;
> +
> +	p = (volatile unsigned long *)(VIRT_IMMRBAR +  
> MPC83XX_SCCR_OFFS); /* SCCR */
> +	sccr = *p;
> +
> +	sccr |= MPC83XX_SCCR_USB_MPHCM_11 | MPC83XX_SCCR_USB_DRCM_11;
> +
> +	*p = sccr;
> +}
> +
> +static void mpc834x_usb_pin_cfg(struct fsl_usb2_platform_data *pdata)
> +{
> +	unsigned long sicrl;
> +	volatile unsigned long *p;
> +
> +	p = (volatile unsigned long *)(VIRT_IMMRBAR +  
> MPC83XX_SICRL_OFFS); /* SCCR */
> +	sicrl = *p;
> +
> +	/* set both ports to MPH mode */
> +	sicrl &= ~(MPC83XX_SICRL_USB0 | MPC83XX_SICRL_USB1);
> +
> +	if (pdata->operating_mode == FSL_USB2_DR_HOST) {
> +		if (pdata->phy_mode == FSL_USB2_PHY_UTMI_WIDE) {
> +			/* UTMI WIDE combines both ports into a single 16-bit port */
> +			sicrl |= MPC83XX_SICRL_USB0 | MPC83XX_SICRL_USB1;
> +		}
> +		else {
> +			if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
> +				sicrl |= MPC83XX_SICRL_USB0;
> +		}
> +	}
> +	*p = sicrl;
> +}
> +
> +static void __init
> +mpc834x_usb_init(void)
> +{
> +	struct fsl_usb2_platform_data *pdata;
> +
> +#ifdef CONFIG_834x_DR_USB_SUPPORT
> +	ppc_sys_device_remove(MPC83xx_USB2_MPH);
> +	pdata = (struct fsl_usb2_platform_data *) ppc_sys_get_pdata 
> (MPC83xx_USB2_DR);
> +
> +	if (pdata) {
> +		pdata->phy_mode = FSL_USB2_PHY_ULPI;
> +		pdata->operating_mode = FSL_USB2_DR_HOST;
> +		pdata->port_enables = FSL_USB2_PORT0_ENABLED;
> +	}
> +
> +#elif defined(CONFIG_834x_MPH_USB_SUPPORT)
> +	ppc_sys_device_remove(MPC83xx_USB2_DR);
> +	pdata = (struct fsl_usb2_platform_data *) ppc_sys_get_pdata 
> (MPC83xx_USB2_MPH);
> +
> +	if (pdata) {
> +		pdata->phy_mode = FSL_USB2_PHY_ULPI;
> +		pdata->operating_mode = FSL_USB2_MPH_HOST;
> +		pdata->port_enables = FSL_USB2_PORT0_ENABLED;
> +	}
> +
> +#endif
> +	mpc834x_usb_pin_cfg(pdata);
> +	mpc834x_board_init();
> +	mpc834x_usb_clk_cfg();
> +	return;
> +}
> +#endif /* CONFIG_834x_USB_SUPPORT */
> +
>  /*  
> ********************************************************************** 
> **
>   *
>   * Setup the architecture
> @@ -144,6 +240,10 @@ mpc834x_sys_setup_arch(void)
>  		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
>  	}
>
> +#ifdef CONFIG_834x_USB_SUPPORT
> +	mpc834x_usb_init();
> +#endif
> +
>  #ifdef CONFIG_BLK_DEV_INITRD
>  	if (initrd_start)
>  		ROOT_DEV = Root_RAM0;
> diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/ 
> platforms/83xx/mpc834x_sys.h
> index 2e514d3..fab3762 100644
> --- a/arch/ppc/platforms/83xx/mpc834x_sys.h
> +++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
> @@ -27,6 +27,9 @@
>  #define BCSR_PHYS_ADDR		((uint)0xf8000000)
>  #define BCSR_SIZE		((uint)(128 * 1024))
>
> +#define BCSR5_OFF		0x05
> +#define BCSR5_INT_USB		0x02
> +
>  #define BCSR_MISC_REG2_OFF	0x07
>  #define BCSR_MISC_REG2_PORESET	0x01
>
> diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/ 
> mpc83xx_devices.c
> index f9b95de..916926c 100644
> --- a/arch/ppc/syslib/mpc83xx_devices.c
> +++ b/arch/ppc/syslib/mpc83xx_devices.c
> @@ -23,6 +23,8 @@
>  #include <asm/ppc_sys.h>
>  #include <asm/machdep.h>
>
> +static u64 mpc83xx_dma_mask = 0xffffffffULL;
> +
>  /* We use offsets for IORESOURCE_MEM since we do not know at  
> compile time
>   * what IMMRBAR is, will get fixed up by mach_mpc83xx_fixup
>   */
> @@ -50,6 +52,14 @@ static struct fsl_i2c_platform_data mpc8
>  	.device_flags = FSL_I2C_DEV_SEPARATE_DFSRR,
>  };
>
> +/* Placeholder to be filled in by board code */
> +static struct fsl_usb2_platform_data mpc83xx_fsl_dr_pdata = {
> +};
> +
> +/* Placeholder to be filled in by board code */
> +static struct fsl_usb2_platform_data mpc83xx_fsl_mph_pdata = {
> +};
> +
>  static struct plat_serial8250_port serial_platform_data[] = {
>  	[0] = {
>  		.mapbase	= 0x4500,
> @@ -190,7 +200,10 @@ struct platform_device ppc_sys_platform_
>  	[MPC83xx_USB2_DR] = {
>  		.name = "fsl-usb2-dr",
>  		.id	= 1,
> +		.dev.platform_data = &mpc83xx_fsl_dr_pdata,
>  		.num_resources	 = 2,
> +		.dev.dma_mask	= &mpc83xx_dma_mask,
> +		.dev.coherent_dma_mask = 0xffffffffULL,
>  		.resource = (struct resource[]) {
>  			{
>  				.start	= 0x23000,
> @@ -208,6 +221,9 @@ struct platform_device ppc_sys_platform_
>  		.name = "fsl-usb2-mph",
>  		.id	= 1,
>  		.num_resources	 = 2,
> +		.dev.platform_data = &mpc83xx_fsl_mph_pdata,
> +		.dev.dma_mask	= &mpc83xx_dma_mask,
> +		.dev.coherent_dma_mask = 0xffffffffULL,
>  		.resource = (struct resource[]) {
>  			{
>  				.start	= 0x22000,
> diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
> index 7cdf60f..cd2baf7 100644
> --- a/include/asm-ppc/mpc83xx.h
> +++ b/include/asm-ppc/mpc83xx.h
> @@ -95,6 +95,23 @@ extern unsigned char __res[];
>
>  #define MPC83xx_CCSRBAR_SIZE	(1024*1024)
>
> +#define MPC83XX_SCCR_OFFS          0xA08
> +#define MPC83XX_SCCR_USB_MPHCM_11  0x00c00000
> +#define MPC83XX_SCCR_USB_MPHCM_01  0x00400000
> +#define MPC83XX_SCCR_USB_MPHCM_10  0x00800000
> +#define MPC83XX_SCCR_USB_DRCM_11   0x00300000
> +#define MPC83XX_SCCR_USB_DRCM_01   0x00100000
> +#define MPC83XX_SCCR_USB_DRCM_10   0x00200000
> +
> +/* system i/o configuration register low */
> +#define MPC83XX_SICRL_OFFS         0x114
> +#define MPC83XX_SICRL_USB0         0x40000000
> +#define MPC83XX_SICRL_USB1         0x20000000
> +
> +/* system i/o configuration register high */
> +#define MPC83XX_SICRH_OFFS         0x118
> +#define MPC83XX_SICRH_USB_UTMI     0x00020000
> +
>  /* Let modules/drivers get at immrbar (physical) */
>  extern phys_addr_t immrbar;
>
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [PATCH 00/10] Updated ML300 & ML403 patches
From: Peter Ryser @ 2006-01-18 23:26 UTC (permalink / raw)
  To: Grant Likely
  Cc: Grant Likely, Andrei Konovalov, Rick Moleres, linuxppc-embedded
In-Reply-To: <43CD460F.8010506@secretlab.ca>


> Yeah, the head of Linus' tree is busted.  Doing a cg-seek 
> 67daf5f11f06b9b15f8320de1d237ccc2e74fe43 will work, but you first need 
> to remove the following line from arch/ppc/kernel/ppc_ksyms.c
>
> EXPORT_SYMBOL(get_wchan);
>
After applying your patches to the branch-point you mention above, 
removing that symbol, and configuring for the ML403 I can get to a boot 
prompt. Good.

Doing the same for the ML300, though, does not work, i.e. I get a single 
line saying:
"Data machine check in kernel mode."

Digging in the kernel configuration I don't seem to find a place where I 
can turn on more verbose output, i.e. a register dump at the time of the 
machine check exception. Any idea where I might find that?

- Peter

^ permalink raw reply

* Re: AGPGART driver for ArticiaS - ioremap() problem
From: Benjamin Herrenschmidt @ 2006-01-18 23:09 UTC (permalink / raw)
  To: Gerhard Pircher; +Cc: linuxppc-dev, debian-powerpc
In-Reply-To: <14295.1137613254@www12.gmx.net>

On Wed, 2006-01-18 at 20:40 +0100, Gerhard Pircher wrote:
> > > That's the problem: we don't have the datasheet for the ArticiaS. :-( 
> > > But the driver initializes correctly with the Uninorth code now and
> > > with the DRI/DRM code changed. (The code in drm_vm.c checks for Apple's
> > > PCI vendor ID. Therefore I just added a check for MAI's PCI vendor ID.)
> > > But the X server freezes after the login screen is displayed (IIRC the
> > > mouse still works, but the keyboard is dead!?).
> > 
> > That check is only necessary because Apple bridge puts the AGP aperture
> > at bus address 0. This is probably not the case for you. You may not
> > have that right. Check what you put in agp_bridge->gart_bus_addr

> Hmm, I'm not sure what value agp_bridge->gart_bus_addr should have. The BIOS
> doesn't setup it and the VIA AGPGART driver even reads it out from the
> northbridge's registers! Where does the value for agp_bridge->gart_bus_addr
> come from? For now it is set to 0x0, which would require the modification in
> drm_vm.c!?

Well... this is where you AGP aperture will be in bus space.. you'd
rather know what to do with it to do a driver...

> :) The driver seems to work better with cant_use_aperture set to 1, so I
> leave it as it is. BTW: What's the meaning of needs_scratch_page?

Well, set to 1 would mean the aperture isn't accessible on the CPU
space. It might seem to work better either because indeed that is the
case... or simply because you put it in a wrong place (ie 0 !) There
must be a chipset register somewhere that tells you where the aperture
is no ?

Ben.

^ permalink raw reply

* Re: inconsistent gdbserver behaviour on Virtex-4
From: Grant Likely @ 2006-01-18 21:08 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-embedded
In-Reply-To: <43CEA971.6050409@secretlab.ca>

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

Sorry, wrong log file; correct one now attached.

Grant Likely wrote:
> I need some help;
> 
> I'm seeing odd inconsistent behaviour when debugging userspace on a 
> Virtex-4 (don't yet know if it's a gdbserver or kernel issue).
> 
> Here's the scenario:
> 
> - tested on kernel versions: 2.6.15, 2.6.16-rc1  both w/ ml403 patches
> - tested with gdb versions 6.1, 6.3 & 6.4
> - root file system contains: busybox-1.01, glibc-2.3.5, gdbserver
> - gcc version: 3.4.4 compiled with crosstool-0.38
> - BDI *not* attached, and CONFIG_BDI_SWITCH is *not set*
> 
> simple hello.c compiled for the target.  Program loops 20 times over 
> some printf's and simple math.
> 
> On target, I start the program with:
> $ gdbserver 192.168.0.37:2345 ./hello
> Process ./hello created; pid = 268
> Listening on port 2345
> 
> On the host, I connect gdb and set a breakpoint at main(), and at two 
> places in the loop.
> 
> Whenever I continue (c), I see one of the following behaviours (randomly 
> it seems):
> 
> 1. gdb stops exactly where it started from.  ie. no code gets executed,
> 2. continue behaves properly, and execution stops at the next 
> breakpoint, or
> 3. the program runs to completion, and no other breakpoints get hit. 
> program exits normally
> 
> When I do a single instruction step (si), I see either:
> 1. the pc does not move, or
> 2. the program runs freely until the next breakpoint.
> 
> I've attached a gdb log with 'set debug remote 1' turned on.  It looks 
> to me that the kernel single step support is still busted on my board. 
> It also seems to be that gdb single steps off of the previous breakpoint 
> before reestablishing all the breakpoints and letting the process run 
> again.  Therefore, if single step is busted, then it makes sense that 
> continue is busted to.
> 
> Any help would be appreciated.
> 
> Thanks,
> g.
> 
> 

-- 
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
(403) 663-0761

[-- Attachment #2: gdb.log --]
[-- Type: text/x-log, Size: 18673 bytes --]

GNU gdb 6.4
Copyright 2005 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=powerpc-405-linux-gnu"...
(gdb) target remote 192.168.0.36\b \b7:2345
Remote debugging using 192.168.0.37:2345
0x3000fa18 in ?? ()
warning: Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
(gdb) br main
Breakpoint 1 at 0x100004c0: file hello.c, line 7.
(gdb) c
Continuing.
Error while mapping shared library sections:
/lib/ld.so.1: No such file or directory.
Error while reading shared library symbols:
/lib/ld.so.1: No such file or directory.

Breakpoint 1, main () at hello.c:7
7	    setvbuf(stdout, NULL, _IONBF, 0);
(gdb) 
Continuing.

Breakpoint 1, main () at hello.c:7
7	    setvbuf(stdout, NULL, _IONBF, 0);
(gdb) set debug remote 1
(gdb) list
2	
3	int
4	main (void)
5	{
6	    int i, j, k;
7	    setvbuf(stdout, NULL, _IONBF, 0);
8	    printf("Hello, world!\n");
9	
10	    j = 100; k=0;
11	    for (i = 0; i< 20; i++) {
(gdb) 
12	        printf("   i=%i j=%i k=%i\n", i, j, k);
13	        j += 4*i;
14	        k -= j/(i+1);
15	        printf("checkpoint\n", i, j, k);
16	    }
17	
18	    printf("done!\n", i, j);
19	
20	    return 0;
21	}
(gdb) br 13
Breakpoint 2 at 0x10000520: file hello.c, line 13.
(gdb) br 15
Breakpoint 3 at 0x10000550: file hello.c, line 15.
(gdb) x/x $pc
Sending packet: $m100004ac,4#b6...Ack
Packet received: 9421ffe0
Sending packet: $m100004b0,4#84...Ack
Packet received: 7c0802a6
Sending packet: $m100004b4,4#88...Ack
Packet received: 93e1001c
Sending packet: $m100004b8,4#8c...Ack
Packet received: 90010024
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78
Sending packet: $m7ffa3da0,4#59...Ack
Packet received: 7ffa3dc0
Sending packet: $Hg0#df...Ack
Packet received: E01
Sending packet: $p1f#07...Ack
Packet received: 
Sending packet: $g#67...Ack
Packet received: 0fec312c7ffa3da030012b00000000017ffa3e247ffa3e2c7ffa3e5c100005b0100006480ffed2747ffa3e10000000000000000110018ab8ffff0000ffff0000ffffffffffff0000ffff00007f83aa100000000010071a0c7f83aa2810071a1c00000000100004ac7ffa3e5c00000001100005b07ffa3e240ffeace47ffa3da000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100004c00002d030220002220fec312c0fec31300000000000000000
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
0x100004c0 <main+20>:	0x3d201001
(gdb) si
Sending packet: $vCont;s#b8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78
Sending packet: $m100004ac,4#b6...Ack
Packet received: 9421ffe0
Sending packet: $m100004b0,4#84...Ack
Packet received: 7c0802a6
Sending packet: $m100004b4,4#88...Ack
Packet received: 93e1001c
Sending packet: $m100004b8,4#8c...Ack
Packet received: 90010024
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78
Sending packet: $m7ffa3da0,4#59...Ack
Packet received: 7ffa3dc0
Sending packet: $g#67...Ack
Packet received: 0fec312c7ffa3da030012b00000000017ffa3e247ffa3e2c7ffa3e5c100005b0100006480ffed2747ffa3e10000000000000000110018ab8ffff0000ffff0000ffffffffffff0000ffff00007f83aa100000000010071a0c7f83aa2810071a1c00000000100004ac7ffa3e5c00000001100005b07ffa3e240ffeace47ffa3da000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100004c00002d230220002220fec312c0fec31300000000000000000
Sending packet: $m7ffa3dc4,4#5f...Ack
Packet received: 0fec312c
Sending packet: $mfec312c,4#f4...Ack
Packet received: 4801918d
Sending packet: $mfec3128,4#c9...Ack
Packet received: 4e800021
Sending packet: $mfec312c,4#f4...Ack
Packet received: 4801918d
Sending packet: $mfec3128,4#c9...Ack
Packet received: 4e800021
Sending packet: $mfec2f30,4#f6...Ack
Packet received: 93c10018
Sending packet: $mfec2f34,4#fa...Ack
Packet received: 93e1001c
Sending packet: $mfec2f38,4#fe...Ack
Packet received: 90010024
Sending packet: $mfec2f3c,4#29...Ack
Packet received: 48127da5
Sending packet: $m7ffa3dc0,4#5b...Ack
Packet received: 7ffa3df0
7	    setvbuf(stdout, NULL, _IONBF, 0);
(gdb) x/x $pc
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
0x100004c0 <main+20>:	0x3d201001
(gdb) c
Continuing.
Sending packet: $vCont;s#b8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7c290b78
Sending packet: $M10000328,4:7d821008#43...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $M100004c0,4:7d821008#6d...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 801f0008
Sending packet: $M10000520,4:7d821008#3d...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 3d201000
Sending packet: $M10000550,4:7d821008#40...Ack
Packet received: OK
Sending packet: $vCont;c#a8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7d821008
Sending packet: $M10000328,4:7c290b78#7b...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 7d821008
Sending packet: $M100004c0,4:3d201001#5a...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 7d821008
Sending packet: $M10000520,4:801f0008#36...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 7d821008
Sending packet: $M10000550,4:3d201000#2c...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78

Breakpoint 1, main () at hello.c:7
7	    setvbuf(stdout, NULL, _IONBF, 0);
(gdb) c
Continuing.
Sending packet: $vCont;s#b8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7c290b78
Sending packet: $M10000328,4:7d821008#43...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $M100004c0,4:7d821008#6d...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 801f0008
Sending packet: $M10000520,4:7d821008#3d...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 3d201000
Sending packet: $M10000550,4:7d821008#40...Ack
Packet received: OK
Sending packet: $vCont;c#a8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7d821008
Sending packet: $M10000328,4:7c290b78#7b...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 7d821008
Sending packet: $M100004c0,4:3d201001#5a...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 7d821008
Sending packet: $M10000520,4:801f0008#36...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 7d821008
Sending packet: $M10000550,4:3d201000#2c...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78

Breakpoint 1, main () at hello.c:7
7	    setvbuf(stdout, NULL, _IONBF, 0);
(gdb) c
Continuing.
Sending packet: $vCont;s#b8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7c290b78
Sending packet: $M10000328,4:7d821008#43...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $M100004c0,4:7d821008#6d...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 801f0008
Sending packet: $M10000520,4:7d821008#3d...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 3d201000
Sending packet: $M10000550,4:7d821008#40...Ack
Packet received: OK
Sending packet: $vCont;c#a8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7d821008
Sending packet: $M10000328,4:7c290b78#7b...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 7d821008
Sending packet: $M100004c0,4:3d201001#5a...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 7d821008
Sending packet: $M10000520,4:801f0008#36...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 7d821008
Sending packet: $M10000550,4:3d201000#2c...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78

Breakpoint 1, main () at hello.c:7
7	    setvbuf(stdout, NULL, _IONBF, 0);
(gdb) c
Continuing.
Sending packet: $vCont;s#b8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7c290b78
Sending packet: $M10000328,4:7d821008#43...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $M100004c0,4:7d821008#6d...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 801f0008
Sending packet: $M10000520,4:7d821008#3d...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 3d201000
Sending packet: $M10000550,4:7d821008#40...Ack
Packet received: OK
Sending packet: $vCont;c#a8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7d821008
Sending packet: $M10000328,4:7c290b78#7b...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 7d821008
Sending packet: $M100004c0,4:3d201001#5a...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 7d821008
Sending packet: $M10000520,4:801f0008#36...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 7d821008
Sending packet: $M10000550,4:3d201000#2c...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78

Breakpoint 1, main () at hello.c:7
7	    setvbuf(stdout, NULL, _IONBF, 0);
(gdb) c
Continuing.
Sending packet: $vCont;s#b8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7c290b78
Sending packet: $M10000328,4:7d821008#43...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $M100004c0,4:7d821008#6d...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 801f0008
Sending packet: $M10000520,4:7d821008#3d...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 3d201000
Sending packet: $M10000550,4:7d821008#40...Ack
Packet received: OK
Sending packet: $vCont;c#a8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7d821008
Sending packet: $M10000328,4:7c290b78#7b...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 7d821008
Sending packet: $M100004c0,4:3d201001#5a...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 7d821008
Sending packet: $M10000520,4:801f0008#36...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 7d821008
Sending packet: $M10000550,4:3d201000#2c...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78

Breakpoint 1, main () at hello.c:7
7	    setvbuf(stdout, NULL, _IONBF, 0);
(gdb) 
Continuing.
Sending packet: $vCont;s#b8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7c290b78
Sending packet: $M10000328,4:7d821008#43...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $M100004c0,4:7d821008#6d...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 801f0008
Sending packet: $M10000520,4:7d821008#3d...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 3d201000
Sending packet: $M10000550,4:7d821008#40...Ack
Packet received: OK
Sending packet: $vCont;c#a8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7d821008
Sending packet: $M10000328,4:7c290b78#7b...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 7d821008
Sending packet: $M100004c0,4:3d201001#5a...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 7d821008
Sending packet: $M10000520,4:801f0008#36...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 7d821008
Sending packet: $M10000550,4:3d201000#2c...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78

Breakpoint 1, main () at hello.c:7
7	    setvbuf(stdout, NULL, _IONBF, 0);
(gdb) 
Continuing.
Sending packet: $vCont;s#b8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7c290b78
Sending packet: $M10000328,4:7d821008#43...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $M100004c0,4:7d821008#6d...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 801f0008
Sending packet: $M10000520,4:7d821008#3d...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 3d201000
Sending packet: $M10000550,4:7d821008#40...Ack
Packet received: OK
Sending packet: $vCont;c#a8...Ack
Packet received: T0501:7ffa3da0;40:100004c0;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7d821008
Sending packet: $M10000328,4:7c290b78#7b...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 7d821008
Sending packet: $M100004c0,4:3d201001#5a...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 7d821008
Sending packet: $M10000520,4:801f0008#36...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 7d821008
Sending packet: $M10000550,4:3d201000#2c...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $m100004bc,4#b7...Ack
Packet received: 7c3f0b78

Breakpoint 1, main () at hello.c:7
7	    setvbuf(stdout, NULL, _IONBF, 0);
(gdb) 
Continuing.
Sending packet: $vCont;s#b8...Ack
Packet received: T0501:7ffa3da0;40:100004c4;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7c290b78
Sending packet: $M10000328,4:7d821008#43...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $M100004c0,4:7d821008#6d...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 801f0008
Sending packet: $M10000520,4:7d821008#3d...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 3d201000
Sending packet: $M10000550,4:7d821008#40...Ack
Packet received: OK
Sending packet: $vCont;c#a8...Ack
Packet received: T0501:7ffa3da0;40:10000520;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7d821008
Sending packet: $M10000328,4:7c290b78#7b...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 7d821008
Sending packet: $M100004c0,4:3d201001#5a...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 7d821008
Sending packet: $M10000520,4:801f0008#36...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 7d821008
Sending packet: $M10000550,4:3d201000#2c...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 801f0008
Sending packet: $m1000051c,4#87...Ack
Packet received: 480105f9
Sending packet: $m10000520,4#55...Ack
Packet received: 801f0008
Sending packet: $m1000051c,4#87...Ack
Packet received: 480105f9

Breakpoint 2, main () at hello.c:13
13	        j += 4*i;
(gdb) 
Continuing.
Sending packet: $vCont;s#b8...Ack
Packet received: T0501:7ffa3da0;40:10000524;
Sending packet: $m10000328,4#5b...Ack
Packet received: 7c290b78
Sending packet: $M10000328,4:7d821008#43...Ack
Packet received: OK
Sending packet: $m100004c0,4#85...Ack
Packet received: 3d201001
Sending packet: $M100004c0,4:7d821008#6d...Ack
Packet received: OK
Sending packet: $m10000520,4#55...Ack
Packet received: 801f0008
Sending packet: $M10000520,4:7d821008#3d...Ack
Packet received: OK
Sending packet: $m10000550,4#58...Ack
Packet received: 3d201000
Sending packet: $M10000550,4:7d821008#40...Ack
Packet received: OK
Sending packet: $vCont;c#a8...Ack
Packet received: W00

Program exited normally.
(gdb) quit

^ permalink raw reply

* inconsistent gdbserver behaviour on Virtex-4
From: Grant Likely @ 2006-01-18 20:47 UTC (permalink / raw)
  To: linuxppc-embedded

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

I need some help;

I'm seeing odd inconsistent behaviour when debugging userspace on a 
Virtex-4 (don't yet know if it's a gdbserver or kernel issue).

Here's the scenario:

- tested on kernel versions: 2.6.15, 2.6.16-rc1  both w/ ml403 patches
- tested with gdb versions 6.1, 6.3 & 6.4
- root file system contains: busybox-1.01, glibc-2.3.5, gdbserver
- gcc version: 3.4.4 compiled with crosstool-0.38
- BDI *not* attached, and CONFIG_BDI_SWITCH is *not set*

simple hello.c compiled for the target.  Program loops 20 times over 
some printf's and simple math.

On target, I start the program with:
$ gdbserver 192.168.0.37:2345 ./hello
Process ./hello created; pid = 268
Listening on port 2345

On the host, I connect gdb and set a breakpoint at main(), and at two 
places in the loop.

Whenever I continue (c), I see one of the following behaviours (randomly 
it seems):

1. gdb stops exactly where it started from.  ie. no code gets executed,
2. continue behaves properly, and execution stops at the next breakpoint, or
3. the program runs to completion, and no other breakpoints get hit. 
program exits normally

When I do a single instruction step (si), I see either:
1. the pc does not move, or
2. the program runs freely until the next breakpoint.

I've attached a gdb log with 'set debug remote 1' turned on.  It looks 
to me that the kernel single step support is still busted on my board. 
It also seems to be that gdb single steps off of the previous breakpoint 
before reestablishing all the breakpoints and letting the process run 
again.  Therefore, if single step is busted, then it makes sense that 
continue is busted to.

Any help would be appreciated.

Thanks,
g.





-- 
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
(403) 663-0761

[-- Attachment #2: gda.log --]
[-- Type: text/x-log, Size: 9506 bytes --]

U-Boot 1.1.3 (Oct 20 2005 - 16:57:02)

CPU:   8560, Version: 2.0, (0x80700020)
Core:  E500, Version: 2.0, (0x80200020)
Clock Configuration:
       CPU: 660 MHz, CCB: 264 MHz,
       DDR: 132 MHz, LBC:  33 MHz
L1:    D-cache 32 kB enabled
       I-cache 32 kB enabled
Board: GDA 04SB006
I2C:   ready
DRAM:      DDR: 256 MB
FLASH:  8 MB
L2 cache 256KB: enabled
In:    serial
Out:   serial
Err:   serial
Net:   TSEC1 ETHERNET: PHY is Marvell 88E1011S (1410c67)
FCC3 ETHERNET, TSEC1 ETHERNET
=> printenv

bootdelay=5
baudrate=38400
loads_echo=1
bootargs=root=/dev/mtdblock1 mtdparts=phys:1536K(kernel),6272K(JFFS2),128K(env),256K(u-boot)ro ip=192.168.0.26:192.168.0.101::255.255.255.0::eth0 rootfstype=jffs2
flashboot=setenv bootargs root=/dev/mtdblock1 mtdparts=phys:1536K(kernel),6272K(JFFS2),128K(env),256K(u-boot)ro ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:eth0 rootfstype=jffs2; bootm ff800000
netboot=tftp 200000 gda/uImage; setenv bootargs nfsroot=/nfsroot/gda rw ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:eth0:off  mtdparts=phys:1536K(kernel),6272K(JFFS2),128K(env),256K(u-boot)ro; bootm 200000
ethaddr=00:01:af:07:9b:8a
eth1addr=00:01:af:07:9b:8b
filesize=11139e
fileaddr=200000
gatewayip=192.168.0.1
netmask=255.255.255.0
ipaddr=192.168.0.26
serverip=192.168.0.102
stdin=serial
stdout=serial
stderr=serial
ethact=FCC3 ETHERNET

Environment size: 851/8188 bytes
=> run flashboot

## Booting image at ff800000 ...
   Image Name:   Linux-2.6.12
   Created:      2005-11-23  15:02:05 UTC
   Image Type:   PowerPC Linux Kernel Image (gzip compressed)
   Data Size:    1119070 Bytes =  1.1 MB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK
PQ3/GDA8560 board support by Arabella

Memory CAM mapping: CAM0=256Mb, CAM1=0Mb, CAM2=0Mb residual: 0Mb

Linux version 2.6.12 (root@ellas) (gcc version 3.3.2) #289 Wed Nov 23 17:02:01 IST 2005

GDA8560 setup arch

Built 1 zonelists

Kernel command line: root=/dev/mtdblock1 mtdparts=phys:1536K(kernel),6272K(JFFS2),128K(env),256K(u-boot)ro ip=192.168.0.26:192.168.0.102:192.168.0.1:255.255.255.0::eth0 rootfstype=jffs2

GDA8560 init IRQ. NR_IRQS=108

OpenPIC Version 1.2 (1 CPUs and 44 IRQ sources) at ff740000

CPM_IRQ_OFFSET = 0 NR_CPM_INTS = 64

PID hash table entries: 2048 (order: 11, 32768 bytes)

GDA8560 calibrate decrementer. FREQ=264000000, tb_ticks_per_jiffy=33000

Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)

Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)

Memory: 257152k available (1772k kernel code, 612k data, 96k init, 0k highmem)

Mount-cache hash table entries: 512

NET: Registered protocol family 16

GDA8560 init

PCI: Probing PCI hardware

JFFS2 version 2.2. (C) 2001-2003 Red Hat, Inc.

Generic RTC Driver v1.07

GPIO: Init

io scheduler noop registered

io scheduler anticipatory registered

io scheduler deadline registered

io scheduler cfq registered

RAMDISK driver initialized: 16 RAM disks of 32768K size 1024 blocksize

loop: loaded (max 8 devices)

eth0: Gianfar Ethernet Controller Version 1.1, 00:01:af:07:9b:8a 

eth0: Running with NAPI enabled

eth0: 256/256 RX/TX BD ring size

Flash physmap: 0x800000 bytes at 0xFF800000, mapped to 0xD1080000

phys: Found 1 x16 devices at 0x0 in 16-bit bank

 Intel/Sharp Extended Query Table at 0x0031

Using buffer write method

cfi_cmdset_0001: Erase suspend on write enabled

4 cmdlinepart partitions found on MTD device phys

Creating 4 MTD partitions on "phys":

0x00000000-0x00180000 : "kernel"

0x00180000-0x007a0000 : "JFFS2"

0x007a0000-0x007c0000 : "env"

0x007c0000-0x00800000 : "u-boot"

i2c /dev entries driver

I2C bus support for MPC82xx, MPC85xx by Arabella Software

SPI bus support for MPC82xx,MPC85xx by Arabella Software

MPC8xxx I2C driver by Arabella Software

MPC8xxx SPI driver by Arabella Software

Serial: pqsxc_uart driver init

MPC FCC Ethernet driver

devsoc_xcc_create c07c0000

Created eth1

NET: Registered protocol family 2

IP: routing cache hash table of 2048 buckets, 16Kbytes

TCP established hash table entries: 16384 (order: 5, 131072 bytes)

TCP bind hash table entries: 16384 (order: 4, 65536 bytes)

TCP: Hash tables configured (established 16384 bind 16384)

NET: Registered protocol family 1

NET: Registered protocol family 17

eth0: PHY is Marvell 88E1101 (1410c67)

IP-Config: Complete:

      device=eth0, addr=192.168.0.26, mask=255.255.255.0, gw=192.168.0.1,

     host=192.168.0.26, domain=, nis-domain=(none),

     bootserver=192.168.0.102, rootserver=192.168.0.102, rootpath=

VFS: Mounted root (jffs2 filesystem) readonly.

Freeing unused kernel memory: 96k init


init started:  BusyBox v1.1.0-pre1 (2005.11.21-12:45+0000) multi-call binary
Mounting a tmpfs over /dev...done.
Creating initial device nodes...done.
Mounting local filesystems...
Setting up IP spoofing protection: rp_filter.
Configuring network interfaces...done.
Starting internet superserver: inetd.
eth0: Full Duplex

eth0: Speed 100BT

eth0: Link is up


192.168.0.26 login: root
Password: 
login[311]: root login  on `tts/0'




BusyBox v1.1.0-pre1 (2005.11.21-12:45+0000) Built-in shell (ash)
Enter 'help' for a list of built-in commands.

~ # ping 192.168.0.102
PING 192.168.0.102 (192.168.0.102): 56 data bytes
64 bytes from 192.168.0.102: icmp_seq=0 ttl=64 time=3.1 ms
64 bytes from 192.168.0.102: icmp_seq=1 ttl=64 time=1.2 ms
64 bytes from 192.168.0.102: icmp_seq=2 ttl=64 time=1.1 ms
64 bytes from 192.168.0.102: icmp_seq=3 ttl=64 time=1.1 ms

--- 192.168.0.102 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 1.1/1.6/3.1 ms
~ # ifconfig eth1 192.168.1.26 up
eth1: OPEN

BD rings initialised, RBASE=7D8220, TBASE=7D8420

~ # ping 192.168.0.102
PING 192.168.0.102 (192.168.0.102): 56 data bytes
64 bytes from 192.168.0.102: icmp_seq=0 ttl=64 time=3.0 ms
64 bytes from 192.168.0.102: icmp_seq=1 ttl=64 time=1.1 ms
64 bytes from 192.168.0.102: icmp_seq=2 ttl=64 time=1.1 ms
64 bytes from 192.168.0.102: icmp_seq=3 ttl=64 time=1.1 ms
64 bytes from 192.168.0.102: icmp_seq=4 ttl=64 time=1.1 ms
64 bytes from 192.168.0.102: icmp_seq=5 ttl=64 time=1.1 ms

--- 192.168.0.102 ping statistics ---
6 packets transmitted, 6 packets received, 0% packet loss
round-trip min/avg/max = 1.1/1.4/3.0 ms
~ # /sb\b\b\b
~ # /sbin/^[[Jifco^[[10D
~ # /sbin/ifconfig ^[[J
eth0      Link encap:Ethernet  HWaddr 00:01:AF:07:9B:8A  
          inet addr:192.168.0.26  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:346 errors:0 dropped:0 overruns:0 frame:0
          TX packets:14 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:107354 (104.8 KiB)  TX bytes:1148 (1.1 KiB)
          Base address:0x4000 

eth1      Link encap:Ethernet  HWaddr 00:01:AF:07:9B:8B  
          inet addr:192.168.1.26  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

~ # eth0: Link is down


~ # ping 192.168.1.102
PING 192.168.1.102 (192.168.1.102): 56 data bytes

--- 192.168.1.102 ping statistics ---
15 packets transmitted, 0 packets received, 100% packet loss
~ # /sbin/ifconfig
eth0      Link encap:Ethernet  HWaddr 00:01:AF:07:9B:8A  
          inet addr:192.168.0.26  Bcast:192.168.0.255  Mask:255.255.255.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:347 errors:0 dropped:0 overruns:0 frame:0
          TX packets:14 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:107520 (105.0 KiB)  TX bytes:1148 (1.1 KiB)
          Base address:0x4000 

eth1      Link encap:Ethernet  HWaddr 00:01:AF:07:9B:8B  
          inet addr:192.168.1.26  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:14 errors:0 dropped:0 overruns:0 frame:0
          TX packets:15 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:4528 (4.4 KiB)  TX bytes:630 (630.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:15 errors:0 dropped:0 overruns:0 frame:0
          TX packets:15 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1680 (1.6 KiB)  TX bytes:1680 (1.6 KiB)

~ # ifconfig eth0 192.168.2.26
~ # eth0: Full Duplex

eth0: Speed 100BT

eth0: Link is up


~ # 
~ # ping 192.168.2.102^[[J
PING 192.168.2.102 (192.168.2.102): 56 data bytes
64 bytes from 192.168.2.102: icmp_seq=0 ttl=64 time=3.0 ms
64 bytes from 192.168.2.102: icmp_seq=1 ttl=64 time=1.1 ms
64 bytes from 192.168.2.102: icmp_seq=2 ttl=64 time=1.1 ms

--- 192.168.2.102 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.1/1.7/3.0 ms

^ permalink raw reply

* clock speed gone from cpuinfo
From: Olaf Hering @ 2006-01-18 20:23 UTC (permalink / raw)
  To: linuxppc-dev


2.6.16 on 32bit doesnt report the cpu speed anymore, but it still has
the bogomips..
chrp_calibrate_decr doesnt seem to set ppc_proc_freq.

lemon:~ # cat /proc/cpuinfo
processor       : 0
cpu             : 604r
revision        : 49.2 (pvr 0009 3102)
bogomips        : 41.47
timebase        : 20781060
machine         : CHRP IBM,7046-B50
lemon:~ # dmesg | grep freq
time_init: decrementer frequency = 20.781060 MHz
time_init: processor frequency   = 0.000000 MHz





While looking at generic_calibrate_decr(), cpu and fp are pointers.

 arch/powerpc/kernel/time.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

Index: linux-2.6.16-rc1-olh/arch/powerpc/kernel/time.c
===================================================================
--- linux-2.6.16-rc1-olh.orig/arch/powerpc/kernel/time.c
+++ linux-2.6.16-rc1-olh/arch/powerpc/kernel/time.c
@@ -612,10 +612,10 @@ void __init generic_calibrate_decr(void)
 
 	ppc_tb_freq = DEFAULT_TB_FREQ;		/* hardcoded default */
 	node_found = 0;
-	if (cpu != 0) {
+	if (cpu) {
 		fp = (unsigned int *)get_property(cpu, "timebase-frequency",
 						  NULL);
-		if (fp != 0) {
+		if (fp) {
 			node_found = 1;
 			ppc_tb_freq = *fp;
 		}
@@ -626,10 +626,10 @@ void __init generic_calibrate_decr(void)
 
 	ppc_proc_freq = DEFAULT_PROC_FREQ;
 	node_found = 0;
-	if (cpu != 0) {
+	if (cpu) {
 		fp = (unsigned int *)get_property(cpu, "clock-frequency",
 						  NULL);
-		if (fp != 0) {
+		if (fp) {
 			node_found = 1;
 			ppc_proc_freq = *fp;
 		}

-- 
short story of a lazy sysadmin:
 alias appserv=wotan

^ permalink raw reply

* [PATCH] Add support for Freescale 83xx Host Mode USB
From: Randy Vinson @ 2006-01-18 18:54 UTC (permalink / raw)
  To: linuxppc-dev

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

Greetings,
     I've attached a patch (based on 2.6.16-rc1) which adds Host mode
support for the Dual-Role(DR) and Multi-Port-Host (MPH) USB controllers
found in the Freescale 8349. Note that this patch only provides the
platform-specific code that sets up the external hardware and pin
configuration. The actual DR and MPH controller driver is being posted
on the linux-usb-devel mailing list.

     Using a Freescale 8349CDS reference board, the DR controller was
successfully tested using a USB 2.0 high speed FLASH drive, a USB 1.1
full speed 4-port hub and a Siemens SpeedStream USB to Ethernet adapter.
The MPH controller has been successfully tested with a USB 2.0 high
speed FLASH drive. Attempts to run USB 1.1 devices with the MPH
controller have proven unsuccessful.


           Randy Vinson
           MontaVista Software



[-- Attachment #2: 8349_usb_platform.patch --]
[-- Type: text/plain, Size: 8580 bytes --]

Adding platform support for the 834x Host Mode USB controller.

This patch provides the platform-specific hardware setup required by the
83xx Host Mode USB controller on the Freescale 8349CDS reference system.

Signed-off-by: Randy Vinson <rvinson@mvista.com>

---
commit 30b1d2d35237f0367aeceb1bc9f62c9fdc46dbff
tree 64af0c1897f30bb1adb72ecbb6f4c4d0ef619639
parent 2581e186c343cd26802279bd80e420307037fbc6
author Randy Vinson <rvinson@linuxbox.(none)> Tue, 17 Jan 2006 16:32:23 -0700
committer Randy Vinson <rvinson@linuxbox.(none)> Tue, 17 Jan 2006 16:32:23 -0700

 arch/ppc/Kconfig                      |    2 +
 arch/ppc/platforms/83xx/Kconfig       |   28 +++++++++
 arch/ppc/platforms/83xx/mpc834x_sys.c |  100 +++++++++++++++++++++++++++++++++
 arch/ppc/platforms/83xx/mpc834x_sys.h |    3 +
 arch/ppc/syslib/mpc83xx_devices.c     |   16 +++++
 include/asm-ppc/mpc83xx.h             |   17 ++++++
 6 files changed, 166 insertions(+), 0 deletions(-)

diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 11899f0..b33b0eb 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -681,6 +681,8 @@ config EV64360
 	  platform.
 endchoice
 
+source arch/ppc/platforms/83xx/Kconfig
+
 config PQ2ADS
 	bool
 	depends on ADS8272
diff --git a/arch/ppc/platforms/83xx/Kconfig b/arch/ppc/platforms/83xx/Kconfig
new file mode 100644
index 0000000..90bc67a
--- /dev/null
+++ b/arch/ppc/platforms/83xx/Kconfig
@@ -0,0 +1,28 @@
+config 834x_USB_SUPPORT
+	bool "834x USB Support"
+	depends on MPC834x_SYS
+	default y
+	---help---
+	  Enables support for the USB controllers on the MPC834x chip. The 834x
+	  reference board is wired for only one USB port. That port may be
+	  used by either the MPH or DR USB controller.
+	  Requires USB Host EHCI support.
+	  If unsure, say Y.
+choice
+	prompt "834x USB Controller Selection"
+	depends on 834x_USB_SUPPORT
+	default 834x_DR_USB_SUPPORT
+
+config 834x_DR_USB_SUPPORT
+	bool "DR Controller"
+	select USB_EHCI_ROOT_HUB_TT
+	---help---
+	  Select if using the Dual-Role (DR) USB controller.
+
+config 834x_MPH_USB_SUPPORT
+	bool "MPH Controller"
+	---help---
+	  Select if using the Multi-Port-Host (MPH) USB controller.
+
+endchoice
+
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
index 012e1e6..6f23909 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -11,6 +11,9 @@
  * 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.
+ *
+ * USB setup added by Randy Vinson <rvinson@mvista.com> based on code from
+ * Hunter Wu.
  */
 
 #include <linux/config.h>
@@ -93,6 +96,99 @@ mpc83xx_exclude_device(u_char bus, u_cha
 }
 #endif /* CONFIG_PCI */
 
+/*
+ * Configure the on-chip USB controller. The MPC834xCDS only supports the
+ * second USB interface (port 1). This code sets up the hardware and then
+ * lets the platform driver take over device setup.
+ */
+
+#ifdef CONFIG_834x_USB_SUPPORT
+void mpc834x_board_init(void)
+{
+	unsigned char __iomem *bcsr;
+	volatile unsigned char *bcsr5_p;
+
+	/*
+	 * if SYS board is plug into PIB board,
+	 * force to use the PHY on SYS board
+	 * */
+	bcsr = ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
+	bcsr5_p = bcsr + BCSR5_OFF;
+	if ( (*bcsr5_p & BCSR5_INT_USB) == 0 )
+		*bcsr5_p = (*bcsr5_p | BCSR5_INT_USB);
+	iounmap(bcsr);
+}
+
+void mpc834x_usb_clk_cfg(void)
+{
+	unsigned long sccr;
+	volatile unsigned long *p;
+
+	p = (volatile unsigned long *)(VIRT_IMMRBAR + MPC83XX_SCCR_OFFS); /* SCCR */
+	sccr = *p;
+
+	sccr |= MPC83XX_SCCR_USB_MPHCM_11 | MPC83XX_SCCR_USB_DRCM_11;
+
+	*p = sccr;
+}
+
+static void mpc834x_usb_pin_cfg(struct fsl_usb2_platform_data *pdata)
+{
+	unsigned long sicrl;
+	volatile unsigned long *p;
+
+	p = (volatile unsigned long *)(VIRT_IMMRBAR + MPC83XX_SICRL_OFFS); /* SCCR */
+	sicrl = *p;
+
+	/* set both ports to MPH mode */
+	sicrl &= ~(MPC83XX_SICRL_USB0 | MPC83XX_SICRL_USB1);
+
+	if (pdata->operating_mode == FSL_USB2_DR_HOST) {
+		if (pdata->phy_mode == FSL_USB2_PHY_UTMI_WIDE) {
+			/* UTMI WIDE combines both ports into a single 16-bit port */
+			sicrl |= MPC83XX_SICRL_USB0 | MPC83XX_SICRL_USB1;
+		}
+		else {
+			if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
+				sicrl |= MPC83XX_SICRL_USB0;
+		}
+	}
+	*p = sicrl;
+}
+
+static void __init
+mpc834x_usb_init(void)
+{
+	struct fsl_usb2_platform_data *pdata;
+
+#ifdef CONFIG_834x_DR_USB_SUPPORT
+	ppc_sys_device_remove(MPC83xx_USB2_MPH);
+	pdata = (struct fsl_usb2_platform_data *) ppc_sys_get_pdata(MPC83xx_USB2_DR);
+
+	if (pdata) {
+		pdata->phy_mode = FSL_USB2_PHY_ULPI;
+		pdata->operating_mode = FSL_USB2_DR_HOST;
+		pdata->port_enables = FSL_USB2_PORT0_ENABLED;
+	}
+
+#elif defined(CONFIG_834x_MPH_USB_SUPPORT)
+	ppc_sys_device_remove(MPC83xx_USB2_DR);
+	pdata = (struct fsl_usb2_platform_data *) ppc_sys_get_pdata(MPC83xx_USB2_MPH);
+
+	if (pdata) {
+		pdata->phy_mode = FSL_USB2_PHY_ULPI;
+		pdata->operating_mode = FSL_USB2_MPH_HOST;
+		pdata->port_enables = FSL_USB2_PORT0_ENABLED;
+	}
+
+#endif
+	mpc834x_usb_pin_cfg(pdata);
+	mpc834x_board_init();
+	mpc834x_usb_clk_cfg();
+	return;
+}
+#endif /* CONFIG_834x_USB_SUPPORT */
+
 /* ************************************************************************
  *
  * Setup the architecture
@@ -144,6 +240,10 @@ mpc834x_sys_setup_arch(void)
 		memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6);
 	}
 
+#ifdef CONFIG_834x_USB_SUPPORT
+	mpc834x_usb_init();
+#endif
+
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
 		ROOT_DEV = Root_RAM0;
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.h b/arch/ppc/platforms/83xx/mpc834x_sys.h
index 2e514d3..fab3762 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.h
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.h
@@ -27,6 +27,9 @@
 #define BCSR_PHYS_ADDR		((uint)0xf8000000)
 #define BCSR_SIZE		((uint)(128 * 1024))
 
+#define BCSR5_OFF		0x05
+#define BCSR5_INT_USB		0x02
+
 #define BCSR_MISC_REG2_OFF	0x07
 #define BCSR_MISC_REG2_PORESET	0x01
 
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c
index f9b95de..916926c 100644
--- a/arch/ppc/syslib/mpc83xx_devices.c
+++ b/arch/ppc/syslib/mpc83xx_devices.c
@@ -23,6 +23,8 @@
 #include <asm/ppc_sys.h>
 #include <asm/machdep.h>
 
+static u64 mpc83xx_dma_mask = 0xffffffffULL;
+
 /* We use offsets for IORESOURCE_MEM since we do not know at compile time
  * what IMMRBAR is, will get fixed up by mach_mpc83xx_fixup
  */
@@ -50,6 +52,14 @@ static struct fsl_i2c_platform_data mpc8
 	.device_flags = FSL_I2C_DEV_SEPARATE_DFSRR,
 };
 
+/* Placeholder to be filled in by board code */
+static struct fsl_usb2_platform_data mpc83xx_fsl_dr_pdata = { 
+};
+
+/* Placeholder to be filled in by board code */
+static struct fsl_usb2_platform_data mpc83xx_fsl_mph_pdata = {
+};
+
 static struct plat_serial8250_port serial_platform_data[] = {
 	[0] = {
 		.mapbase	= 0x4500,
@@ -190,7 +200,10 @@ struct platform_device ppc_sys_platform_
 	[MPC83xx_USB2_DR] = {
 		.name = "fsl-usb2-dr",
 		.id	= 1,
+		.dev.platform_data = &mpc83xx_fsl_dr_pdata,
 		.num_resources	 = 2,
+		.dev.dma_mask	= &mpc83xx_dma_mask,
+		.dev.coherent_dma_mask = 0xffffffffULL,
 		.resource = (struct resource[]) {
 			{
 				.start	= 0x23000,
@@ -208,6 +221,9 @@ struct platform_device ppc_sys_platform_
 		.name = "fsl-usb2-mph",
 		.id	= 1,
 		.num_resources	 = 2,
+		.dev.platform_data = &mpc83xx_fsl_mph_pdata,
+		.dev.dma_mask	= &mpc83xx_dma_mask,
+		.dev.coherent_dma_mask = 0xffffffffULL,
 		.resource = (struct resource[]) {
 			{
 				.start	= 0x22000,
diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
index 7cdf60f..cd2baf7 100644
--- a/include/asm-ppc/mpc83xx.h
+++ b/include/asm-ppc/mpc83xx.h
@@ -95,6 +95,23 @@ extern unsigned char __res[];
 
 #define MPC83xx_CCSRBAR_SIZE	(1024*1024)
 
+#define MPC83XX_SCCR_OFFS          0xA08
+#define MPC83XX_SCCR_USB_MPHCM_11  0x00c00000
+#define MPC83XX_SCCR_USB_MPHCM_01  0x00400000
+#define MPC83XX_SCCR_USB_MPHCM_10  0x00800000
+#define MPC83XX_SCCR_USB_DRCM_11   0x00300000
+#define MPC83XX_SCCR_USB_DRCM_01   0x00100000
+#define MPC83XX_SCCR_USB_DRCM_10   0x00200000
+
+/* system i/o configuration register low */
+#define MPC83XX_SICRL_OFFS         0x114
+#define MPC83XX_SICRL_USB0         0x40000000
+#define MPC83XX_SICRL_USB1         0x20000000
+
+/* system i/o configuration register high */
+#define MPC83XX_SICRH_OFFS         0x118
+#define MPC83XX_SICRH_USB_UTMI     0x00020000
+
 /* Let modules/drivers get at immrbar (physical) */
 extern phys_addr_t immrbar;
 



^ permalink raw reply related

* Re: General GIT MO question
From: Grant Likely @ 2006-01-18 19:41 UTC (permalink / raw)
  To: Andrey Volkov; +Cc: David H. Lynch Jr., linuxppc-embedded
In-Reply-To: <43CE3475.9040406@varma-el.com>

Andrey Volkov wrote:
> Grant Likely wrote:
> 
>>David H. Lynch Jr. wrote:
>>>	I am looking for a clue here. How do you produce a clean set of
>>>granular patches including only what you want and not the all the steps
>>>and mis-steps along the way ?
>>
>>
> 
> Or use stg (http://www.procode.org/stgit/),
> steps 1-2 you could made by
>  stg new
> steps 3 trough 5 by :
>  stg refresh/stg export

cool!  I need to try that

Thanks,
g.

-- 
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
(403) 663-0761

^ permalink raw reply

* Re: AGPGART driver for ArticiaS - ioremap() problem
From: Gerhard Pircher @ 2006-01-18 19:40 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, debian-powerpc
In-Reply-To: <1137533072.4823.92.camel@localhost.localdomain>

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="us-ascii", Size: 2009 bytes --]

> > That's the problem: we don't have the datasheet for the ArticiaS. :-( 
> > But the driver initializes correctly with the Uninorth code now and
> > with the DRI/DRM code changed. (The code in drm_vm.c checks for Apple's
> > PCI vendor ID. Therefore I just added a check for MAI's PCI vendor ID.)
> > But the X server freezes after the login screen is displayed (IIRC the
> > mouse still works, but the keyboard is dead!?).
> 
> That check is only necessary because Apple bridge puts the AGP aperture
> at bus address 0. This is probably not the case for you. You may not
> have that right. Check what you put in agp_bridge->gart_bus_addr
Hmm, I'm not sure what value agp_bridge->gart_bus_addr should have. The BIOS
doesn't setup it and the VIA AGPGART driver even reads it out from the
northbridge's registers! Where does the value for agp_bridge->gart_bus_addr
come from? For now it is set to 0x0, which would require the modification in
drm_vm.c!?

> > >  - The AGP aperture itself. The main issue there is wether your
> > > chipset makes the AGP aperture visible to the CPU or not. The Apple
> > > UniNorth one doesn't for example, it;'s only visible to the graphic
> > > chip. That is why the uninorth driver sets cant_use_aperture to 1.
> > > That forces the DRM to generate AGP mappings by using the real memory 
> > > pages and putting them together into a virtual mapping instead of
> > > doing a direct mapping of the AGP aperture on the bus. Most x86
> > > chipsets however _can_, thus a simple remapping of pages is enough.
> 
> > Good question! How would I have to modify the Uninorth driver to use a
> > direct mapping of the AGP aperture on the bus?
> 
> Don't set cant_use_aperture to 1 :)
:) The driver seems to work better with cant_use_aperture set to 1, so I
leave it as it is. BTW: What's the meaning of needs_scratch_page?

Thanks for your support!

Gerhard

-- 
10 GB Mailbox, 100 FreeSMS/Monat http://www.gmx.net/de/go/topmail
+++ GMX - die erste Adresse für Mail, Message, More +++

^ permalink raw reply

* [PATCH] powerpc: replace linuxppc64.org references with penguinppc.org/ppc64/
From: Arthur Othieno @ 2006-01-18 18:53 UTC (permalink / raw)
  To: Hollis Blanchard; +Cc: linuxppc-dev, Olaf Hering
In-Reply-To: <1137599288.10689.2.camel@localhost.localdomain>

On Wed, Jan 18, 2006 at 09:48:08AM -0600, Hollis Blanchard wrote:
> On Wed, 2006-01-18 at 13:07 +0100, Olaf Hering wrote:
> >  On Wed, Jan 18, Arthur Othieno wrote:
> > 
> > > What about the s/linuxppc64\.org/penguinppc\.org/g case? Or is
> > > penguinppc64.org preferable? Or am I just taking it too far? ;)
> > 
> > They are redirected on DNS or HTTP level.
> 
> HTTP level, but that doesn't answer his question.
> 
> As the maintainer of that site, I would prefer to remove the
> linuxppc64.org reference.
 
[PATCH] powerpc: replace linuxppc64.org references with penguinppc.org/ppc64/

http://www.penguinppc.org/ppc64/ is the canonical URL for all things ppc64.
http://linuxppc64.org is just a redirect so update all references accordingly.

Signed-off-by: Arthur Othieno <apgo@patchbomb.org>

---

Depends on Olaf's: [PATCH] drop linuxppc64-dev


 MAINTAINERS |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

07edae4fcd285140c92dc32229043af1429196ce
diff --git a/MAINTAINERS b/MAINTAINERS
index 3283304..18dcfb3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -535,7 +535,7 @@ BROADBAND PROCESSOR ARCHITECTURE
 P:	Arnd Bergmann
 M:	arnd@arndb.de
 L:	linuxppc-dev@ozlabs.org
-W:	http://linuxppc64.org
+W:	http://www.penguinppc.org/ppc64/
 S:	Supported
 
 BTTV VIDEO4LINUX DRIVER
@@ -1608,7 +1608,7 @@ M:	paulus@au.ibm.com
 P:	Anton Blanchard
 M:	anton@samba.org
 M:	anton@au.ibm.com
-W:	http://linuxppc64.org
+W:	http://www.penguinppc.org/ppc64/
 L:	linuxppc-dev@ozlabs.org
 S:	Supported
 
-- 
1.0.0b

^ permalink raw reply related

* Re: Feedback: Support for fn key on Apple PowerBooks
From: Michael Hanselmann @ 2006-01-18 19:10 UTC (permalink / raw)
  To: Frank Arnold; +Cc: linuxppc-dev
In-Reply-To: <1137594633.3466.151.camel@localhost>

On Wed, Jan 18, 2006 at 03:30:33PM +0100, Frank Arnold wrote:
> Anyway, perhaps I'm biased. I can live with both, now that I know where
> to set it.

You can also pass the usbhid.pb_fnmode parameter when loading the
kernel. For example, append="video=radeonfb usbhid.pb_fnmode=2" with
yaboot.

Greets,
Michael

-- 
Gentoo Linux developer, http://hansmi.ch/, http://forkbomb.ch/

^ permalink raw reply

* Re: [PATCH] drop linuxppc64-dev
From: Hollis Blanchard @ 2006-01-18 15:48 UTC (permalink / raw)
  To: Olaf Hering; +Cc: linuxppc-dev
In-Reply-To: <20060118120715.GB19765@suse.de>

On Wed, 2006-01-18 at 13:07 +0100, Olaf Hering wrote:
>  On Wed, Jan 18, Arthur Othieno wrote:
> 
> > What about the s/linuxppc64\.org/penguinppc\.org/g case? Or is
> > penguinppc64.org preferable? Or am I just taking it too far? ;)
> 
> They are redirected on DNS or HTTP level.

HTTP level, but that doesn't answer his question.

As the maintainer of that site, I would prefer to remove the
linuxppc64.org reference.

-Hollis

^ permalink raw reply

* Re: 2.6.16-rc1: iptables broken on ppc32?
From: Harald Welte @ 2006-01-18 15:01 UTC (permalink / raw)
  To: Mikael Pettersson; +Cc: linuxppc-dev, netfilter-devel, linux-kernel
In-Reply-To: <17358.19458.555996.684819@alkaid.it.uu.se>

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

On Wed, Jan 18, 2006 at 03:09:06PM +0100, Mikael Pettersson wrote:
> When trying out kernel 2.6.16-rc1 on a ppc32 box (G4 eMac),
> the kernel refused to load my /etc/sysconfig/iptables. strace
> on /sbin/iptables-restore shows that the kernel returns EINVAL
> instead of accepting the configuration:

thanks for letting us know, you might have catched a very important bug.

We've introduced a number of changes (x_tables) that haven't received
testing on all architectures yet.

I will try to reproduce the bug on my debian ppc box here.

This is not meant as a fix, but you might try it to narrow down the
problem:  Try recompiling iptables on your own, and report back whether
that works or not.

Please Follow-up-to netfilter-devel@lists.netfilter.org

-- 
- Harald Welte <laforge@netfilter.org>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie

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

^ permalink raw reply

* [PATCH] dtc: add bus-frequency prop to SOC node
From: Becky Bruce @ 2006-01-18 15:20 UTC (permalink / raw)
  To: david; +Cc: linuxppc-dev

Updated SOC node definition in documentation to include bus-frequency
property. Also extended mdio example to match specification.

Signed-off-by: Becky Bruce <becky.bruce@freescale.com>

---
commit d7c0e0c8f51ac5023d92cdcf539f0ecea8a94e43
tree c66c0f8066d695e220a265cfdfbe6e508c5f3925
parent f192a7ae0ba797478920b7980159e0b2047b45f1
author Becky Bruce <becky.bruce@freescale.com> Wed, 18 Jan 2006 09:16:14 -0600
committer Becky Bruce <becky.bruce@freescale.com> Wed, 18 Jan 2006 09:16:14 -0600

 Documentation/booting-without-of.txt |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/Documentation/booting-without-of.txt b/Documentation/booting-without-of.txt
index 60d5b7a..39aa3c1 100644
--- a/Documentation/booting-without-of.txt
+++ b/Documentation/booting-without-of.txt
@@ -880,6 +880,9 @@ address which can extend beyond that lim
     - device_type : Should be "soc"
     - ranges : Should be defined as specified in 1) to describe the
       translation of SOC addresses for memory mapped SOC registers.  
+    - bus-frequency: Contains the bus frequency for the SOC node.
+      Typically, the value of this field is filled in by the boot
+      loader. 
 
   Recommended properties:
 
@@ -919,6 +922,7 @@ SOC.   
 		device_type = "soc";
 		ranges = <00000000 e0000000 00100000>
 		reg = <e0000000 00003000>;
+		bus-frequency = <0>;
 	}
 
 
@@ -1170,6 +1174,8 @@ platforms are moved over to use the flat
 
 	mdio@24520 {
 		reg = <24520 20>;
+		device_type = "mdio"; 
+		compatible = "gianfar";
 
 		ethernet-phy@0 {
 			......
@@ -1317,6 +1323,7 @@ not necessary as they are usually the sa
 		device_type = "soc";
 		ranges = <00000000 e0000000 00100000>
 		reg = <e0000000 00003000>;
+		bus-frequency = <0>;
 
 		mdio@24520 {
 			reg = <24520 20>;

^ permalink raw reply related

* Badness in kref_get at lib/kref.c:32, of_get_parent broken
From: Olaf Hering @ 2006-01-18 15:18 UTC (permalink / raw)
  To: linuxppc-dev

2.6.16-rc1-git1 gives these warnings in early boot:


Total memory = 512MB; using 1024kB for hash table (at cfe00000)
Linux version 2.6.16-rc1-git1-pegasos2 (olaf@pomegranate) (gcc version 3.3.3 (SuSE Linux)) #21 Wed Jan 18 15:15:25 CET 2006
Found initrd at 0xc2711000:0xc293d578
Found legacy serial port 0 for /pci@80000000/isa@C/serial@i2F8
  port=2f8, taddr=ffffffff, irq=ffffffff, clk=1843200, speed=0
chrp type = 6
Pegasos l2cr : L2 cache was not active, activating
PCI bus 0 controlled by pci at 80000000
Badness in kref_get at /home/olaf/kernel/olh/ppc64/linux-2.6.16-rc1-olh/lib/kref.c:32
Call Trace:
[C0379D00] [C0007A20] show_stack+0x5c/0x184 (unreliable)
[C0379D30] [C000E150] program_check_exception+0x184/0x584
[C0379D90] [C000F6D8] ret_from_except_full+0x0/0x4c
--- Exception: 700 at kref_get+0xc/0x24
    LR = of_node_get+0x24/0x3c
[C0379E50] [C004FD20] __pte_alloc_kernel+0x64/0x80 (unreliable)
[C0379E70] [C000CB04] of_get_parent+0x34/0x58
[C0379E90] [C0009C04] of_get_address+0x24/0x174
[C0379ED0] [C000A1F4] of_address_to_resource+0x24/0x68
[C0379F00] [C038917C] chrp_find_bridges+0x114/0x470
[C0379F90] [C0388E38] chrp_setup_arch+0x1fc/0x32c
[C0379FB0] [C03829A0] setup_arch+0x144/0x188
[C0379FD0] [C037A45C] start_kernel+0x34/0x1a8
[C0379FF0] [000037A0] 0x37a0
Badness in kref_get at /home/olaf/kernel/olh/ppc64/linux-2.6.16-rc1-olh/lib/kref.c:32
Call Trace:
[C0379C90] [C0007A20] show_stack+0x5c/0x184 (unreliable)
[C0379CC0] [C000E150] program_check_exception+0x184/0x584
[C0379D20] [C000F6D8] ret_from_except_full+0x0/0x4c
--- Exception: 700 at kref_get+0xc/0x24
    LR = of_node_get+0x24/0x3c
[C0379DE0] [00002700] 0x2700 (unreliable)
[C0379E00] [C000CB04] of_get_parent+0x34/0x58
[C0379E20] [C0009DD4] of_translate_address+0x2c/0x2fc
[C0379EA0] [C000A0D4] __of_address_to_resource+0x30/0xc4
[C0379ED0] [C000A21C] of_address_to_resource+0x4c/0x68
[C0379F00] [C038917C] chrp_find_bridges+0x114/0x470
[C0379F90] [C0388E38] chrp_setup_arch+0x1fc/0x32c
[C0379FB0] [C03829A0] setup_arch+0x144/0x188
[C0379FD0] [C037A45C] start_kernel+0x34/0x1a8
[C0379FF0] [000037A0] 0x37a0
PCI bus 0 controlled by pci at c0000000
Top of RAM: 0x20000000, Total RAM: 0x20000000
Memory hole size: 0MB
On node 0 totalpages: 131072
  DMA zone: 131072 pages, LIFO batch:31
  DMA32 zone: 0 pages, LIFO batch:0
  Normal zone: 0 pages, LIFO batch:0
  HighMem zone: 0 pages, LIFO batch:0
Built 1 zonelists
Kernel command line: debug sysrq=1 root=/dev/hda7 
PID hash table entries: 4096 (order: 12, 65536 bytes)
time_init: decrementer frequency = 33.333333 MHz
time_init: processor frequency   = 0.000000 MHz
Console: colour dummy device 80x25
Dentry cache hash table entries: 131072 (order: 7, 524288 bytes)
Inode-cache hash table entries: 65536 (order: 6, 262144 bytes)
High memory: 0k
Memory: 511232k/524288k available (3064k kernel code, 12564k reserved, 484k data, 457k bss, 144k init)
Calibrating delay loop... 66.56 BogoMIPS (lpj=133120)
Mount-cache hash table entries: 512
checking if image is initramfs... it is
Freeing initrd memory: 2225k freed
NET: Registered protocol family 16
PCI: Probing PCI hardware
usbcore: registered new driver usbfs
usbcore: registered new driver hub
Initializing Cryptographic API
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered
PCI: Enabling device 0001:01:08.0 (0002 -> 0003)
radeonfb: Found Intel x86 BIOS ROM Image
radeonfb: No ATY,RefCLK property !
radeonfb: Retrieved PLL infos from BIOS
radeonfb: Reference=27.00 MHz (RefDiv=12) Memory=240.00 Mhz, System=200.25 MHz
radeonfb: PLL min 20000 max 40000
radeonfb: Monitor 1 type DFP found
radeonfb: EDID probed
radeonfb: Monitor 2 type no found
radeonfb: Assuming panel size 8x1
Console: switching to colour frame buffer device 80x25
radeonfb (0001:01:08.0): ATI Radeon Y` 
Generic RTC Driver v1.07
Macintosh non-volatile memory driver v1.1
serio: i8042 AUX port at 0x60,0x64 irq 12
serio: i8042 KBD port at 0x60,0x64 irq 1
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports, IRQ sharing disabled
serial8250.0: ttyS0 at I/O 0x2f8 (irq = 3) is a 16550A
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
loop: loaded (max 8 devices)
Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=xx
VP_IDE: IDE controller at PCI slot 0000:00:0c.1
VP_IDE: chipset revision 6
VP_IDE: VIA vt8231 (rev 10) IDE UDMA100 controller on pci0000:00:0c.1
VP_IDE: 100% native mode on irq 14
    ide0: BM-DMA at 0x1020-0x1027, BIOS settings: hda:pio, hdb:pio
    ide1: BM-DMA at 0x1028-0x102f, BIOS settings: hdc:pio, hdd:pio
Probing IDE interface ide0...
hda: SAMSUNG SP0802N, ATA DISK drive
ide0 at 0x1000-0x1007,0x100e on irq 14
Probing IDE interface ide1...
hdc: TSSTcorpCD/DVDW TS-H552U, ATAPI CD/DVD-ROM drive
ide1 at 0x1010-0x1017,0x101e on irq 15
hda: max request size: 512KiB
hda: 156368016 sectors (80060 MB) w/2048KiB Cache, CHS=16383/255/63, UDMA(100)
hda: cache flushes supported
 hda: RDSK (512) hda1 (LNX^@)(res 2 spb 1) hda2 (SWP^@)(res 2 spb 1) hda3 (LNX^@)(res 2 spb 1) hda4 (LNX^@)(res 2 spb 1) hda5 (LNX^@)(res 2 spb 1) hda6 (LNX^@)(res 2 spb 1) hda7 (LNX^@)(res 2 spb 1)
ohci_hcd: 2005 April 22 USB 1.1 'Open' Host Controller (OHCI) Driver (PCI)
PCI: Enabling device 0000:00:05.0 (0000 -> 0002)
ohci_hcd 0000:00:05.0: OHCI Host Controller
ohci_hcd 0000:00:05.0: new USB bus registered, assigned bus number 1
ohci_hcd 0000:00:05.0: irq 9, io mem 0x80000000
usb usb1: configuration #1 chosen from 1 choice
hub 1-0:1.0: USB hub found
hub 1-0:1.0: 3 ports detected
PCI: Enabling device 0000:00:05.1 (0000 -> 0002)
ohci_hcd 0000:00:05.1: OHCI Host Controller
ohci_hcd 0000:00:05.1: new USB bus registered, assigned bus number 2
ohci_hcd 0000:00:05.1: irq 9, io mem 0x80001000
usb usb2: configuration #1 chosen from 1 choice
hub 2-0:1.0: USB hub found
hub 2-0:1.0: 2 ports detected
usbcore: registered new driver libusual
usbcore: registered new driver hiddev
usbcore: registered new driver usbhid
/home/olaf/kernel/olh/ppc64/linux-2.6.16-rc1-olh/drivers/usb/input/hid-core.c: v2.6:USB HID core driver
mice: PS/2 mouse device common for all mice
md: md driver 0.90.3 MAX_MD_DEVS=256, MD_SB_DISKS=27
md: bitmap version 4.39
NET: Registered protocol family 2
atkbd.c: keyboard reset failed on isa0060/serio1
IP route cache hash table entries: 32768 (order: 5, 131072 bytes)
TCP established hash table entries: 131072 (order: 9, 2097152 bytes)
TCP bind hash table entries: 65536 (order: 8, 1310720 bytes)
TCP: Hash tables configured (established 131072 bind 65536)
TCP reno registered
TCP westwood registered
TCP htcp registered
NET: Registered protocol family 1
NET: Registered protocol family 17
Freeing unused kernel memory: 144k init
input: AT Translated Set 2 keyboard as /class/input/input0
kjournald starting.  Commit interval 5 seconds
EXT3-fs: mounted filesystem with ordered data mode.
Adding 1044216k swap on /dev/hda2.  Priority:-1 extents:1 across:1044216k
EXT3 FS on hda7, internal journal
md: Autodetecting RAID arrays.
md: autorun ...
md: ... autorun DONE.
device-mapper: 4.5.0-ioctl (2005-10-04) initialised: dm-devel@redhat.com
PCI: Enabling device 0000:00:05.2 (0000 -> 0002)
ehci_hcd 0000:00:05.2: EHCI Host Controller
ehci_hcd 0000:00:05.2: new USB bus registered, assigned bus number 3
ehci_hcd 0000:00:05.2: irq 9, io mem 0x80002000
ehci_hcd 0000:00:05.2: USB 2.0 started, EHCI 1.00, driver 10 Dec 2004
usb usb3: configuration #1 chosen from 1 choice
hub 3-0:1.0: USB hub found
hub 3-0:1.0: 5 ports detected
via-rhine.c:v1.10-LK1.2.0-2.6 June-10-2004 Written by Donald Becker
PCI: Enabling device 0000:00:0d.0 (0005 -> 0007)
eth0: VIA Rhine II at 0x80002100, 00:0b:2f:4b:f6:8f, IRQ 9.
eth0: MII PHY found at address 16, status 0x786d advertising 01e1 Link 45e1.
PCI: Enabling device 0000:00:0c.5 (0000 -> 0001)
parport_pc: VIA 686A/8231 detected
parport_pc: probing current configuration
parport_pc: Current parallel port base: 0x3BC
parport0: PC-style at 0x3bc, irq 7 [PCSPP]
ieee1394: Initialized config rom entry `ip1394'
parport_pc: VIA parallel port: io=0x3BC, irq=7
PCI: Enabling device 0000:00:01.0 (0000 -> 0003)
ohci1394: fw-host0: OHCI-1394 1.0 (PCI): IRQ=[9]  MMIO=[80002800-80002fff]  Max Packet=[2048]  IR/IT contexts=[8/8]
ieee1394: Host added: ID:BUS[0-00:1023]  GUID[0011060000004b2f]
eth0: link up, 100Mbps, full-duplex, lpa 0x45E1

-- 
short story of a lazy sysadmin:
 alias appserv=wotan

^ 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