Message ID | 20110404222637.GA4633@iram.es (mailing list archive) |
---|---|
State | Accepted, archived |
Commit | 2c78027a62ea38585da1ff944afdc6146335cb7c |
Headers | show |
On Tue, Apr 05, 2011 at 08:28:50AM +1000, Benjamin Herrenschmidt wrote: > > > Ok, I got fed up about it. The patch referred above is obviously wrong since > > it leaves interrupts at 0 when a device_type or name of 8042 is found, > > so what about the following? > > > > I can ship it with a signed-off-by and proper comments a bit later if people agree. > > > > Compiled and tested, otherwise I couldn't even type this message :-) > > Shouldn't that be a pegasos specific quirk in chrp/setup.c ? In this case I don't think so: 1) The code looks for the pnp id for the 8042 controllers and tries to fill the interrupt fields from OF/DT, but falls back to defaults 1 and 12 if it does not get them. 2) Then it tries to find device_type of 8042 or node name of 8042 and returns success if it finds them, but in this case leaves the interrupt numbers at zero. Note that in this case the code does not even attempt to get interrupt information from OF/DT, this looks like a fallback case where filling with defaults seems reasonable. Actually, it is not filling with defaults which seems wrong since the other case always provides interrupt information. Regards, Gabriel > > > > diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c > > index 9d4882a..06865ac 100644 > > --- a/arch/powerpc/kernel/setup-common.c > > +++ b/arch/powerpc/kernel/setup-common.c > > @@ -599,6 +599,10 @@ int check_legacy_ioport(unsigned long base_port) > > * name instead */ > > if (!np) > > np = of_find_node_by_name(NULL, "8042"); > > + if (np) { > > + of_i8042_kbd_irq = 1; > > + of_i8042_aux_irq = 12; > > + } > > break; > > case FDC_BASE: /* FDC1 */ > > np = of_find_node_by_type(NULL, "fdc"); >
Gabriel Paubert writes: > > Ok, I got fed up about it. The patch referred above is obviously wrong since > it leaves interrupts at 0 when a device_type or name of 8042 is found, > so what about the following? Looks like the workaround I was using for a while. In the original report I said I wasn't sending my kernel workaround patch because of the previous disagreements about whether the kernel should work around this type of bug. (In fact the current difficulty is the result of changes being made without considering the special case that was created by my first workaround... what a mess.) I also said I wasn't comfortable hacking the Forth-based part of the boot sequence because I didn't know the language. As it turned out, learning Forth was much easier than getting any guidance from the kernel people on how to proceed with a workaround, so I wrote this: === CUT HERE === " /isa/8042" find-device : open true ; : close ; : decode-unit ( addr len -- phys ) 1 <> if abort" invalid unit address" then c@ dup ascii 0 = if drop 0 exit then ascii 1 = if 1 exit then abort" invalid unit address" ; : encode-unit ( phys -- addr len ) dup 0 = if " 0" exit then 1 = if " 1" exit then abort" invalid unit address" ; 1 encode-int 3 encode-int encode+ d# 12 encode-int encode+ 3 encode-int encode+ " interrupts" property 0 0 " 0" " /isa/8042" begin-package " keyboard" device-name " keyboard" device-type " pnpPNP,303" encode-string " compatible" property 0 encode-int " reg" property end-package 0 0 " 1" " /isa/8042" begin-package " mouse" device-name " mouse" device-type " pnpPNP,f03" encode-string " compatible" property 1 encode-int " reg" property end-package === CUT HERE === Along with the previous device tree patch (pegasos-dts-20071018), this should present the kernel with a properly filled-out 8042 device-tree node, preventing the need for any more patching the next time the kernel changes its mind about how to initialize the keyboard driver.
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 9d4882a..06865ac 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -599,6 +599,10 @@ int check_legacy_ioport(unsigned long base_port) * name instead */ if (!np) np = of_find_node_by_name(NULL, "8042"); + if (np) { + of_i8042_kbd_irq = 1; + of_i8042_aux_irq = 12; + } break; case FDC_BASE: /* FDC1 */ np = of_find_node_by_type(NULL, "fdc");