LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] powerpc: Instrument Hypervisor Calls
From: Mike Kravetz @ 2006-08-25 18:52 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <17645.19790.527223.207556@cargo.ozlabs.ibm.com>

On Thu, Aug 24, 2006 at 04:55:10PM +1000, Paul Mackerras wrote:
> > +	/* calculate address of stat structure */		\
> > +	ld	r4,STK_PARM(r3)(r1);	/* use opcode as */	\
> > +	rldicl	r4,r4,62,2;		/* index into array */	\
> > +	mulli	r4,r4,HCALL_STAT_SIZE;				\
> 
> It's a pity our multiplies are slow (6 cycles).  The rldicl would I
> think be more clearly expressed as srdi r4,r4,2.  We could use a shift
> and add instead of the multiply if we put a big fat comment in the
> header that defines the structure warning people to adjust the
> assembly if they change the structure.  Might not be worth it though.

I would rather keep the multiply and minimal safety it provides when
people change the structure.

> BTW are we going to die horribly if someone uses an hcall greater than
> MAX_HCALL_OPCODES?  The hcall functions are available to modules, so
> it would be quite possible for a module to come along and try to use
> some new hcalls that weren't known about when the kernel was built.

Yes, bad things would happen.  This is/was a bad assumption on my part
that all callers would pass in valid opcodes.  I'll put in a simple check
for that.

-- 
Mike

^ permalink raw reply

* RE: "ip=" command line strangeness...
From: T Ziomek @ 2006-08-25 19:18 UTC (permalink / raw)
  To: Claus Gindhart; +Cc: linuxppc-embedded
In-Reply-To: <DADA32856852FC458E0F96B664A6F55E011E2425@kom-mailsrv1.kontron-modular.com>

> please provide the ip-commandline in the full-size format
> ip=<my ip>:<server ip>:<host ip>:<net mask>:<hostname>:<which ethernet port, e.g. "eth0">

The port should be followed by ":<autoconf>", right?  I'm basing that on 
Documentation/nfsroot.txt .

> I assume, that this will fix your problem

Meh...that string is so bloody long I don't want to bother trying it since
I know that "ip=<my IP>:gibberish" works well enough...

Somebody else suggested "ip=<my IP> off"; that had no effect.  Neither did 
"ip=<my IP>::::::" or "ip=<my IP>::::::off" (which I have successfully
used with 2.4).

I'm just going to stick with my silly workaround.  Thanks to all for the
suggestions though.
Tom
-- 
   /"\  ASCII Ribbon Campaign   |
   \ /                          |   Email to user 'CTZ001'
    X        Against HTML       |             at 'email.mot.com'
   / \     in e-mail & news     |

^ permalink raw reply

* Re: "ip=" command line strangeness...
From: Dan Malek @ 2006-08-25 19:32 UTC (permalink / raw)
  To: T Ziomek; +Cc: linuxppc-embedded
In-Reply-To: <Pine.WNT.4.61.0608251400100.200@holyoke.labs.mot.com>


On Aug 25, 2006, at 3:18 PM, T Ziomek wrote:

>> please provide the ip-commandline in the full-size format
>> ip=<my ip>:<server ip>:<host ip>:<net mask>:<hostname>:<which  
>> ethernet port, e.g. "eth0">
>
> The port should be followed by ":<autoconf>", right?  I'm basing  
> that on
> Documentation/nfsroot.txt .

Documentation is out of date.  After the port number should be
one of:
	off | none
	on | any
	dhcp | bootp | rarp
	both

I usually use 'on' or 'any' to cause the autoconfig to happen.

> Meh...that string is so bloody long I don't want to bother trying  
> it since
> I know that "ip=<my IP>:gibberish" works well enough...

If you run a dhcp server (which I do), all you need is 'ip=any'.
If you are really doing the configuration with all of those options
on the command line, you have to use 'off' after the port
identifier or it will try to contact a server using one of the
configured protocols (dhcp, bootp. rarp) to get the information.


	-- Dan

^ permalink raw reply

* Re: [PATCH] reboot when panic_timout is set
From: Olaf Hering @ 2006-08-25 20:14 UTC (permalink / raw)
  To: Mike Strosaker; +Cc: linuxppc-dev, Paul Mackeras
In-Reply-To: <44EF428B.8010100@austin.ibm.com>

On Fri, Aug 25, Mike Strosaker wrote:

> Olaf Hering wrote:
> 
> >Only call into RTAS when booted with panic=0 because the RTAS call does 
> >not return.
> >The system has to be rebooted via the HMC or via the management console 
> >right now.
> >This is cumbersome and not what the default panic=180 is supposed to do.
> > 
> >
> The os-term call is supposed to indicate to the platform that it should 
> follow it's abnormal OS termination policy.  I normally set my 
> partitions to reboot immediately after an os-term call.  I believe that 
> "/usr/sbin/serv_config -b" (installed with powerpc-utils-papr) is used 
> to set that policy from the command line.

That doesnt help me at all if the kernel crashes before it reaches
/init. And if one has to call a binary anyway to set or upgrade the
policy, this binary can also set /proc/sys/kernel/panic to 0.

Do I have to set it for each boot, or is a change permanent?

^ permalink raw reply

* Re: [CFT] ELF Relocatable x86 and x86_64 bzImages
From: Vivek Goyal @ 2006-08-25 20:16 UTC (permalink / raw)
  To: Eric W. Biederman
  Cc: fastboot, Jan Kratochvil, linux-kernel, Linda Wang, Horms,
	H. Peter Anvin, linuxppc64-dev
In-Reply-To: <m1u04x4uiv.fsf_-_@ebiederm.dsl.xmission.com>

On Mon, Jul 31, 2006 at 10:19:04AM -0600, Eric W. Biederman wrote:
> 
> I have spent some time and have gotten my relocatable kernel patches
> working against the latest kernels.  I intend to push this upstream
> shortly.
> 
> Could all of the people who care take a look and test this out
> to make certain that it doesn't just work on my test box?
> 
> My approach is to extend bzImage so that it is an ET_DYN ELF executable
> (we have what used to be a bootsector where we can put the header).
> Boot loaders are explicitly not expected to process relocations.
> 
> The x86_64 kernel is simply built to live at a fixed virtual address
> and the boot page tables are relocated.  The i386 kernel is built
> to process relocates generated with --embedded-relocs (after vmlinux.lds.S)
> has been fixed up to sort out static and dynamic relocations.
> 
> Currently there are 33 patches in my tree to do this.
> 
> The weirdest symptom I have had so far is that page faults did not
> trigger the early exception handler on x86_64 (instead I got a reboot).
> 
> The code should be available shortly at:
> git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/linux-2.6-reloc.git#reloc-v2.6.18-rc3
> 
> If all goes well with the testing I will push the patches to Andrew in the next couple 
> of days.

It breaks powerpc build as poewrpc does not seem to be defining symbol
_text which is used by arch independent kallsyms.c. Attached is the one
line fix.

Thanks
Vivek


o ppc64 does not seem to be defining symbol _text  which is used by
  kernel/kallsyms.c for relocatable kernel patches. Instead of absolute
  symbol addresses now it is stored as offset from symbol _text
  (_text + offset) so that relocations entries for this section are
  generated, if need be. (currently i386 will be the only user once
  the relocatable kernel patches are merged).

Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com>
---

 arch/powerpc/kernel/vmlinux.lds.S |    1 +
 1 file changed, 1 insertion(+)

diff -puN arch/powerpc/kernel/vmlinux.lds.S~ppc64-compilation-fix arch/powerpc/kernel/vmlinux.lds.S
--- linux-2.6.18-rc3-1M/arch/powerpc/kernel/vmlinux.lds.S~ppc64-compilation-fix	2006-08-24 16:16:17.000000000 -0400
+++ linux-2.6.18-rc3-1M-root/arch/powerpc/kernel/vmlinux.lds.S	2006-08-24 16:26:33.000000000 -0400
@@ -33,6 +33,7 @@ SECTIONS
 
 	/* Text and gots */
 	.text : {
+		_text = .;
 		*(.text .text.*)
 		SCHED_TEXT
 		LOCK_TEXT
_

^ permalink raw reply

* [PATCH] fixup ibm_architecture_vec definition
From: Will Schmidt @ 2006-08-25 20:46 UTC (permalink / raw)
  To: linuxppc-dev, Paul Mackerras; +Cc: Paul Mackerras

Hi, 

This problem was noticed by one of the Phyp firmware folks.
Our ibm,client-architecture-support call was failing.

This patch correctly terminates the PVR list, and corrects the vector
length parms being passed in.  

Please apply.   :-) 

Signed-off-by: Will Schmidt <will_schmidt@vnet.ibm.com>

diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 462bced..7065390 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -643,16 +643,17 @@ static unsigned char ibm_architecture_ve
 	W(0xfffe0000), W(0x003a0000),	/* POWER5/POWER5+ */
 	W(0xffff0000), W(0x003e0000),	/* POWER6 */
 	W(0xfffffffe), W(0x0f000001),	/* all 2.04-compliant and earlier */
+	W(0x00000000), W(0xffffffff),	/* Terminator-list-entry */
 	5 - 1,				/* 5 option vectors */
 
 	/* option vector 1: processor architectures supported */
-	3 - 1,				/* length */
+	3 - 2,				/* length */
 	0,				/* don't ignore, don't halt */
 	OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
 	OV1_PPC_2_04 | OV1_PPC_2_05,
 
 	/* option vector 2: Open Firmware options supported */
-	34 - 1,				/* length */
+	34 - 2,				/* length */
 	OV2_REAL_MODE,
 	0, 0,
 	W(0xffffffff),			/* real_base */
@@ -666,16 +667,16 @@ static unsigned char ibm_architecture_ve
 	48,				/* max log_2(hash table size) */
 
 	/* option vector 3: processor options supported */
-	3 - 1,				/* length */
+	3 - 2,				/* length */
 	0,				/* don't ignore, don't halt */
 	OV3_FP | OV3_VMX,
 
 	/* option vector 4: IBM PAPR implementation */
-	2 - 1,				/* length */
+	2 - 2,				/* length */
 	0,				/* don't halt */
 
 	/* option vector 5: PAPR/OF options */
-	3 - 1,				/* length */
+	3 - 2,				/* length */
 	0,				/* don't ignore, don't halt */
 	OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES,
 };

^ permalink raw reply related

* Re: [PATCH] powerpc: Support for "weird" MPICs and fixup mpc7448_hpc2
From: Benjamin Herrenschmidt @ 2006-08-25 22:50 UTC (permalink / raw)
  To: Zang Roy-r61911; +Cc: linuxppc-dev list, Paul Mackerras
In-Reply-To: <1156492062.7107.26.camel@localhost.localdomain>

On Fri, 2006-08-25 at 15:47 +0800, Zang Roy-r61911 wrote:
> On Fri, 2006-08-25 at 12:16, Benjamin Herrenschmidt wrote:
> > This patch is a slightly cleaned up version of Zang Roy's support for
> > the TSI108 MPIC variant. It also fixes up MPC7448_hpc2 to use the new
> > version of the type macros and changes the way MPIC is selected in
> > Kconfig to better match what is done for other system devices.
> > 
> > Signed-off-by: Roy Zang <tie-fei.zang@freescale.com> 
> > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > ---
> > 
> > Zang Roy, please verify that it still works for you. I've tested it on
> > an Apple G5 with and without CONFIG_MPIC_WEIRD .
> > 
> 
> It works OK on my mpc7448hpc2 board. 
> There is a sequence for the patch applying.
> 
> (1) patch for IRQ update for mpc7448hpc2:
> http://ozlabs.org/pipermail/linuxppc-dev/2006-August/025559.html
> 
> (2) the weird mpic patch repost by your mail.
> (3) the following minor patch to build mpic.o for CONFIG_MPIC_WEIRD

The later shouldn't be needed.

CONFIG_MPIC_WEIRD is an _addition_ to CONFIG_MPIC. That is, for example,
your HPC2 platform should define both CONFIG_MPIC and CONFIG_MPIC_WEIRD

Ben.

^ permalink raw reply

* Re: [PATCH] powerpc: Improve IRQ radix tree locking
From: Benjamin Herrenschmidt @ 2006-08-25 22:54 UTC (permalink / raw)
  To: Milton Miller; +Cc: linuxppc-dev, Paul Mackerras, Anton Blanchard
In-Reply-To: <e991208eced0af7536e9f71bf6cb7016@bga.com>

On Fri, 2006-08-25 at 09:42 -0500, Milton Miller wrote:
> On Fri Aug 25 16:04:52 EST 2006,  Benjamin Herrenschmidt wrote:
> > When reworking the powerpc irq code, I figured out that we were using
> > the radix tree in a racy way. As a temporary fix, I put a spinlock in
> > there. However, this can have a significant impact on performances. 
> > This
> > patch reworks that to use a smarter technique based on the fact that
> > what we need is in fact a rwlock with extremely rare writers (thus
> > optimized for the read path).
> 
> 
> > +static void irq_radix_wrlock(unsigned long *flags)
> > +{
> > +       unsigned int cpu, ok;
> > +
> > +       spin_lock_irqsave(&irq_big_lock, *flags);
> > +       irq_radix_writer = 1;
> 
> I think the smp_mb() is needed after here
> 
> > +       do {
> > +               ok = 1;
> > +               smp_mb();
> 
> but not every time we poll the cpus.  We are only
> updating our local variable ok which we have not
> given anyone else.   It could even be a register.

Doesn't really matter, the write case is extremely rare and not at all
performance critical. If I don't put the mb in the loop, I wonder if the
compiler might start optimizing out the reads... and I don't want to add
a volatile in there. I feel safer with the smp_mb() in there.

> > +               for_each_possible_cpu(cpu) {
> > +                       if (per_cpu(irq_radix_reader, cpu)) {
> > +                               ok = 0;
> > +                               break;
> > +                       }
> > +               }
> > +               if (!ok)
> > +                       cpu_relax();
> 
> Hmmm.  the gcc barrier is conditional.   How about putting
> barrier() before the ok=1 at the top, to avoid any optimization
> blockage but still telling gcc you must read every time?

Yeah, well, as I said, smp_mb() hits both cases and this isn't perf.
critical... 

> > +       } while(!ok);
> > +}
> > +
> 
> Oh, and how about some (un)likely in irq_radix_rdlock ?  It
> could happen by default by why not show our expected path?

Yup, that would make sense. I might also drop the first test of
irq_radix_writer. The will penalize a bit more the contention case vs.
the read case but that's exactly what I want...

> And, while I'm thinking of changes, when set ok=0 above add:
> #ifdef CONFIG_SPINLOCK_DEBUG
>                                BUG_ON(cpu == smp_processor_id());
> #endif

Do you see any case where I might actually hit that ? :)

> Hmm... just thought of something .... we are spinning under
> irq lock.  We are waiting on some other thread, but not
> telling the hypervisor.   Should we confer our execution
> over to the cpu we are waiting on?  I know, it sounds ugly
> to call that code.   I guess we would want a
> cpu_waiting_on(cpu) that calls cpu_relax and/or hypervisor.

I'm not sure this will really matter in real life. The write case is
really so rare and the contention case even more...

Ben.

^ permalink raw reply

* powerpc virq: minor cleanups
From: Geoff Levand @ 2006-08-25 23:02 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

Ben,

Please consider these cleanups.


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

---
Index: cell--common--4/arch/powerpc/kernel/irq.c
===================================================================
--- cell--common--4.orig/arch/powerpc/kernel/irq.c
+++ cell--common--4/arch/powerpc/kernel/irq.c
@@ -678,7 +680,7 @@
 }
 EXPORT_SYMBOL_GPL(irq_dispose_mapping);
 
-unsigned int irq_find_mapping(struct irq_host *host,
+unsigned int irq_find_mapping(const struct irq_host *host,
 			      irq_hw_number_t hwirq)
 {
 	unsigned int i;
Index: cell--common--4/include/asm-powerpc/irq.h
===================================================================
--- cell--common--4.orig/include/asm-powerpc/irq.h
+++ cell--common--4/include/asm-powerpc/irq.h
@@ -28,10 +28,10 @@
 
 #ifdef CONFIG_PPC_MERGE
 
-/* This number is used when no interrupt has been assigned */
+/* This number is used when no virq has been assigned */
 #define NO_IRQ			(0)
 
-/* This is a special irq number to return from get_irq() to tell that
+/* This is a special virq number to return from get_irq() to tell that
  * no interrupt happened _and_ ignore it (don't count it as bad). Some
  * platforms like iSeries rely on that.
  */
@@ -217,7 +222,7 @@
  * irq controller implementation directly calls the appropriate low level
  * mapping function.
  */
-extern unsigned int irq_find_mapping(struct irq_host *host,
+extern unsigned int irq_find_mapping(const struct irq_host *host,
 				     irq_hw_number_t hwirq);
 
 

^ permalink raw reply

* powerpc virq: new routine virq_to_hw
From: Geoff Levand @ 2006-08-25 23:02 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

Ben,

Please consider this accessor routine which hides the details
of the map.

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

---
Index: cell--common--4/include/asm-powerpc/irq.h
===================================================================
--- cell--common--4.orig/include/asm-powerpc/irq.h
+++ cell--common--4/include/asm-powerpc/irq.h
@@ -136,6 +136,11 @@
 
 extern struct irq_map_entry irq_map[NR_IRQS];
 
+static inline irq_hw_number_t
+virq_to_hw (unsigned int virq)
+{
+	return irq_map[virq].hwirq;
+}
 
 /**
  * irq_alloc_host - Allocate a new irq_host data structure

^ permalink raw reply

* Difference between zImage.treeboot zImage
From: Akhilesh Soni @ 2006-08-26  4:52 UTC (permalink / raw)
  To: linuxppc-embedded

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

Hi,

I'm using opebios on IBM redwood6 ppc405 platform. Currently when I compile my kernel by doing "make zImage" I get one file zImage.treeboot. I just want to know what is the difference between normal zImage and zImage.treeboot.

One more thing I've noticed that there is also a small boot program inside the kernel also (arch/ppc/boot/simple) which decompresses the kernel and jumps to start of zImage. Why this is required ? In normal U-boot which I've worked earlier directly decompresses the zImage by bootm command and starts its execution. Please help me in understanding this mechanism.

Also If I want to build linux kernel 2.6 then will my opebios will work with it or I'll have to change to uboot for for 2.6 kernel.


regards,
Akhilesh


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

^ permalink raw reply

* [PATCH] Keyboard backlight driver for Oct 2005 PowerBooks
From: Michael Hanselmann @ 2006-08-27 12:30 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: johannes, rpurdie, linux-kernel

This driver provides an interface to the keyboard backlight on Oct 2005
PowerBooks, which have the backlight behind the PMU. This driver doesn't
support the I²C variant used in earlier PowerBooks.

Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch>

---
diff -Nrup --exclude-from linux-exclude-from linux-2.6.18-rc4-git1.orig/drivers/macintosh/Kconfig linux-2.6.18-rc4-git1/drivers/macintosh/Kconfig
--- linux-2.6.18-rc4-git1.orig/drivers/macintosh/Kconfig	2006-08-26 22:24:36.000000000 +0200
+++ linux-2.6.18-rc4-git1/drivers/macintosh/Kconfig	2006-08-27 02:39:05.000000000 +0200
@@ -99,6 +99,14 @@ config ADB_PMU_LED_IDE
 	  This option makes the front LED default to the IDE trigger
 	  so that it blinks on IDE activity.
 
+config ADB_PMU_ALS_LED
+	bool "Support for keyboard backlight"
+	depends on ADB_PMU
+	select NEW_LEDS
+	select LEDS_CLASS
+	help
+	  Support for the keyboard backlight on Oct 2005 PowerBooks.
+
 config PMAC_SMU
 	bool "Support for SMU  based PowerMacs"
 	depends on PPC_PMAC64
diff -Nrup --exclude-from linux-exclude-from linux-2.6.18-rc4-git1.orig/drivers/macintosh/Makefile linux-2.6.18-rc4-git1/drivers/macintosh/Makefile
--- linux-2.6.18-rc4-git1.orig/drivers/macintosh/Makefile	2006-08-26 22:24:36.000000000 +0200
+++ linux-2.6.18-rc4-git1/drivers/macintosh/Makefile	2006-08-27 02:39:55.000000000 +0200
@@ -13,6 +13,7 @@ obj-$(CONFIG_ANSLCD)		+= ans-lcd.o
 
 obj-$(CONFIG_ADB_PMU)		+= via-pmu.o via-pmu-event.o
 obj-$(CONFIG_ADB_PMU_LED)	+= via-pmu-led.o
+obj-$(CONFIG_ADB_PMU_ALS_LED)	+= via-pmu-als-led.o
 obj-$(CONFIG_PMAC_BACKLIGHT)	+= via-pmu-backlight.o
 obj-$(CONFIG_ADB_CUDA)		+= via-cuda.o
 obj-$(CONFIG_PMAC_APM_EMU)	+= apm_emu.o
diff -Nrup --exclude-from linux-exclude-from linux-2.6.18-rc4-git1.orig/drivers/macintosh/via-pmu-als-led.c linux-2.6.18-rc4-git1/drivers/macintosh/via-pmu-als-led.c
--- linux-2.6.18-rc4-git1.orig/drivers/macintosh/via-pmu-als-led.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.18-rc4-git1/drivers/macintosh/via-pmu-als-led.c	2006-08-27 04:01:16.000000000 +0200
@@ -0,0 +1,107 @@
+/*
+ * Driver for keyboard backlight on Oct 2005 PowerBooks
+ *
+ * Copyright 2006 Michael Hanselmann <linux-kernel@hansmi.ch>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/leds.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <asm/prom.h>
+
+static spinlock_t ams_led_pmu_lock;
+static struct adb_request pmu_req = {
+	.complete = 1,
+};
+static int sleeping;
+static int pmu_cmd;
+
+static void als_led_pmu_set(struct led_classdev *led_cdev,
+		enum led_brightness brightness)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ams_led_pmu_lock, flags);
+
+	if (pmu_req.complete && !sleeping) {
+		if (brightness < 0)
+			brightness = 0;
+		else if (brightness > 255)
+			brightness = 255;
+
+		pmu_request(&pmu_req, NULL, 4, pmu_cmd, 0, 0, brightness);
+	}
+
+ 	spin_unlock_irqrestore(&ams_led_pmu_lock, flags);
+}
+
+static struct led_classdev als_led = {
+	.name = "als-led-pmu",
+	.brightness_set = als_led_pmu_set,
+};
+
+#ifdef CONFIG_PM
+static int als_led_pmu_sleep_call(struct pmu_sleep_notifier *self, int when)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ams_led_pmu_lock, flags);
+
+	switch (when) {
+	case PBOOK_SLEEP_REQUEST:
+		sleeping = 1;
+		break;
+	case PBOOK_WAKE:
+		sleeping = 0;
+		break;
+	default:
+		/* do nothing */
+		break;
+	}
+
+	spin_unlock_irqrestore(&ams_led_pmu_lock, flags);
+
+	return PBOOK_SLEEP_OK;
+}
+
+static struct pmu_sleep_notifier als_led_pmu_sleep_notif = {
+	.notifier_call = als_led_pmu_sleep_call,
+};
+#endif
+
+static int __init als_led_pmu_init(void)
+{
+	struct device_node *np;
+	u32 *reg;
+
+	np = of_find_node_by_name(NULL, "als-controls");
+	if (!np)
+		return -ENODEV;
+
+	reg = (u32*)get_property(np, "reg", NULL);
+	if (!reg || !*reg)
+		return -ENODEV;
+
+	pmu_cmd = ((*reg) >> 8) & 0xff;
+
+	of_node_put(np);
+
+	spin_lock_init(&ams_led_pmu_lock);
+
+#ifdef CONFIG_PM
+	pmu_register_sleep_notifier(&als_led_pmu_sleep_notif);
+#endif
+
+	return led_classdev_register(NULL, &als_led);
+}
+
+late_initcall(als_led_pmu_init);

^ permalink raw reply

* PCI driver
From: Lee Revell @ 2006-08-27 16:24 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: Leonid

Hello,

We have implemented a driver for a PCI sound card and are attempting to
use it on a PPC400 Yosemite board.  However, as soon as any port I/O is
attempted, we get a machine check error:

dream/mem/mpu 9 0 1 "w" 10
MIDI message chip 9 mpu_port 0 offset 1 direction 1 16bit 0 data 0x10
outb 0x331
Data machine check in kernel mode.
PLB0: BEAR=0x0000000000000000 ACR=  0x00000000 BESR= 0xffffffff
POB0: BEAR=0xc27e3194ffffffff BESR0=0x00000000 BESR1=0x00000000
OPB0: BEAR=0x0000000000000151 BSTAT=0x00000000
Oops: machine check, sig: 7 [#1]
PREEMPT
NIP: 00000000 LR: C02022B0 SP: CFA7FDC0 REGS: c0343f50 TRAP: 0202    Not
tainted
MSR: 00000000 EE: 0 PR: 0 FP: 0 ME: 0 IR/DR: 00
TASK = cffe80d0[43] 'akadiag' THREAD: cfa7e000
Last syscall: 54
GP

Are we doing something wrong?  We use pci_resource_start(pci,0) to get
the BAR which returns 0xFFF0.  This also matches what is
in /proc/ioports, but outb/outw/outl all cause the machine check crash.

Lee

^ permalink raw reply

* [PATCH] EHCI Oops on CONFIG_NOT_COHERENT_CACHE system
From: Marcus Comstedt @ 2006-08-27 16:17 UTC (permalink / raw)
  To: linuxppc-dev

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


Hello.

I'm running 2.6.16.27 on an AmigaOneXE, which is a G4 based board
which has a northbridge (ArticiaS) which does not support cache
coherency.  Because of this, CONFIG_NOT_COHERENT_CACHE is set.

The problem I've been having is that the EHCI USB2 host driver causes
a kernel oops (see attachment) immediately on bootup.

First, let me outline why this oops happens:

1) The EHCI driver uses a structure called "echi_qh", which contains
   both data to be accessed by the USB hardware through DMA, and
   private housekeeping data.
2) Since part of the structure is for DMA, instances of the structre
   are allocated with dma_pool_alloc().
3) Pages allocated with dma_pool_alloc() are cache-inhibited on this
   system, due to the lack of cache coherency support.
4) The private data in this structure included a struct kref, which in
   turn contains an atomic_t.
5) Incrementing and decrementing an atom_t, and thereby a kref, is
   done with lwarx/stwcx.
6) lwarx on a cache-inhibited address is not allowed on G4 (generates
   a DSI).

Now, the problem is deciding in which of these steps the actual error
lies, since none of these facts (apart from #6) is set in stone.  In
my opinion though, it makes sense to simply say that atomic_t:s (and
therefore kref:s) are not supported in DMA memory.  This would place
the error in the EHCI driver, with two possible solutions:

A) Rewrite qh_get() and qh_put() to use something else than
   kref_get()/kref_put().  Simply using non-atomic increment and
   decrement made the Oops go away, but as I don't know the design
   decision behind using a struct kref, I can't say that atomicity
   isn't needed, so such a simple fix might lead to race conditions.

B) Break struct ehci_qh into two parts, one allcated with
   dma_pool_alloc() and one allocated with kmalloc(), where the fields
   accessed by the hardware is put into the former, and the driver
   private data (which includes the kref) in the latter.  Safe and no
   major performance hit (just one level of indirection added in some
   places, and using cache-enabled memory for the internal data might
   actually improve performance), but the change touches a rather
   large amount of lines (patch attached).

C) Basically the same as B, but only the kref (and a pointer back to
   the rest of the data, so that qh_destroy can find it) is moved to
   the kmalloced part.  This means only ehci_qh_alloc(), qh_get() and
   qh_put() need to be changed, so the changeset is much smaller.  I
   don't have a patch ready for this, but I can make one on request.

A completely different approach would be

D) Make the DSI exception handler emulate lwarx on cache-inhibited
   pages.

This seems like a more complex fix though, and I'm sure the
performance would be pretty lousy (although only NOT_COHERENT_CACHE
systems would be affected of course).

So, what do you guys think?  Which is the best way to rectify the
situation?  (Apart from changing to a better northbrige, which I don't
see happening, realistically.  :-/ )


  // Marcus




[-- Attachment #2: End of dmesg output after oops --]
[-- Type: text/plain, Size: 1559 bytes --]

hub 4-0:1.0: port 5, status 0501, change 0001, 480 Mb/s
hub 4-0:1.0: debounce: port 5: total 100ms stable 100ms status 0x501
hub 4-0:1.0: port 5 not reset yet, waiting 50ms
ehci_hcd 0000:00:09.2: port 5 high speed
ehci_hcd 0000:00:09.2: GetStatus port 5 status 001005 POWER sig=se0  PE CONNECT
usb 4-5: new high speed USB device using address 5
Oops: kernel access of bad area, sig: 11 [#1]
NIP: C01490FC LR: E224A96C SP: DFE95D00 REGS: dfe95c50 TRAP: 0300    Not tainted
MSR: 00001032 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DAR: FC1180E0, DSISR: 04000000
TASK = dfe93980[24] 'khubd' THREAD: dfe94000Last syscall: -1 
GPR00: 00000000 DFE95D00 DFE93980 FC1180E0 00000000 00000000 FC1190BC DFE95D78 
GPR08: FC1190F8 FFFFFFFF FC119158 C01490EC 24004042 00000000 0FFD5600 00000001 
GPR16: 00800000 0FFFF220 FFFFFFFF C0320000 C0320000 C0A61A10 D142E888 C0B743E0 
GPR24: DFE95D78 800E0800 40000000 FC119098 FC119120 110A9060 FC118080 FC119060 
NIP [c01490fc] kref_get+0x10/0x24
LR [e224a96c] qh_append_tds+0x16c/0x2f0 [ehci_hcd]
Call trace:
 [e224ab64] submit_async+0x74/0xe0 [ehci_hcd]
 [e224e9d4] ehci_urb_enqueue+0x6c/0xe4 [ehci_hcd]
 [c01ec9f4] hcd_submit_urb+0x1a0/0x268
 [c01ed650] usb_submit_urb+0x24c/0x330
 [c01ed9fc] usb_start_wait_urb+0x5c/0x10c
 [c01edb20] usb_internal_control_msg+0x74/0x9c
 [c01edbe4] usb_control_msg+0x9c/0xc0
 [c01e9d34] hub_set_address+0x5c/0x94
 [c01e9f48] hub_port_init+0x1dc/0x3dc
 [c01ea4fc] hub_port_connect_change+0x1c0/0x4b4
 [c01eac10] hub_events+0x420/0x51c
 [c01ead4c] hub_thread+0x40/0xec
 [c000aec4] kernel_thread+0x44/0x60

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: Patch to split struct ehci_qh into two parts --]
[-- Type: text/x-patch, Size: 17755 bytes --]

diff -rup -x'*.o' -x'*.ko' -x'*.cmd' -x'*~' drivers/usb/host.orig/ehci-dbg.c drivers/usb/host/ehci-dbg.c
--- drivers/usb/host.orig/ehci-dbg.c	2006-07-17 15:58:58.000000000 +0200
+++ drivers/usb/host/ehci-dbg.c	2006-08-20 21:00:09.000000000 +0200
@@ -135,9 +135,9 @@ static void __attribute__((__unused__))
 dbg_qh (const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
 	ehci_dbg (ehci, "%s qh %p n%08x info %x %x qtd %x\n", label,
-		qh, qh->hw_next, qh->hw_info1, qh->hw_info2,
-		qh->hw_current);
-	dbg_qtd ("overlay", ehci, (struct ehci_qtd *) &qh->hw_qtd_next);
+		qh, qh->qh_hw->hw_next, qh->qh_hw->hw_info1, qh->qh_hw->hw_info2,
+		qh->qh_hw->hw_current);
+	dbg_qtd ("overlay", ehci, (struct ehci_qtd *) &qh->qh_hw->hw_qtd_next);
 }
 
 static void __attribute__((__unused__))
@@ -361,29 +361,29 @@ static void qh_lines (
 	char			*next = *nextp;
 	char			mark;
 
-	if (qh->hw_qtd_next == EHCI_LIST_END)	/* NEC does this */
+	if (qh->qh_hw->hw_qtd_next == EHCI_LIST_END)	/* NEC does this */
 		mark = '@';
 	else
-		mark = token_mark (qh->hw_token);
+		mark = token_mark (qh->qh_hw->hw_token);
 	if (mark == '/') {	/* qh_alt_next controls qh advance? */
-		if ((qh->hw_alt_next & QTD_MASK) == ehci->async->hw_alt_next)
+		if ((qh->qh_hw->hw_alt_next & QTD_MASK) == ehci->async->qh_hw->hw_alt_next)
 			mark = '#';	/* blocked */
-		else if (qh->hw_alt_next == EHCI_LIST_END)
+		else if (qh->qh_hw->hw_alt_next == EHCI_LIST_END)
 			mark = '.';	/* use hw_qtd_next */
 		/* else alt_next points to some other qtd */
 	}
-	scratch = le32_to_cpup (&qh->hw_info1);
-	hw_curr = (mark == '*') ? le32_to_cpup (&qh->hw_current) : 0;
+	scratch = le32_to_cpup (&qh->qh_hw->hw_info1);
+	hw_curr = (mark == '*') ? le32_to_cpup (&qh->qh_hw->hw_current) : 0;
 	temp = scnprintf (next, size,
 			"qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)",
 			qh, scratch & 0x007f,
 			speed_char (scratch),
 			(scratch >> 8) & 0x000f,
-			scratch, le32_to_cpup (&qh->hw_info2),
-			le32_to_cpup (&qh->hw_token), mark,
-			(__constant_cpu_to_le32 (QTD_TOGGLE) & qh->hw_token)
+			  scratch, le32_to_cpup (&qh->qh_hw->hw_info2),
+			le32_to_cpup (&qh->qh_hw->hw_token), mark,
+			(__constant_cpu_to_le32 (QTD_TOGGLE) & qh->qh_hw->hw_token)
 				? "data1" : "data0",
-			(le32_to_cpup (&qh->hw_alt_next) >> 1) & 0x0f);
+			(le32_to_cpup (&qh->qh_hw->hw_alt_next) >> 1) & 0x0f);
 	size -= temp;
 	next += temp;
 
@@ -394,10 +394,10 @@ static void qh_lines (
 		mark = ' ';
 		if (hw_curr == td->qtd_dma)
 			mark = '*';
-		else if (qh->hw_qtd_next == cpu_to_le32(td->qtd_dma))
+		else if (qh->qh_hw->hw_qtd_next == cpu_to_le32(td->qtd_dma))
 			mark = '+';
 		else if (QTD_LENGTH (scratch)) {
-			if (td->hw_alt_next == ehci->async->hw_alt_next)
+			if (td->hw_alt_next == ehci->async->qh_hw->hw_alt_next)
 				mark = '#';
 			else if (td->hw_alt_next != EHCI_LIST_END)
 				mark = '/';
@@ -525,7 +525,7 @@ show_periodic (struct class_device *clas
 			case Q_TYPE_QH:
 				temp = scnprintf (next, size, " qh%d-%04x/%p",
 						p.qh->period,
-						le32_to_cpup (&p.qh->hw_info2)
+						le32_to_cpup (&p.qh->qh_hw->hw_info2)
 							/* uframe masks */
 							& (QH_CMASK | QH_SMASK),
 						p.qh);
@@ -544,7 +544,7 @@ show_periodic (struct class_device *clas
 				/* show more info the first time around */
 				if (temp == seen_count && p.ptr) {
 					u32	scratch = le32_to_cpup (
-							&p.qh->hw_info1);
+							&p.qh->qh_hw->hw_info1);
 					struct ehci_qtd	*qtd;
 					char		*type = "";
 
@@ -576,7 +576,7 @@ show_periodic (struct class_device *clas
 				} else
 					temp = 0;
 				if (p.qh) {
-					tag = Q_NEXT_TYPE (p.qh->hw_next);
+					tag = Q_NEXT_TYPE (p.qh->qh_hw->hw_next);
 					p = p.qh->qh_next;
 				}
 				break;
diff -rup -x'*.o' -x'*.ko' -x'*.cmd' -x'*~' drivers/usb/host.orig/ehci-hcd.c drivers/usb/host/ehci-hcd.c
--- drivers/usb/host.orig/ehci-hcd.c	2006-07-17 15:58:58.000000000 +0200
+++ drivers/usb/host/ehci-hcd.c	2006-08-20 15:51:33.000000000 +0200
@@ -445,12 +445,12 @@ static int ehci_init(struct usb_hcd *hcd
 	 * from automatically advancing to the next td after short reads.
 	 */
 	ehci->async->qh_next.qh = NULL;
-	ehci->async->hw_next = QH_NEXT(ehci->async->qh_dma);
-	ehci->async->hw_info1 = cpu_to_le32(QH_HEAD);
-	ehci->async->hw_token = cpu_to_le32(QTD_STS_HALT);
-	ehci->async->hw_qtd_next = EHCI_LIST_END;
+	ehci->async->qh_hw->hw_next = QH_NEXT(ehci->async->qh_dma);
+	ehci->async->qh_hw->hw_info1 = cpu_to_le32(QH_HEAD);
+	ehci->async->qh_hw->hw_token = cpu_to_le32(QTD_STS_HALT);
+	ehci->async->qh_hw->hw_qtd_next = EHCI_LIST_END;
 	ehci->async->qh_state = QH_STATE_LINKED;
-	ehci->async->hw_alt_next = QTD_NEXT(ehci->async->dummy->qtd_dma);
+	ehci->async->qh_hw->hw_alt_next = QTD_NEXT(ehci->async->dummy->qtd_dma);
 
 	/* clear interrupt enables, set irq latency */
 	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
@@ -828,7 +828,7 @@ rescan:
 	/* endpoints can be iso streams.  for now, we don't
 	 * accelerate iso completions ... so spin a while.
 	 */
-	if (qh->hw_info1 == 0) {
+	if (qh->qh_hw->hw_info1 == 0) {
 		ehci_vdbg (ehci, "iso delay\n");
 		goto idle_timeout;
 	}
diff -rup -x'*.o' -x'*.ko' -x'*.cmd' -x'*~' drivers/usb/host.orig/ehci-mem.c drivers/usb/host/ehci-mem.c
--- drivers/usb/host.orig/ehci-mem.c	2006-07-17 15:58:58.000000000 +0200
+++ drivers/usb/host/ehci-mem.c	2006-08-20 15:54:05.000000000 +0200
@@ -76,23 +76,31 @@ static void qh_destroy (struct kref *kre
 	if (qh->dummy)
 		ehci_qtd_free (ehci, qh->dummy);
 	usb_put_dev (qh->dev);
-	dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
+	dma_pool_free (ehci->qh_pool, qh->qh_hw, qh->qh_dma);
+	kfree (qh);
 }
 
 static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags)
 {
 	struct ehci_qh		*qh;
+	struct ehci_qh_hw	*qh_hw;
 	dma_addr_t		dma;
 
-	qh = (struct ehci_qh *)
+	qh_hw = (struct ehci_qh_hw *)
 		dma_pool_alloc (ehci->qh_pool, flags, &dma);
-	if (!qh)
+	if (!qh_hw)
+		return NULL;
+	qh = (struct ehci_qh *)
+		kmalloc (sizeof (struct ehci_qh), GFP_KERNEL);
+	if (!qh) {
+		dma_pool_free (ehci->qh_pool, qh_hw, dma);
 		return qh;
-
+	}
 	memset (qh, 0, sizeof *qh);
 	kref_init(&qh->kref);
 	qh->ehci = ehci;
 	qh->qh_dma = dma;
+	qh->qh_hw = qh_hw;
 	// INIT_LIST_HEAD (&qh->qh_list);
 	INIT_LIST_HEAD (&qh->qtd_list);
 
@@ -100,7 +108,8 @@ static struct ehci_qh *ehci_qh_alloc (st
 	qh->dummy = ehci_qtd_alloc (ehci, flags);
 	if (qh->dummy == NULL) {
 		ehci_dbg (ehci, "no dummy td\n");
-		dma_pool_free (ehci->qh_pool, qh, qh->qh_dma);
+		dma_pool_free (ehci->qh_pool, qh_hw, dma);
+		kfree (qh);
 		qh = NULL;
 	}
 	return qh;
@@ -178,7 +187,7 @@ static int ehci_mem_init (struct ehci_hc
 	/* QHs for control/bulk/intr transfers */
 	ehci->qh_pool = dma_pool_create ("ehci_qh", 
 			ehci_to_hcd(ehci)->self.controller,
-			sizeof (struct ehci_qh),
+			sizeof (struct ehci_qh_hw),
 			32 /* byte alignment (for hw parts) */,
 			4096 /* can't cross 4K */);
 	if (!ehci->qh_pool) {
diff -rup -x'*.o' -x'*.ko' -x'*.cmd' -x'*~' drivers/usb/host.orig/ehci-q.c drivers/usb/host/ehci-q.c
--- drivers/usb/host.orig/ehci-q.c	2006-07-17 15:58:58.000000000 +0200
+++ drivers/usb/host/ehci-q.c	2006-08-20 21:26:54.000000000 +0200
@@ -89,28 +89,28 @@ qh_update (struct ehci_hcd *ehci, struct
 	/* writes to an active overlay are unsafe */
 	BUG_ON(qh->qh_state != QH_STATE_IDLE);
 
-	qh->hw_qtd_next = QTD_NEXT (qtd->qtd_dma);
-	qh->hw_alt_next = EHCI_LIST_END;
+	qh->qh_hw->hw_qtd_next = QTD_NEXT (qtd->qtd_dma);
+	qh->qh_hw->hw_alt_next = EHCI_LIST_END;
 
 	/* Except for control endpoints, we make hardware maintain data
 	 * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
 	 * and set the pseudo-toggle in udev. Only usb_clear_halt() will
 	 * ever clear it.
 	 */
-	if (!(qh->hw_info1 & cpu_to_le32(1 << 14))) {
+	if (!(qh->qh_hw->hw_info1 & cpu_to_le32(1 << 14))) {
 		unsigned	is_out, epnum;
 
 		is_out = !(qtd->hw_token & cpu_to_le32(1 << 8));
-		epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f;
+		epnum = (le32_to_cpup(&qh->qh_hw->hw_info1) >> 8) & 0x0f;
 		if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
-			qh->hw_token &= ~__constant_cpu_to_le32 (QTD_TOGGLE);
+			qh->qh_hw->hw_token &= ~__constant_cpu_to_le32 (QTD_TOGGLE);
 			usb_settoggle (qh->dev, epnum, is_out, 1);
 		}
 	}
 
 	/* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
 	wmb ();
-	qh->hw_token &= __constant_cpu_to_le32 (QTD_TOGGLE | QTD_STS_PING);
+	qh->qh_hw->hw_token &= __constant_cpu_to_le32 (QTD_TOGGLE | QTD_STS_PING);
 }
 
 /* if it weren't for a common silicon quirk (writing the dummy into the qh
@@ -128,7 +128,7 @@ qh_refresh (struct ehci_hcd *ehci, struc
 		qtd = list_entry (qh->qtd_list.next,
 				struct ehci_qtd, qtd_list);
 		/* first qtd may already be partially processed */
-		if (cpu_to_le32 (qtd->qtd_dma) == qh->hw_current)
+		if (cpu_to_le32 (qtd->qtd_dma) == qh->qh_hw->hw_current)
 			qtd = NULL;
 	}
 
@@ -222,7 +222,7 @@ __acquires(ehci->lock)
 		struct ehci_qh	*qh = (struct ehci_qh *) urb->hcpriv;
 
 		/* S-mask in a QH means it's an interrupt urb */
-		if ((qh->hw_info2 & __constant_cpu_to_le32 (QH_SMASK)) != 0) {
+		if ((qh->qh_hw->hw_info2 & __constant_cpu_to_le32 (QH_SMASK)) != 0) {
 
 			/* ... update hc-wide periodic stats (for usbfs) */
 			ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
@@ -375,16 +375,16 @@ qh_completions (struct ehci_hcd *ehci, s
 			/* token in overlay may be most current */
 			if (state == QH_STATE_IDLE
 					&& cpu_to_le32 (qtd->qtd_dma)
-						== qh->hw_current)
-				token = le32_to_cpu (qh->hw_token);
+						== qh->qh_hw->hw_current)
+				token = le32_to_cpu (qh->qh_hw->hw_token);
 
 			/* force halt for unlinked or blocked qh, so we'll
 			 * patch the qh later and so that completions can't
 			 * activate it while we "know" it's stopped.
 			 */
-			if ((HALT_BIT & qh->hw_token) == 0) {
+			if ((HALT_BIT & qh->qh_hw->hw_token) == 0) {
 halt:
-				qh->hw_token |= HALT_BIT;
+				qh->qh_hw->hw_token |= HALT_BIT;
 				wmb ();
 			}
 		}
@@ -419,7 +419,7 @@ halt:
 	 * it after fault cleanup, or recovering from silicon wrongly
 	 * overlaying the dummy qtd (which reduces DMA chatter).
 	 */
-	if (stopped != 0 || qh->hw_qtd_next == EHCI_LIST_END) {
+	if (stopped != 0 || qh->qh_hw->hw_qtd_next == EHCI_LIST_END) {
 		switch (state) {
 		case QH_STATE_IDLE:
 			qh_refresh(ehci, qh);
@@ -429,7 +429,7 @@ halt:
 			 * except maybe high bandwidth ...
 			 */
 			if ((__constant_cpu_to_le32 (QH_SMASK)
-					& qh->hw_info2) != 0) {
+					& qh->qh_hw->hw_info2) != 0) {
 				intr_deschedule (ehci, qh);
 				(void) qh_schedule (ehci, qh);
 			} else
@@ -543,7 +543,7 @@ qh_urb_transaction (
 		len -= this_qtd_len;
 		buf += this_qtd_len;
 		if (is_input)
-			qtd->hw_alt_next = ehci->async->hw_alt_next;
+			qtd->hw_alt_next = ehci->async->qh_hw->hw_alt_next;
 
 		/* qh makes control packets use qtd toggle; maybe switch it */
 		if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0)
@@ -762,8 +762,8 @@ done:
 
 	/* init as live, toggle clear, advance to dummy */
 	qh->qh_state = QH_STATE_IDLE;
-	qh->hw_info1 = cpu_to_le32 (info1);
-	qh->hw_info2 = cpu_to_le32 (info2);
+	qh->qh_hw->hw_info1 = cpu_to_le32 (info1);
+	qh->qh_hw->hw_info2 = cpu_to_le32 (info2);
 	usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
 	qh_refresh (ehci, qh);
 	return qh;
@@ -800,11 +800,11 @@ static void qh_link_async (struct ehci_h
 
 	/* splice right after start */
 	qh->qh_next = head->qh_next;
-	qh->hw_next = head->hw_next;
+	qh->qh_hw->hw_next = head->qh_hw->hw_next;
 	wmb ();
 
 	head->qh_next.qh = qh;
-	head->hw_next = dma;
+	head->qh_hw->hw_next = dma;
 
 	qh->qh_state = QH_STATE_LINKED;
 	/* qtd completions reported later by interrupt */
@@ -850,7 +850,7 @@ static struct ehci_qh *qh_append_tds (
 
                         /* usb_reset_device() briefly reverts to address 0 */
                         if (usb_pipedevice (urb->pipe) == 0)
-                                qh->hw_info1 &= ~QH_ADDR_MASK;
+                                qh->qh_hw->hw_info1 &= ~QH_ADDR_MASK;
 		}
 
 		/* just one way to queue requests: swap with the dummy qtd.
@@ -1031,7 +1031,7 @@ static void start_unlink_async (struct e
 	while (prev->qh_next.qh != qh)
 		prev = prev->qh_next.qh;
 
-	prev->hw_next = qh->hw_next;
+	prev->qh_hw->hw_next = qh->qh_hw->hw_next;
 	prev->qh_next = qh->qh_next;
 	wmb ();
 
diff -rup -x'*.o' -x'*.ko' -x'*.cmd' -x'*~' drivers/usb/host.orig/ehci-sched.c drivers/usb/host/ehci-sched.c
--- drivers/usb/host.orig/ehci-sched.c	2006-07-17 15:58:58.000000000 +0200
+++ drivers/usb/host/ehci-sched.c	2006-08-20 21:55:02.000000000 +0200
@@ -95,12 +95,12 @@ periodic_usecs (struct ehci_hcd *ehci, u
 		switch (Q_NEXT_TYPE (*hw_p)) {
 		case Q_TYPE_QH:
 			/* is it in the S-mask? */
-			if (q->qh->hw_info2 & cpu_to_le32 (1 << uframe))
+			if (q->qh->qh_hw->hw_info2 & cpu_to_le32 (1 << uframe))
 				usecs += q->qh->usecs;
 			/* ... or C-mask? */
-			if (q->qh->hw_info2 & cpu_to_le32 (1 << (8 + uframe)))
+			if (q->qh->qh_hw->hw_info2 & cpu_to_le32 (1 << (8 + uframe)))
 				usecs += q->qh->c_usecs;
-			hw_p = &q->qh->hw_next;
+			hw_p = &q->qh->qh_hw->hw_next;
 			q = &q->qh->qh_next;
 			break;
 		// case Q_TYPE_FSTN:
@@ -198,13 +198,13 @@ static int tt_no_collision (
 				if (same_tt (dev, here.qh->dev)) {
 					u32		mask;
 
-					mask = le32_to_cpu (here.qh->hw_info2);
+					mask = le32_to_cpu (here.qh->qh_hw->hw_info2);
 					/* "knows" no gap is needed */
 					mask |= mask >> 8;
 					if (mask & uf_mask)
 						break;
 				}
-				type = Q_NEXT_TYPE (here.qh->hw_next);
+				type = Q_NEXT_TYPE (here.qh->qh_hw->hw_next);
 				here = here.qh->qh_next;
 				continue;
 			case Q_TYPE_SITD:
@@ -301,7 +301,7 @@ static int qh_link_periodic (struct ehci
 
 	dev_dbg (&qh->dev->dev,
 		"link qh%d-%04x/%p start %d [%d/%d us]\n",
-		period, le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK),
+		period, le32_to_cpup (&qh->qh_hw->hw_info2) & (QH_CMASK | QH_SMASK),
 		qh, qh->start, qh->usecs, qh->c_usecs);
 
 	/* high bandwidth, or otherwise every microframe */
@@ -320,7 +320,7 @@ static int qh_link_periodic (struct ehci
 			if (type == Q_TYPE_QH)
 				break;
 			prev = periodic_next_shadow (prev, type);
-			hw_p = &here.qh->hw_next;
+			hw_p = &here.qh->qh_hw->hw_next;
 			here = *prev;
 		}
 
@@ -331,14 +331,14 @@ static int qh_link_periodic (struct ehci
 			if (qh->period > here.qh->period)
 				break;
 			prev = &here.qh->qh_next;
-			hw_p = &here.qh->hw_next;
+			hw_p = &here.qh->qh_hw->hw_next;
 			here = *prev;
 		}
 		/* link in this qh, unless some earlier pass did that */
 		if (qh != here.qh) {
 			qh->qh_next = here;
 			if (here.qh)
-				qh->hw_next = *hw_p;
+				qh->qh_hw->hw_next = *hw_p;
 			wmb ();
 			prev->qh = qh;
 			*hw_p = QH_NEXT (qh->qh_dma);
@@ -386,7 +386,7 @@ static void qh_unlink_periodic (struct e
 	dev_dbg (&qh->dev->dev,
 		"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
 		qh->period,
-		le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK),
+		le32_to_cpup (&qh->qh_hw->hw_info2) & (QH_CMASK | QH_SMASK),
 		qh, qh->start, qh->usecs, qh->c_usecs);
 
 	/* qh->qh_next still "live" to HC */
@@ -413,14 +413,14 @@ static void intr_deschedule (struct ehci
 	 */
 	if (list_empty (&qh->qtd_list)
 			|| (__constant_cpu_to_le32 (QH_CMASK)
-					& qh->hw_info2) != 0)
+					& qh->qh_hw->hw_info2) != 0)
 		wait = 2;
 	else
 		wait = 55;	/* worst case: 3 * 1024 */
 
 	udelay (wait);
 	qh->qh_state = QH_STATE_IDLE;
-	qh->hw_next = EHCI_LIST_END;
+	qh->qh_hw->hw_next = EHCI_LIST_END;
 	wmb ();
 }
 
@@ -529,12 +529,12 @@ static int qh_schedule (struct ehci_hcd 
 	unsigned	frame;		/* 0..(qh->period - 1), or NO_FRAME */
 
 	qh_refresh(ehci, qh);
-	qh->hw_next = EHCI_LIST_END;
+	qh->qh_hw->hw_next = EHCI_LIST_END;
 	frame = qh->start;
 
 	/* reuse the previous schedule slots, if we can */
 	if (frame < qh->period) {
-		uframe = ffs (le32_to_cpup (&qh->hw_info2) & QH_SMASK);
+		uframe = ffs (le32_to_cpup (&qh->qh_hw->hw_info2) & QH_SMASK);
 		status = check_intr_schedule (ehci, frame, --uframe,
 				qh, &c_mask);
 	} else {
@@ -570,11 +570,11 @@ static int qh_schedule (struct ehci_hcd 
 		qh->start = frame;
 
 		/* reset S-frame and (maybe) C-frame masks */
-		qh->hw_info2 &= __constant_cpu_to_le32(~(QH_CMASK | QH_SMASK));
-		qh->hw_info2 |= qh->period
+		qh->qh_hw->hw_info2 &= __constant_cpu_to_le32(~(QH_CMASK | QH_SMASK));
+		qh->qh_hw->hw_info2 |= qh->period
 			? cpu_to_le32 (1 << uframe)
 			: __constant_cpu_to_le32 (QH_SMASK);
-		qh->hw_info2 |= c_mask;
+		qh->qh_hw->hw_info2 |= c_mask;
 	} else
 		ehci_dbg (ehci, "reused qh %p schedule\n", qh);
 
@@ -1918,7 +1918,7 @@ restart:
 			case Q_TYPE_QH:
 				/* handle any completions */
 				temp.qh = qh_get (q.qh);
-				type = Q_NEXT_TYPE (q.qh->hw_next);
+				type = Q_NEXT_TYPE (q.qh->qh_hw->hw_next);
 				q = q.qh->qh_next;
 				modified = qh_completions (ehci, temp.qh, regs);
 				if (unlikely (list_empty (&temp.qh->qtd_list)))
diff -rup -x'*.o' -x'*.ko' -x'*.cmd' -x'*~' drivers/usb/host.orig/ehci.h drivers/usb/host/ehci.h
--- drivers/usb/host.orig/ehci.h	2006-07-17 15:58:58.000000000 +0200
+++ drivers/usb/host/ehci.h	2006-08-20 15:46:12.000000000 +0200
@@ -381,7 +381,7 @@ union ehci_shadow {
  * These appear in both the async and (for interrupt) periodic schedules.
  */
 
-struct ehci_qh {
+struct ehci_qh_hw {
 	/* first part defined by EHCI spec */
 	__le32			hw_next;	 /* see EHCI 3.6.1 */
 	__le32			hw_info1;        /* see EHCI 3.6.2 */
@@ -402,6 +402,10 @@ struct ehci_qh {
 	__le32			hw_buf_hi [5];
 
 	/* the rest is HCD-private */
+};
+
+struct ehci_qh {
+	struct ehci_qh_hw	*qh_hw;
 	dma_addr_t		qh_dma;		/* address of qh */
 	union ehci_shadow	qh_next;	/* ptr to qh; or periodic */
 	struct list_head	qtd_list;	/* sw qtd list */

^ permalink raw reply

* Re: [PATCH] Keyboard backlight driver for Oct 2005 PowerBooks
From: Benjamin Herrenschmidt @ 2006-08-27 22:34 UTC (permalink / raw)
  To: Michael Hanselmann; +Cc: linuxppc-dev, johannes, rpurdie, linux-kernel
In-Reply-To: <20060827123015.GA4697@hansmi.ch>

On Sun, 2006-08-27 at 14:30 +0200, Michael Hanselmann wrote:
> This driver provides an interface to the keyboard backlight on Oct 2005
> PowerBooks, which have the backlight behind the PMU. This driver doesn't
> support the I²C variant used in earlier PowerBooks.
> 
> Signed-off-by: Michael Hanselmann <linux-kernel@hansmi.ch>

Why would we need a driver ? Userland can emit PMU commands directly...
At least, if we do a driver, it should provide a common interface to
both PMU and i2c based LMUs

Ben.

^ permalink raw reply

* Re: [PATCH] Keyboard backlight driver for Oct 2005 PowerBooks
From: Michael Hanselmann @ 2006-08-27 23:07 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, johannes, rpurdie, linux-kernel
In-Reply-To: <1156718063.8433.358.camel@localhost.localdomain>

On Mon, Aug 28, 2006 at 08:34:23AM +1000, Benjamin Herrenschmidt wrote:
> Why would we need a driver ? Userland can emit PMU commands directly...

Drivers are there to abstract hardware. Userland shouldn't know about
hardware specific commands (PMU commands in this case).

It would make it much simpler for programs to use these devices, because
not each of them has to implement everything needed to locate the device
and control it.

pbbuttonsd supports both the I²C and PMU variant. The code is a mess
there and a generic driver would help to clean it up. And yes, I'm
partly responsible for it, since I supplied the original patch for the
PMU keyboard backlight support in pbbuttonsd.

Maybe controlling the keyboard backlight could be moved to its own
program anyway, because the algorithm used by pbbuttonsd isn't appealing
to all people. But those are just ideas.

Oh, and using the LED class allows users to attach it to some trigger.
Maybe someone wants to use it as the IDE LED. :-)

> At least, if we do a driver, it should provide a common interface to
> both PMU and i2c based LMUs

Yeah, I figured after sending it. You'll hear again from me once I got
my hands on an I²C backlight. Something like the AMS driver would be
nice.

^ permalink raw reply

* Re: [PATCH] Keyboard backlight driver for Oct 2005 PowerBooks
From: Benjamin Herrenschmidt @ 2006-08-27 23:11 UTC (permalink / raw)
  To: Michael Hanselmann; +Cc: linuxppc-dev, johannes, rpurdie, linux-kernel
In-Reply-To: <20060827230714.GA12569@hansmi.ch>

On Mon, 2006-08-28 at 01:07 +0200, Michael Hanselmann wrote:
> On Mon, Aug 28, 2006 at 08:34:23AM +1000, Benjamin Herrenschmidt wrote:
> > Why would we need a driver ? Userland can emit PMU commands directly...
> 
> Drivers are there to abstract hardware. Userland shouldn't know about
> hardware specific commands (PMU commands in this case).

This is a bit of a broad statement :) If I were to follow you, thinks
like USB scanner or printer drivers should all be in the kernel :)
Well... they happen not to be.

Only drivers providing services to the kernel itself (block,
network, ...) or doing things like direct DMA, interrupts, etc... that
aren't useable from an exposed userland interfaces need to be in the
kernel.

> It would make it much simpler for programs to use these devices, because
> not each of them has to implement everything needed to locate the device
> and control it.

Then the best is to do a library.

> pbbuttonsd supports both the I²C and PMU variant. The code is a mess
> there and a generic driver would help to clean it up. And yes, I'm
> partly responsible for it, since I supplied the original patch for the
> PMU keyboard backlight support in pbbuttonsd.
> 
> Maybe controlling the keyboard backlight could be moved to its own
> program anyway, because the algorithm used by pbbuttonsd isn't appealing
> to all people. But those are just ideas.

Yeah, separate program or library would do the trick just fine. Also,
your driver doesn't handle reading the light sensors, does it ?

> Oh, and using the LED class allows users to attach it to some trigger.
> Maybe someone wants to use it as the IDE LED. :-)

That would be just insane :)

> > At least, if we do a driver, it should provide a common interface to
> > both PMU and i2c based LMUs
> 
> Yeah, I figured after sending it. You'll hear again from me once I got
> my hands on an I²C backlight. Something like the AMS driver would be
> nice.

I still think this has little to do in the kernel ...

Ben.

^ permalink raw reply

* Re: [PATCH] Keyboard backlight driver for Oct 2005 PowerBooks
From: Michael Hanselmann @ 2006-08-27 23:24 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, johannes, rpurdie, linux-kernel
In-Reply-To: <1156720264.8433.362.camel@localhost.localdomain>

On Mon, Aug 28, 2006 at 09:11:03AM +1000, Benjamin Herrenschmidt wrote:
> > Drivers are there to abstract hardware. Userland shouldn't know about
> > hardware specific commands (PMU commands in this case).

> This is a bit of a broad statement :) If I were to follow you, thinks
> like USB scanner or printer drivers should all be in the kernel :)
> Well... they happen not to be.

True. But then again, a printer driver does little more than configuring
a single PWM value.

If there wasn't an I²C variant, we could even export these things as PMU
sub-devices. But there is one and a driver could easily hide these
differences from userland, because they simply don't matter there.

> Then the best is to do a library.

There was some effort ongoing on that a few months ago (at least on
IRC). Was there anything coming out of it?

> Yeah, separate program or library would do the trick just fine. Also,
> your driver doesn't handle reading the light sensors, does it ?

No, it doesn't. The light sensor is a different device and doesn't
belong into a LED driver. I plan to do a driver for it separately.

So the target is to have one driver for backlight and one for sensors,
each handling the I²C and PMU variants. MacBooks have some other
variant, which could be included, theoretically. Lacking the hardware, I
can't do that, tough.

The main reason I did not do all at once is that I feared a discussion
like we have it now. I'm not going to invest much time for unused code
anymore like I did with the ctrl+click patch.

Greets,
Michael

^ permalink raw reply

* [PATCH] powerpc: Improve IRQ radix tree locking (#2)
From: Benjamin Herrenschmidt @ 2006-08-28  1:17 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev list

When reworking the powerpc irq code, I figured out that we were using
the radix tree in a racy way. As a temporary fix, I put a spinlock in
there. However, this can have a significant impact on performances. This
patch reworks that to use a smarter technique based on the fact that
what we need is in fact a rwlock with extremely rare writers (thus
optimized for the read path).

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

This version includes changes based on Milton's comments. I also removed
the first test of irq_radix_writer in irq_radix_rdlock(). The result
should still be correct, though penalizing the contention path a bit
more while slightly improving the fast path, which is my goal.

Index: linux-work/arch/powerpc/kernel/irq.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/irq.c	2006-08-25 14:08:41.000000000 +1000
+++ linux-work/arch/powerpc/kernel/irq.c	2006-08-28 11:13:02.000000000 +1000
@@ -322,7 +322,8 @@ EXPORT_SYMBOL(do_softirq);
 
 static LIST_HEAD(irq_hosts);
 static spinlock_t irq_big_lock = SPIN_LOCK_UNLOCKED;
-
+static DEFINE_PER_CPU(unsigned int, irq_radix_reader);
+static unsigned int irq_radix_writer;
 struct irq_map_entry irq_map[NR_IRQS];
 static unsigned int irq_virq_count = NR_IRQS;
 static struct irq_host *irq_default_host;
@@ -455,6 +456,58 @@ void irq_set_virq_count(unsigned int cou
 		irq_virq_count = count;
 }
 
+/* radix tree not lockless safe ! we use a brlock-type mecanism
+ * for now, until we can use a lockless radix tree
+ */
+static void irq_radix_wrlock(unsigned long *flags)
+{
+	unsigned int cpu, ok;
+
+	spin_lock_irqsave(&irq_big_lock, *flags);
+	irq_radix_writer = 1;
+	smp_mb();
+	do {
+		barrier();
+		ok = 1;
+		for_each_possible_cpu(cpu) {
+			if (per_cpu(irq_radix_reader, cpu)) {
+				ok = 0;
+				break;
+			}
+		}
+		if (!ok)
+			cpu_relax();
+	} while(!ok);
+}
+
+static void irq_radix_wrunlock(unsigned long flags)
+{
+	smp_wmb();
+	irq_radix_writer = 0;
+	spin_unlock_irqrestore(&irq_big_lock, flags);
+}
+
+static void irq_radix_rdlock(unsigned long *flags)
+{
+	local_irq_save(*flags);
+	__get_cpu_var(irq_radix_reader) = 1;
+	smp_mb();
+	if (likely(irq_radix_writer == 0))
+		return;
+	__get_cpu_var(irq_radix_reader) = 0;
+	smp_wmb();
+	spin_lock(&irq_big_lock);
+	__get_cpu_var(irq_radix_reader) = 1;
+	spin_unlock(&irq_big_lock);
+}
+
+static void irq_radix_rdunlock(unsigned long flags)
+{
+	__get_cpu_var(irq_radix_reader) = 0;
+	local_irq_restore(flags);
+}
+
+
 unsigned int irq_create_mapping(struct irq_host *host,
 				irq_hw_number_t hwirq)
 {
@@ -604,13 +657,9 @@ void irq_dispose_mapping(unsigned int vi
 		/* Check if radix tree allocated yet */
 		if (host->revmap_data.tree.gfp_mask == 0)
 			break;
-		/* XXX radix tree not safe ! remove lock whem it becomes safe
-		 * and use some RCU sync to make sure everything is ok before we
-		 * can re-use that map entry
-		 */
-		spin_lock_irqsave(&irq_big_lock, flags);
+		irq_radix_wrlock(&flags);
 		radix_tree_delete(&host->revmap_data.tree, hwirq);
-		spin_unlock_irqrestore(&irq_big_lock, flags);
+		irq_radix_wrunlock(flags);
 		break;
 	}
 
@@ -677,25 +726,24 @@ unsigned int irq_radix_revmap(struct irq
 	if (tree->gfp_mask == 0)
 		return irq_find_mapping(host, hwirq);
 
-	/* XXX Current radix trees are NOT SMP safe !!! Remove that lock
-	 * when that is fixed (when Nick's patch gets in
-	 */
-	spin_lock_irqsave(&irq_big_lock, flags);
-
 	/* Now try to resolve */
+	irq_radix_rdlock(&flags);
 	ptr = radix_tree_lookup(tree, hwirq);
+	irq_radix_rdunlock(flags);
+
 	/* Found it, return */
 	if (ptr) {
 		virq = ptr - irq_map;
-		goto bail;
+		return virq;
 	}
 
 	/* If not there, try to insert it */
 	virq = irq_find_mapping(host, hwirq);
-	if (virq != NO_IRQ)
+	if (virq != NO_IRQ) {
+		irq_radix_wrlock(&flags);
 		radix_tree_insert(tree, hwirq, &irq_map[virq]);
- bail:
-	spin_unlock_irqrestore(&irq_big_lock, flags);
+		irq_radix_wrunlock(flags);
+	}
 	return virq;
 }
 
@@ -806,12 +854,12 @@ static int irq_late_init(void)
 	struct irq_host *h;
 	unsigned long flags;
 
-	spin_lock_irqsave(&irq_big_lock, flags);
+	irq_radix_wrlock(&flags);
 	list_for_each_entry(h, &irq_hosts, link) {
 		if (h->revmap_type == IRQ_HOST_MAP_TREE)
 			INIT_RADIX_TREE(&h->revmap_data.tree, GFP_ATOMIC);
 	}
-	spin_unlock_irqrestore(&irq_big_lock, flags);
+	irq_radix_wrunlock(flags);
 
 	return 0;
 }

^ permalink raw reply

* Re: powerpc virq: minor cleanups
From: Benjamin Herrenschmidt @ 2006-08-28  1:20 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <44EF8182.2000401@am.sony.com>

On Fri, 2006-08-25 at 16:02 -0700, Geoff Levand wrote:
> Ben,
> 
> Please consider these cleanups.
> 
> 
> Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>

Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

> ---
> Index: cell--common--4/arch/powerpc/kernel/irq.c
> ===================================================================
> --- cell--common--4.orig/arch/powerpc/kernel/irq.c
> +++ cell--common--4/arch/powerpc/kernel/irq.c
> @@ -678,7 +680,7 @@
>  }
>  EXPORT_SYMBOL_GPL(irq_dispose_mapping);
>  
> -unsigned int irq_find_mapping(struct irq_host *host,
> +unsigned int irq_find_mapping(const struct irq_host *host,
>  			      irq_hw_number_t hwirq)
>  {
>  	unsigned int i;
> Index: cell--common--4/include/asm-powerpc/irq.h
> ===================================================================
> --- cell--common--4.orig/include/asm-powerpc/irq.h
> +++ cell--common--4/include/asm-powerpc/irq.h
> @@ -28,10 +28,10 @@
>  
>  #ifdef CONFIG_PPC_MERGE
>  
> -/* This number is used when no interrupt has been assigned */
> +/* This number is used when no virq has been assigned */
>  #define NO_IRQ			(0)
>  
> -/* This is a special irq number to return from get_irq() to tell that
> +/* This is a special virq number to return from get_irq() to tell that
>   * no interrupt happened _and_ ignore it (don't count it as bad). Some
>   * platforms like iSeries rely on that.
>   */
> @@ -217,7 +222,7 @@
>   * irq controller implementation directly calls the appropriate low level
>   * mapping function.
>   */
> -extern unsigned int irq_find_mapping(struct irq_host *host,
> +extern unsigned int irq_find_mapping(const struct irq_host *host,
>  				     irq_hw_number_t hwirq);
>  
> 

^ permalink raw reply

* Re: powerpc virq: new routine virq_to_hw
From: Benjamin Herrenschmidt @ 2006-08-28  1:22 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev
In-Reply-To: <44EF818B.9080301@am.sony.com>

On Fri, 2006-08-25 at 16:02 -0700, Geoff Levand wrote:
> Ben,
> 
> Please consider this accessor routine which hides the details
> of the map.
> 
> Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
> 
> ---
> Index: cell--common--4/include/asm-powerpc/irq.h
> ===================================================================
> --- cell--common--4.orig/include/asm-powerpc/irq.h
> +++ cell--common--4/include/asm-powerpc/irq.h
> @@ -136,6 +136,11 @@
>  
>  extern struct irq_map_entry irq_map[NR_IRQS];
>  
> +static inline irq_hw_number_t
> +virq_to_hw (unsigned int virq)
> +{
> +	return irq_map[virq].hwirq;
> +}

I'd much prefer:

static inline irq_hw_number_t virq_to_hw (unsigned int virq)
{
	return irq_map[virq].hwirq;
}

I've grown to dislike the CR between the return type and the function
name (I used to do that too) and it seems that this opinion is shared by
Linus (there was an old thread on lkml about it).

Cheers,
Ben.

^ permalink raw reply

* RE: Cache coherency question
From: Liu Dave-r63238 @ 2006-08-28  3:17 UTC (permalink / raw)
  To: Martin, Tim, ppc
In-Reply-To: <821B2170E9E7F04FA38DF7EC21DE4871062827EA@VCAEXCH01.hq.corp.viasat.com>

> Ah.  This must be the problem.  I have a few PCI devices, and=20
> on one of them it looked like snooping was working.  I just=20
> assumed the other device was setup correctly.

Why one is looked like snooping was working, and the other device
not working?

> > Also, you can define the CONFIG_NOT_COHERENT_CACHE, then you are=20
> > assuming The system has not hardware coherency. You need use the=20
> > software to keep the cache coherency.
> >=20
>=20
> I tried this, and got compiler errors.

What is the file got compiler errors? I notice that the
/ev64360_defconfig
Did define CONFIG_NOT_COHERENT_CACHE.


> I added some inline assembly dcbi/dcbf (invalidate/flush)=20
> instructions to the particular code in question, and the=20
> problems went away.  So definitely a cache problem.  As I=20
> said above, defining CONFIG_NOT_COHERENT_CACHE causes=20
> compiler errors, so I'm going to look into this more.  I=20
> suppose whatever file implements the=20
> include/linux/dma-mapping.h stuff isn't BSP specific, so its=20
> probably just not being compiled in?  Will look into it.

Somebody said from maillist. The bridge MV64360 seems
having some issue about cache coherent. I don't know if it is really?

-Dave

^ permalink raw reply

* Re: PCI driver
From: Lee Revell @ 2006-08-28  4:10 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: Leonid
In-Reply-To: <1156695850.6010.70.camel@mindpipe>

On Sun, 2006-08-27 at 12:24 -0400, Lee Revell wrote:
> Hello,
> 
> We have implemented a driver for a PCI sound card and are attempting to
> use it on a PPC400 Yosemite board.  However, as soon as any port I/O is
> attempted, we get a machine check error:
> 

Found the problem:

http://ozlabs.org/pipermail/linuxppc-embedded/2006-January/021708.html

Thanks!

Lee

^ permalink raw reply

* RE: [PATCH 4/4] Add MPC8349E MDS device tree source file toarch/powerpc/boot/dts
From: Li Yang-r58472 @ 2006-08-28  4:15 UTC (permalink / raw)
  To: Phillips Kim-R1AAHA, linuxppc-dev
In-Reply-To: <20060825115947.0d9ad52f.kim.phillips@freescale.com>

> -----Original Message-----
> From: linuxppc-dev-bounces+leoli=3Dfreescale.com@ozlabs.org
> [mailto:linuxppc-dev-bounces+leoli=3Dfreescale.com@ozlabs.org] On =
Behalf
Of Kim
> Phillips
> Sent: Saturday, August 26, 2006 1:00 AM
> To: linuxppc-dev@ozlabs.org
> Subject: [PATCH 4/4] Add MPC8349E MDS device tree source file
> toarch/powerpc/boot/dts

{snip}
> +
> +		pci@8500 {
> +			interrupt-map-mask =3D <f800 0 0 7>;
> +			interrupt-map =3D <
> +
> +					/* IDSEL 0x11 */
> +					 8800 0 0 1 700 14 0
> +					 8800 0 0 2 700 15 0
> +					 8800 0 0 3 700 16 0
> +					 8800 0 0 4 700 17 0

If we are changing sense definition in IPIC, we should change the
mapping to lines like below:
					 8800 0 0 1 700 14 2

- Leo

^ permalink raw reply

* RE: [PATCH 4/4] Add MPC8349E MDS device tree source filetoarch/powerpc/boot/dts
From: Li Yang-r58472 @ 2006-08-28  6:11 UTC (permalink / raw)
  To: Li Yang-r58472, Phillips Kim-R1AAHA, linuxppc-dev
In-Reply-To: <4879B0C6C249214CBE7AB04453F84E4D0FC5A7@zch01exm20.fsl.freescale.net>

> {snip}
> > +
> > +		pci@8500 {
> > +			interrupt-map-mask =3D <f800 0 0 7>;
> > +			interrupt-map =3D <
> > +
> > +					/* IDSEL 0x11 */
> > +					 8800 0 0 1 700 14 0
> > +					 8800 0 0 2 700 15 0
> > +					 8800 0 0 3 700 16 0
> > +					 8800 0 0 4 700 17 0
>=20
> If we are changing sense definition in IPIC, we should change the
> mapping to lines like below:
> 					 8800 0 0 1 700 14 2

Sorry, should be 8 for level low.

^ 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