* Re: [patch] fix RTC/NVRAM accesses on Maple
From: Segher Boessenkool @ 2006-05-30 11:38 UTC (permalink / raw)
To: jfaslist; +Cc: linuxppc-dev, Paul Mackerras, Hollis Blanchard
In-Reply-To: <447C20C4.50804@yahoo.fr>
> So the RTC/NVRAM patch is no longer needed for the Maple?
> Thanks
> -jf simon
[Post-top not do. Backwards read not do people.]
Hollis' latest patch is needed still. We agreed not to solve it
completely correctly yet, as we'll need more surgery in other parts
of the PowerPC kernel first.
Segher
^ permalink raw reply
* Re: [Done #2] Re: snd-aoa: Sound gone after snd-aoa updates, on PB5, 8
From: Wolfgang Pfeiffer @ 2006-05-30 11:23 UTC (permalink / raw)
To: Michel Dänzer; +Cc: linuxppc-dev, Johannes Berg
In-Reply-To: <1148975072.27856.294.camel@thor.lorrainebruecke.local>
On Tue, May 30, 2006 at 09:44:32AM +0200, Michel Dänzer wrote:
> On Tue, 2006-05-30 at 00:17 +0200, Wolfgang Pfeiffer wrote:
> >
> > The problem is: with libasound2 1.0.11-6 I cannot even *start*
> > alsamixer:
> >
> > ------------------------
> > $ alsamixer
> > ALSA lib control.c:816:(snd_ctl_open_noupdate) Invalid CTL default
> >
> > alsamixer: function snd_ctl_open failed for default: No such file or directory
>
> See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=369478 and friends.
Thanks.
And the bug already seems to be fixed with a new version: I just
installed it (libasound2 1.0.11-7) and at least alsamixer and amixer
started without error. Plus: Restarting the KDE sound system after
installing this new version also worked liked a charm.
Thanks to everyone involved :)
Best Regards
Wolfgang
--
Wolfgang Pfeiffer: /ICQ: 286585973/ + + + /AIM: crashinglinux/
http://profiles.yahoo.com/wolfgangpfeiffer
Key ID: E3037113
http://keyserver.mine.nu/pks/lookup?search=0xE3037113&fingerprint=on
^ permalink raw reply
* Re: [patch] fix RTC/NVRAM accesses on Maple
From: jfaslist @ 2006-05-30 10:39 UTC (permalink / raw)
To: Hollis Blanchard; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <1148593014.15517.32.camel@basalt.austin.ibm.com>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=us-ascii; format=flowed, Size: 594 bytes --]
Hi,
So the RTC/NVRAM patch is no longer needed for the Maple?
Thanks
-jf simon
Hollis Blanchard wrote:
>On Fri, 2006-05-19 at 08:58 +1000, Paul Mackerras wrote:
>
>
>>Care to redo the patch?
>>
>>
>
>After some offline discussion, I think we're in agreement that these
>properties are fine, since Linux's device tree code can't handle
>multiple ranges. Right Segher?
>
>
>
___________________________________________________________________________
Yahoo! Mail réinvente le mail ! Découvrez le nouveau Yahoo! Mail et son interface révolutionnaire.
http://fr.mail.yahoo.com
^ permalink raw reply
* RE: Linux kernel thread with Linux 2.6.x
From: Laurent Lagrange @ 2006-05-30 9:46 UTC (permalink / raw)
To: 'Thiago Galesi'; +Cc: linuxppc-embedded
In-Reply-To: <82ecf08e0605291013t7bd1627bg92d13908b3d0b7b7@mail.gmail.com>
Hi,
Thanks for your answer, but a tasklet runs in interrupt context
(in_interrupt() != 0) so it doesn't support schedule() call
included in "down" semaphore function.
Any other idea ?
Laurent.
> -----Message d'origine-----
> De : Thiago Galesi [mailto:thiagogalesi@gmail.com]
> Envoyé : lun. 29 mai 2006 18:13
> À : Laurent Lagrange
> Cc : linuxppc-embedded@ozlabs.org
> Objet : Re: Linux kernel thread with Linux 2.6.x
>
>
> >
> > As the interrupt handler can't be scheduled, I have made a
> kernel thread
> > which waits forever on a semaphore.
> > This semaphore is set when a received packet interrupt occured.
>
> You should look into tasklets for this. Not that your system is not
> OK, but, as you said it, it's not fast enough.
>
> Note that you still have some limitations using tasklets, but it's
> more flexible than Interrupt handlers.
>
>
^ permalink raw reply
* Re: Can't get CoralP drivers to work
From: jourdan @ 2006-05-30 9:39 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: linuxppc-embedded
In-Reply-To: <1758.194.3.133.184.1148897976.squirrel@webmail.enib.fr>
>> In message <1402.194.3.133.184.1148888040.squirrel@webmail.enib.fr> you
>> wrote:
>>>
>>> This seems ok to me but I don't have any video signal. My screen
>>> remains
>>> blank.
>>
>> What's your boot arguments? Where is your console device, on the
>> serial port or on the frame buffer?
>
> My boot arguments :
> # more /proc/cmdline
> console=tty0 console=ttyS1,9600 devfs=mount ip=bootp root=/dev/nfs rw
>
> My console is on the serial port (ttyS1 on SMC2).
>
>>> xf86OpenConsole: Cannot open /dev/tty0 (No such file or directory)
>>> ...
>>
>> Did you enable all of the following options in your kernel config?
>>
>> CONFIG_FB=y
>> CONFIG_DUMMY_CONSOLE=y
>> CONFIG_FB_MB86290=y
>> CONFIG_FBCON_ADVANCED=y
>> CONFIG_FBCON_CFB16=y
>> CONFIG_FBCON_FONTS=y
>> CONFIG_FONT_8x8=y
>> CONFIG_FONT_8x16=y
>> CONFIG_VT=y
>> CONFIG_VT_CONSOLE=y
>>
>> My guess is that CONFIG_VT and/or CONFIG_VT_CONSOLE might be missing.
>
> All those options are enabled.
>
As I said earlier, when the driver loads, my monitor don't receive any
video signal. I can force it by calling at the end of the initialization
of the driver :
reg = MB86290FB_READ_DISP_REGISTER(GDC_DISP_REG_EXT_MODE);
MB86290FB_WRITE_DISP_REGISTER(GDC_DISP_REG_EXT_MODE, reg | 0x80010000);
This command enables the display, and "garbage" appears on the monitor.
Then if i do :
# cat /dev/urandom > /dev/fb0
I should see dummy pixels on the screen but in fact nothing happens. This
is still the same garbage on the screen.
I use a custom processor card based on a MPC8270. I can't figure out if
the problem comes from the configuration of my kernel (all the needed
options are enabled) or if it is in the code of the initialisation of my
platform.
This is the first time I try to use framebuffer graphics, so I'm new with
it. Can the framebuffer work from a serial console on a platform without
keyboard ?
Thanks for your help.
^ permalink raw reply
* Re: [SOLVED] LXT973 support (dual PHY with single MDIO)
From: Laurent Pinchart @ 2006-05-30 9:28 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <200605301048.01209.laurent.pinchart@tbox.biz>
Hi,
once again, posting to a mailing list helped me solving my problem. It should
have been obvious that the MDIO bus is really a bus, and can as such support
several devices. The issue was that the drivers/net/fs_enet driver set
bus->phy_mask to ~0x9, and the LXT973 uses addresses 0 and 1. Address 1 thus
never got probed. What's the reason for probing addresses 0 and 3 only ?
Laurent Pinchart
^ permalink raw reply
* Re: LXT973 support (dual PHY with single MDIO)
From: Wojciech Kromer @ 2006-05-30 9:05 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <200605301048.01209.laurent.pinchart@tbox.biz>
I'm sucesfully using this chip with denx.de 2.4.25 kernel and single
MDIO port.
You need to change auto PHY-addr detection method. By default it
detects both PHYs on same addr.
^ permalink raw reply
* LXT973 support (dual PHY with single MDIO)
From: Laurent Pinchart @ 2006-05-30 8:48 UTC (permalink / raw)
To: linuxppc-embedded
Hi everybody,
I'm trying to bring up the two ethernet ports on a LXT973 dual-PHY chip. I've
declared two FCC platform devices, which are detected and handled by the
driver/net/fs_enet driver. My issue comes from MDIO support.
The LXT973 has a single MDIO port which answers to two addresses, one for each
PHY. The MDC and MDIO lines are connected to GPIO pins (no PHY interrupt), so
I'm using the bitbang MDIO driver. I've declared a MPC82xx_MDIO_BB platform
device, and set bus_id to "0:00" for both FCC ethernet devices. The first
ethernet device works fine, but the second complains that the PHY is already
in use.
As the PHY read/write accesses are protected by the bus->mdio_lock, I thought
about declaring a second MDIO platform device using the same I/O pins as the
first. Does anybody knows any problem I could run into using that approach ?
Is there a better method to handle the LXT973 MDIO ?
Thanks in advance for any help you can provide.
Best regards,
Laurent Pinchart
^ permalink raw reply
* Re: [Done] Re: snd-aoa: Sound gone after snd-aoa updates, on PB5,8
From: Michel Dänzer @ 2006-05-30 7:44 UTC (permalink / raw)
To: Wolfgang Pfeiffer; +Cc: linuxppc-dev, Johannes Berg
In-Reply-To: <20060529221730.GA3138@localhost>
On Tue, 2006-05-30 at 00:17 +0200, Wolfgang Pfeiffer wrote:
>=20
> The problem is: with libasound2 1.0.11-6 I cannot even *start*=20
> alsamixer:
>=20
> ------------------------
> $ alsamixer
> ALSA lib control.c:816:(snd_ctl_open_noupdate) Invalid CTL default
>=20
> alsamixer: function snd_ctl_open failed for default: No such file or dire=
ctory
See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=3D369478 and friends.
--=20
Earthling Michel D=C3=A4nzer | http://tungstengraphics.c=
om
Libre software enthusiast | Debian, X and DRI developer
^ permalink raw reply
* Re: undefined symbols of modules
From: Eugene Surovegin @ 2006-05-30 8:06 UTC (permalink / raw)
To: Josef Angermeier; +Cc: linuxppc-embedded
In-Reply-To: <447BF82A.8000503@cs.fau.de>
On Tue, May 30, 2006 at 09:45:46AM +0200, Josef Angermeier wrote:
> Hello,
>
> when i try to compile my kernel extension as modul, i get some undefined
> references. But a look in System.map shows, that the relevant symbols
> are defined in the main kernel. Why then those undefined references ?
Symbol must be exported to be available for modules, just being listed
in System.map isn't enough.
Try adding EXPORT_SYMBOL(...) for those "undefined" references.
--
Eugene
^ permalink raw reply
* undefined symbols of modules
From: Josef Angermeier @ 2006-05-30 7:45 UTC (permalink / raw)
To: linuxppc-embedded
Hello,
when i try to compile my kernel extension as modul, i get some undefined
references. But a look in System.map shows, that the relevant symbols
are defined in the main kernel. Why then those undefined references ?
Any hint is appreciated!
bye
Josef
make ARCH=ppc -C linux modules
make[1]: Entering directory `/scratch-local/esm/linux'
CHK include/linux/version.h
Building modules, stage 2.
MODPOST
*** Warning: "cpm_load_patch" [drivers/usb/host/m82xx-hcd.ko] undefined!
*** Warning: "cpmp" [drivers/usb/host/m82xx-hcd.ko] undefined!
^ permalink raw reply
* Re: [PATCH] powerpc vdso updates
From: Benjamin Herrenschmidt @ 2006-05-30 7:21 UTC (permalink / raw)
To: Ingo Molnar
Cc: Andrew Morton, linuxppc-dev list, Paul Mackerras,
Linux Kernel list
In-Reply-To: <20060530062447.GD19870@elte.hu>
> get_unmapped_area() without holding the mmap semaphore seems dangerous.
> The VDSO setup itself should be 'private' to the process, but i'm not
> totally sure that no other kernel code could get access to this mm. For
> example the swapout code? Am i missing something?
Well, all of this happens so early, I doubt anything will cause actual
harm, for get_unmapped_area to be a problem, something would have to
concurrently allocate a VMA (or dispose of) I think that can't happen at
this point before we even run the binary but yes, better safe than
sorry... I supose the whole patch could get in 2.6.17 even without the
arch_vma_name (that is it can be there, it wont be used though until
your patch gets in).
Ben.
^ permalink raw reply
* Re: [PATCH] powerpc vdso updates
From: Ingo Molnar @ 2006-05-30 6:24 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Andrew Morton, linuxppc-dev list, Paul Mackerras,
Linux Kernel list
In-Reply-To: <1148961097.15722.11.camel@localhost.localdomain>
* Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> This patch cleans up some locking & error handling in the ppc vdso and
> moves the vdso base pointer from the thread struct to the mm context
> where it more logically belongs. It brings the powerpc implementation
> closer to Ingo's new x86 one and also adds an arch_vma_name() function
> allowing to print [vsdo] in /proc/<pid>/maps if Ingo's x86 vdso patch
> is also applied.
looks good to me.
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: Ingo Molnar <mingo@elte.hu>
> This is 2.6.18 material, hopefully should go along with Ingo's x86
> vdso updates. Ingo, if you change something to arch_vma_name(), please
> let me know.
ok. There's one bit that could potentially be 2.6.17 material:
> * at vdso_base which is the "natural" base for it, but we might fail
> * and end up putting it elsewhere.
> */
> + down_write(&mm->mmap_sem);
> vdso_base = get_unmapped_area(NULL, vdso_base,
> vdso_pages << PAGE_SHIFT, 0, 0);
get_unmapped_area() without holding the mmap semaphore seems dangerous.
The VDSO setup itself should be 'private' to the process, but i'm not
totally sure that no other kernel code could get access to this mm. For
example the swapout code? Am i missing something?
Ingo
^ permalink raw reply
* [PATCH] kexec ppc64: add missing usage info for options
From: Michael Neuling @ 2006-05-30 6:06 UTC (permalink / raw)
To: linuxppc-dev, Fastboot mailing list
I had to look through the source to remember what these are one too many
times.
Patch below is against Maneesh's kexec-tools-1.101-kdump8 patches.
Signed-off-by: Michael Neuling <mikey@neuling.org>
---
kexec/arch/ppc64/kexec-ppc64.c | 4 ++++
1 file changed, 4 insertions(+)
Index: kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c
===================================================================
--- kexec-tools-1.101.orig/kexec/arch/ppc64/kexec-ppc64.c
+++ kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c
@@ -552,6 +552,10 @@ int file_types = sizeof(file_type) / siz
void arch_usage(void)
{
+ fprintf(stderr, " --command-line=<Command line> command line to append.\n");
+ fprintf(stderr, " --append=<Command line> same as --command-line.\n");
+ fprintf(stderr, " --ramdisk=<filename> Initial RAM disk.\n");
+ fprintf(stderr, " --initrd=<filename> same as --ramdisk.\n");
fprintf(stderr, " --devicetreeblob=<filename> Specify device tree blob file.\n");
fprintf(stderr, " --elf64-core-headers Prepare core headers in ELF64 format\n");
}
^ permalink raw reply
* [PATCH] kexec ppc64: fix segv when missing root= on cmdline
From: Michael Neuling @ 2006-05-30 5:02 UTC (permalink / raw)
To: linuxppc-dev, Fastboot mailing list; +Cc: miltonm
If the first kernel command line or the --command-line parameter doesn't
have a 'root=', we seg fault on ppc64.
Patch below is against Maneesh's kexec-tools-1.101-kdump8 patches.
Signed-off-by: Michael Neuling <mikey@neuling.org>
--
kexec/arch/ppc64/fs2dt.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
Index: kexec-tools-1.101/kexec/arch/ppc64/fs2dt.c
===================================================================
--- kexec-tools-1.101.orig/kexec/arch/ppc64/fs2dt.c
+++ kexec-tools-1.101/kexec/arch/ppc64/fs2dt.c
@@ -267,10 +267,12 @@ void putprops(char *fn, struct dirent **
char *old_param;
memcpy(temp_cmdline, dt, len);
param = strstr(temp_cmdline, "root=");
- old_param = strtok(param, " ");
- if (cmd_len != 0)
- strcat(local_cmdline, " ");
- strcat(local_cmdline, old_param);
+ if (param) {
+ old_param = strtok(param, " ");
+ if (cmd_len != 0)
+ strcat(local_cmdline, " ");
+ strcat(local_cmdline, old_param);
+ }
}
strcat(local_cmdline, " ");
cmd_len = strlen(local_cmdline);
^ permalink raw reply
* Re: [PATCH] powerpc: Fix buglet with MMU hash management
From: Benjamin Herrenschmidt @ 2006-05-30 4:55 UTC (permalink / raw)
To: Olof Johansson; +Cc: linuxppc-dev list, Paul Mackerras
In-Reply-To: <20060530043626.GC5101@pb15.lixom.net>
On Mon, 2006-05-29 at 23:36 -0500, Olof Johansson wrote:
> On Tue, May 30, 2006 at 02:14:19PM +1000, Benjamin Herrenschmidt wrote:
>
> > This fixes by allowing the updating of the protection bits in the native
> > hash handling to also set (but not clear) the "C" bit, and, in order to
> > also improve performances in the general case, by always setting that
> > bit on newly inserted hash PTE so that writeback really never happens.
>
> Good catch!
>
> However, you'll have a writeback on the R bit too, you should set that
> together with C.
Nope, R is always set at PTE insertion (it's _PAGE_ACCESSED)
Ben.
^ permalink raw reply
* Re: [PATCH] powerpc: Fix buglet with MMU hash management
From: Olof Johansson @ 2006-05-30 4:36 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, Paul Mackerras
In-Reply-To: <1148962460.15722.19.camel@localhost.localdomain>
On Tue, May 30, 2006 at 02:14:19PM +1000, Benjamin Herrenschmidt wrote:
> This fixes by allowing the updating of the protection bits in the native
> hash handling to also set (but not clear) the "C" bit, and, in order to
> also improve performances in the general case, by always setting that
> bit on newly inserted hash PTE so that writeback really never happens.
Good catch!
However, you'll have a writeback on the R bit too, you should set that
together with C.
-Olof
^ permalink raw reply
* RE: [PATCH/2.6.17-rc4 4/10]Powerpc: Add tsi108 pic support
From: Benjamin Herrenschmidt @ 2006-05-30 4:17 UTC (permalink / raw)
To: Zang Roy-r61911
Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
Alexandre.Bounine
In-Reply-To: <9FCDBA58F226D911B202000BDBAD467306585F22@zch01exm40.ap.freescale.net>
On Tue, 2006-05-30 at 11:28 +0800, Zang Roy-r61911 wrote:
> Tsi108 implementation of MPIC has many differences form the original one, the following
> code implements it with mpic. Any comment? The following patch is just based on
> my previous send out patches.
>
> Integrate Tundra Semiconductor tsi108 host bridge interrupt controller
> to mpic arch.
As usual... #ifdef's are evil. Only use them to avoid building bits that
are not useful for a given platform, not to change the behaviour of a
driver. By changing the MPIC driver with #ifdef's, you once again
prevent building a generic kernel image that can boot both your board
and pSeries, powermac, etc...
Please add an MPIC flag instead (as there is already for specifying, for
example, big endian MPICs) and add the necessary abstractions (for
example, put some register stride in the mpic instance structure and
initialize them based on the flags etc...)
Cheers,
Ben.
^ permalink raw reply
* [PATCH] powerpc: Fix buglet with MMU hash management
From: Benjamin Herrenschmidt @ 2006-05-30 4:14 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev list
Our MMU hash management code would not set the "C" bit (changed bit) in
the hardware PTE when updating a RO PTE into a RW PTE. That would cause
the hardware to possibly to a write back to the hash table to set it on
the first store access, which in addition to being a performance issue,
might also hit a bug when running with native hash management (non-HV)
as our code is specifically optimized for the case where no write back
happens.
Thus there is a very small therocial window were a hash PTE can become
corrupted if that HPTE has just been upgraded to read write, a store
access happens on it, and that races with another processor evicting
that same slot. Since eviction (caused by an almost full hash) is
extremely rare, the bug is very unlikely to happen fortunately.
This fixes by allowing the updating of the protection bits in the native
hash handling to also set (but not clear) the "C" bit, and, in order to
also improve performances in the general case, by always setting that
bit on newly inserted hash PTE so that writeback really never happens.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Index: linux-work/arch/powerpc/mm/hash_low_64.S
===================================================================
--- linux-work.orig/arch/powerpc/mm/hash_low_64.S 2006-01-14 14:43:22.000000000 +1100
+++ linux-work/arch/powerpc/mm/hash_low_64.S 2006-05-30 14:00:53.000000000 +1000
@@ -136,6 +136,7 @@ _GLOBAL(__hash_page_4K)
and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
andc r0,r30,r0 /* r0 = pte & ~r0 */
rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
+ ori r3,r3,HPTE_R_C /* Always add "C" bit for perf. */
/* We eventually do the icache sync here (maybe inline that
* code rather than call a C function...)
@@ -400,6 +401,7 @@ _GLOBAL(__hash_page_4K)
and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
andc r0,r30,r0 /* r0 = pte & ~r0 */
rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
+ ori r3,r3,HPTE_R_C /* Always add "C" bit for perf. */
/* We eventually do the icache sync here (maybe inline that
* code rather than call a C function...)
@@ -671,6 +673,7 @@ _GLOBAL(__hash_page_64K)
and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
andc r0,r30,r0 /* r0 = pte & ~r0 */
rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
+ ori r3,r3,HPTE_R_C /* Always add "C" bit for perf. */
/* We eventually do the icache sync here (maybe inline that
* code rather than call a C function...)
Index: linux-work/arch/powerpc/mm/hash_native_64.c
===================================================================
--- linux-work.orig/arch/powerpc/mm/hash_native_64.c 2006-03-10 15:58:17.000000000 +1100
+++ linux-work/arch/powerpc/mm/hash_native_64.c 2006-05-30 13:54:12.000000000 +1000
@@ -238,7 +238,7 @@ static long native_hpte_updatepp(unsigne
DBG_LOW(" -> hit\n");
/* Update the HPTE */
hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
- (newpp & (HPTE_R_PP | HPTE_R_N));
+ (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C));
native_unlock_hpte(hptep);
}
Index: linux-work/include/asm-powerpc/mmu.h
===================================================================
--- linux-work.orig/include/asm-powerpc/mmu.h 2006-05-30 13:40:21.000000000 +1000
+++ linux-work/include/asm-powerpc/mmu.h 2006-05-30 13:53:18.000000000 +1000
@@ -96,6 +96,8 @@ extern char initial_stab[];
#define HPTE_R_FLAGS ASM_CONST(0x00000000000003ff)
#define HPTE_R_PP ASM_CONST(0x0000000000000003)
#define HPTE_R_N ASM_CONST(0x0000000000000004)
+#define HPTE_R_C ASM_CONST(0x0000000000000080)
+#define HPTE_R_R ASM_CONST(0x0000000000000100)
/* Values for PP (assumes Ks=0, Kp=1) */
/* pp0 will always be 0 for linux */
^ permalink raw reply
* [PATCH] powerpc vdso updates
From: Benjamin Herrenschmidt @ 2006-05-30 3:51 UTC (permalink / raw)
To: linuxppc-dev list; +Cc: Ingo Molnar, Paul Mackerras, Linux Kernel list
This patch cleans up some locking & error handling in the ppc vdso and
moves the vdso base pointer from the thread struct to the mm context
where it more logically belongs. It brings the powerpc implementation
closer to Ingo's new x86 one and also adds an arch_vma_name() function
allowing to print [vsdo] in /proc/<pid>/maps if Ingo's x86 vdso patch is
also applied.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
This is 2.6.18 material, hopefully should go along with Ingo's x86 vdso updates. Ingo, if you
change something to arch_vma_name(), please let me know.
Index: linux-work/arch/powerpc/kernel/signal_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/signal_32.c 2006-05-30 13:34:09.000000000 +1000
+++ linux-work/arch/powerpc/kernel/signal_32.c 2006-05-30 13:40:21.000000000 +1000
@@ -757,10 +757,10 @@ static int handle_rt_signal(unsigned lon
/* Save user registers on the stack */
frame = &rt_sf->uc.uc_mcontext;
- if (vdso32_rt_sigtramp && current->thread.vdso_base) {
+ if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
if (save_user_regs(regs, frame, 0))
goto badframe;
- regs->link = current->thread.vdso_base + vdso32_rt_sigtramp;
+ regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
} else {
if (save_user_regs(regs, frame, __NR_rt_sigreturn))
goto badframe;
@@ -1029,10 +1029,10 @@ static int handle_signal(unsigned long s
|| __put_user(sig, &sc->signal))
goto badframe;
- if (vdso32_sigtramp && current->thread.vdso_base) {
+ if (vdso32_sigtramp && current->mm->context.vdso_base) {
if (save_user_regs(regs, &frame->mctx, 0))
goto badframe;
- regs->link = current->thread.vdso_base + vdso32_sigtramp;
+ regs->link = current->mm->context.vdso_base + vdso32_sigtramp;
} else {
if (save_user_regs(regs, &frame->mctx, __NR_sigreturn))
goto badframe;
Index: linux-work/arch/powerpc/kernel/signal_64.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/signal_64.c 2006-05-30 13:34:09.000000000 +1000
+++ linux-work/arch/powerpc/kernel/signal_64.c 2006-05-30 13:40:21.000000000 +1000
@@ -394,8 +394,8 @@ static int setup_rt_frame(int signr, str
current->thread.fpscr.val = 0;
/* Set up to return from userspace. */
- if (vdso64_rt_sigtramp && current->thread.vdso_base) {
- regs->link = current->thread.vdso_base + vdso64_rt_sigtramp;
+ if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
+ regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
} else {
err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
if (err)
Index: linux-work/arch/powerpc/kernel/vdso.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vdso.c 2006-05-30 13:34:09.000000000 +1000
+++ linux-work/arch/powerpc/kernel/vdso.c 2006-05-30 13:41:31.000000000 +1000
@@ -223,6 +223,7 @@ int arch_setup_additional_pages(struct l
struct vm_area_struct *vma;
unsigned long vdso_pages;
unsigned long vdso_base;
+ int rc;
#ifdef CONFIG_PPC64
if (test_thread_flag(TIF_32BIT)) {
@@ -237,20 +238,13 @@ int arch_setup_additional_pages(struct l
vdso_base = VDSO32_MBASE;
#endif
- current->thread.vdso_base = 0;
+ current->mm->context.vdso_base = 0;
/* vDSO has a problem and was disabled, just don't "enable" it for the
* process
*/
if (vdso_pages == 0)
return 0;
-
- vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
- if (vma == NULL)
- return -ENOMEM;
-
- memset(vma, 0, sizeof(*vma));
-
/* Add a page to the vdso size for the data page */
vdso_pages ++;
@@ -259,17 +253,23 @@ int arch_setup_additional_pages(struct l
* at vdso_base which is the "natural" base for it, but we might fail
* and end up putting it elsewhere.
*/
+ down_write(&mm->mmap_sem);
vdso_base = get_unmapped_area(NULL, vdso_base,
vdso_pages << PAGE_SHIFT, 0, 0);
- if (vdso_base & ~PAGE_MASK) {
- kmem_cache_free(vm_area_cachep, vma);
- return (int)vdso_base;
+ if (IS_ERR_VALUE(vdso_base)) {
+ rc = vdso_base;
+ goto fail_mmapsem;
}
- current->thread.vdso_base = vdso_base;
+ /* Allocate a VMA structure and fill it up */
+ vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
+ if (vma == NULL) {
+ rc = -ENOMEM;
+ goto fail_mmapsem;
+ }
vma->vm_mm = mm;
- vma->vm_start = current->thread.vdso_base;
+ vma->vm_start = vdso_base;
vma->vm_end = vma->vm_start + (vdso_pages << PAGE_SHIFT);
/*
@@ -282,23 +282,38 @@ int arch_setup_additional_pages(struct l
* It's fine to use that for setting breakpoints in the vDSO code
* pages though
*/
- vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
+ vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC;
vma->vm_flags |= mm->def_flags;
vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
vma->vm_ops = &vdso_vmops;
- down_write(&mm->mmap_sem);
- if (insert_vm_struct(mm, vma)) {
- up_write(&mm->mmap_sem);
- kmem_cache_free(vm_area_cachep, vma);
- return -ENOMEM;
- }
+ /* Insert new VMA */
+ rc = insert_vm_struct(mm, vma);
+ if (rc)
+ goto fail_vma;
+
+ /* Put vDSO base into mm struct and account for memory usage */
+ current->mm->context.vdso_base = vdso_base;
mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
up_write(&mm->mmap_sem);
-
return 0;
+
+ fail_vma:
+ kmem_cache_free(vm_area_cachep, vma);
+ fail_mmapsem:
+ up_write(&mm->mmap_sem);
+ return rc;
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso_base)
+ return "[vdso]";
+ return NULL;
}
+
+
static void * __init find_section32(Elf32_Ehdr *ehdr, const char *secname,
unsigned long *size)
{
Index: linux-work/include/asm-powerpc/elf.h
===================================================================
--- linux-work.orig/include/asm-powerpc/elf.h 2006-05-30 13:34:09.000000000 +1000
+++ linux-work/include/asm-powerpc/elf.h 2006-05-30 13:40:21.000000000 +1000
@@ -294,7 +294,7 @@ do { \
NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize); \
NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize); \
NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize); \
- VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->thread.vdso_base) \
+ VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso_base) \
} while (0)
/* PowerPC64 relocations defined by the ABIs */
Index: linux-work/include/asm-powerpc/mmu.h
===================================================================
--- linux-work.orig/include/asm-powerpc/mmu.h 2006-05-30 13:34:09.000000000 +1000
+++ linux-work/include/asm-powerpc/mmu.h 2006-05-30 13:40:21.000000000 +1000
@@ -360,6 +360,7 @@ typedef struct {
#ifdef CONFIG_HUGETLB_PAGE
u16 low_htlb_areas, high_htlb_areas;
#endif
+ unsigned long vdso_base;
} mm_context_t;
Index: linux-work/include/asm-powerpc/page.h
===================================================================
--- linux-work.orig/include/asm-powerpc/page.h 2006-05-30 13:34:09.000000000 +1000
+++ linux-work/include/asm-powerpc/page.h 2006-05-30 13:40:21.000000000 +1000
@@ -198,6 +198,9 @@ extern void copy_user_page(void *to, voi
struct page *p);
extern int page_is_ram(unsigned long pfn);
+struct vm_area_struct;
+extern const char *arch_vma_name(struct vm_area_struct *vma);
+
#include <asm-generic/memory_model.h>
#endif /* __ASSEMBLY__ */
Index: linux-work/include/asm-powerpc/processor.h
===================================================================
--- linux-work.orig/include/asm-powerpc/processor.h 2006-05-30 13:34:09.000000000 +1000
+++ linux-work/include/asm-powerpc/processor.h 2006-05-30 13:40:21.000000000 +1000
@@ -153,7 +153,6 @@ struct thread_struct {
unsigned long start_tb; /* Start purr when proc switched in */
unsigned long accum_tb; /* Total accumilated purr for process */
#endif
- unsigned long vdso_base; /* base of the vDSO library */
unsigned long dabr; /* Data address breakpoint register */
#ifdef CONFIG_ALTIVEC
/* Complete AltiVec register set */
^ permalink raw reply
* RE: [PATCH/2.6.17-rc4 4/10]Powerpc: Add tsi108 pic support
From: Zang Roy-r61911 @ 2006-05-30 3:28 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Paul Mackerras,
Alexandre.Bounine
>
> On Wed, 2006-05-17 at 18:14 +0800, Zang Roy-r61911 wrote:
> > Add Tundra Semiconductor tsi108 host bridge interrupt
> controller support.
>
> It looks a bit like an hacked up MPIC... Is it different
> enough to justify a separate driver ? Or would it be possible
> to define a TSI108 flag to pass the current mpic driver and
> add the necessary bits to it ?
>
Tsi108 implementation of MPIC has many differences form the original one, the following
code implements it with mpic. Any comment? The following patch is just based on
my previous send out patches.
Integrate Tundra Semiconductor tsi108 host bridge interrupt controller
to mpic arch.
Signed-off-by: Alexandre Bounine <alexandreb@tundra.com>
diff -pNur -x project.pj linux-2.6.17-rc4-tun/arch/powerpc/Kconfig linux-2.6.17-rc4-hpc2/arch/powerpc/Kconfig
--- linux-2.6.17-rc4-tun/arch/powerpc/Kconfig 2006-05-28 20:15:21.000000000 -0400
+++ linux-2.6.17-rc4-hpc2/arch/powerpc/Kconfig 2006-05-29 16:04:30.000000000 -0400
@@ -408,7 +408,8 @@ config U3_DART
default n
config MPIC
- depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP
+ depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \
+ || MPC7448HPC2
bool
default y
diff -pNur -x project.pj linux-2.6.17-rc4-tun/arch/powerpc/configs/mpc7448_hpc2_defconfig linux-2.6.17-rc4-hpc2/arch/powerpc/configs/mpc7448_hpc2_defconfig
--- linux-2.6.17-rc4-tun/arch/powerpc/configs/mpc7448_hpc2_defconfig 2006-05-28 20:15:36.000000000 -0400
+++ linux-2.6.17-rc4-hpc2/arch/powerpc/configs/mpc7448_hpc2_defconfig 2006-05-27 19:05:42.000000000 -0400
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.17-rc4
-# Tue May 23 11:29:48 2006
+# Sat May 27 18:45:55 2006
#
# CONFIG_PPC64 is not set
CONFIG_PPC32=y
@@ -110,6 +110,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_PPC_ISERIES is not set
CONFIG_EMBEDDED6xx=y
# CONFIG_APUS is not set
+CONFIG_MPIC=y
# CONFIG_PPC_RTAS is not set
# CONFIG_MMIO_NVRAM is not set
# CONFIG_PPC_MPC106 is not set
@@ -899,6 +900,7 @@ CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DEBUG_FS is not set
# CONFIG_UNWIND_INFO is not set
# CONFIG_BOOTX_TEXT is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
# CONFIG_PPC_EARLY_DEBUG_G5 is not set
# CONFIG_PPC_EARLY_DEBUG_RTAS is not set
diff -pNur -x project.pj linux-2.6.17-rc4-tun/arch/powerpc/platforms/embedded6xx/Kconfig linux-2.6.17-rc4-hpc2/arch/powerpc/platforms/embedded6xx/Kconfig
--- linux-2.6.17-rc4-tun/arch/powerpc/platforms/embedded6xx/Kconfig 2006-05-28 20:15:36.000000000 -0400
+++ linux-2.6.17-rc4-hpc2/arch/powerpc/platforms/embedded6xx/Kconfig 2006-05-29 15:55:13.000000000 -0400
@@ -79,6 +79,7 @@ config MPC7448HPC2
select TSI108_BRIDGE
select DEFAULT_UIMAGE
select PPC_UDBG_16550
+ select MPIC
help
Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga)
platform
diff -pNur -x project.pj linux-2.6.17-rc4-tun/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c linux-2.6.17-rc4-hpc2/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
--- linux-2.6.17-rc4-tun/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c 2006-05-28 20:15:36.000000000 -0400
+++ linux-2.6.17-rc4-hpc2/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c 2006-05-29 15:52:59.000000000 -0400
@@ -43,7 +43,16 @@
#include <asm/reg.h>
#include <mm/mmu_decl.h>
#include "mpc7448_hpc2.h"
-#include <asm/tsi108_pic.h>
+#include <asm/tsi108_irq.h>
+#include <asm/mpic.h>
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(fmt...) do { printk(fmt); } while(0)
+#else
+#define DBG(fmt...) do { } while(0)
+#endif
#ifndef CONFIG_PCI
isa_io_base = MPC7448_HPC2_ISA_IO_BASE;
@@ -53,6 +62,8 @@ pci_dram_offset = MPC7448_HPC2_PCI_MEM_O
extern int add_bridge(struct device_node *dev);
extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
+extern void tsi108_pci_int_init(void);
+extern int tsi108_irq_cascade(struct pt_regs *regs, void *unused);
#ifdef TSI108_ETH
hw_info hw_info_table[TSI108_ETH_MAX_PORTS + 1] = {
@@ -76,10 +87,32 @@ hw_info hw_info_table[TSI108_ETH_MAX_POR
*/
static u_char mpc7448_hpc2_pic_initsenses[] __initdata = {
+ /* External on-board sources */
(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[0] XINT0 from FPGA */
(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[1] XINT1 from FPGA */
(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[2] PHY_INT from both GIGE */
(IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[3] RESERVED */
+ /* Internal Tsi108/109 interrupt sources */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA0 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA1 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA2 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA3 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART0 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART1 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* I2C */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* GPIO */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE1 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* HLP */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* SDC */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Processor IF */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* PCI/X block */
};
/*
@@ -196,11 +229,42 @@ static void __init mpc7448_hpc2_setup_ar
*/
static void __init mpc7448_hpc2_init_IRQ(void)
{
+ struct mpic *mpic;
+ phys_addr_t mpic_paddr = 0;
+ struct device_node *tsi_pic;
+
+ tsi_pic = of_find_node_by_type(NULL, "open-pic");
+ if (tsi_pic) {
+ unsigned int size;
+ void *prop = get_property(tsi_pic, "reg", &size);
+ mpic_paddr = of_translate_address(tsi_pic, prop);
+ }
+
+ if (mpic_paddr == 0) {
+ printk("%s: No tsi108 PIC found !\n", __FUNCTION__);
+ return;
+ }
+
+ DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__,
+ (u32) mpic_paddr);
- tsi108_pic_init(mpc7448_hpc2_pic_initsenses);
+ mpic = mpic_alloc(mpic_paddr,
+ MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET,
+ 0, /* num_sources used */
+ TSI108_IRQ_BASE,
+ 0, /* num_sources used */
+ NR_IRQS - 4 /* XXXX */,
+ mpc7448_hpc2_pic_initsenses,
+ sizeof(mpc7448_hpc2_pic_initsenses), "Tsi108_PIC");
+
+ BUG_ON(mpic == NULL); /* XXXX */
+
+ mpic_init(mpic);
+ mpic_setup_cascade(IRQ_TSI108_PCI, tsi108_irq_cascade, mpic);
+ tsi108_pci_int_init();
/* Configure MPIC outputs to CPU0 */
- tsi108_pic_set_output(0, IRQ_SENSE_EDGE, IRQ_POLARITY_NEGATIVE);
+ tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
}
static void __init mpc7448_hpc2_map_io(void)
@@ -269,7 +333,7 @@ define_machine(mpc7448_hpc2){
.setup_arch = mpc7448_hpc2_setup_arch,
.init_IRQ = mpc7448_hpc2_init_IRQ,
.show_cpuinfo = mpc7448_hpc2_show_cpuinfo,
- .get_irq = tsi108_pic_get_irq,
+ .get_irq = mpic_get_irq,
.restart = mpc7448_hpc2_restart,
.calibrate_decr = generic_calibrate_decr,
.setup_io_mappings = mpc7448_hpc2_map_io,
diff -pNur -x project.pj linux-2.6.17-rc4-tun/arch/powerpc/sysdev/Makefile linux-2.6.17-rc4-hpc2/arch/powerpc/sysdev/Makefile
--- linux-2.6.17-rc4-tun/arch/powerpc/sysdev/Makefile 2006-05-28 20:12:58.000000000 -0400
+++ linux-2.6.17-rc4-hpc2/arch/powerpc/sysdev/Makefile 2006-05-29 16:06:23.000000000 -0400
@@ -8,4 +8,4 @@ obj-$(CONFIG_U3_DART) += dart_iommu.o
obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
obj-$(CONFIG_PPC_83xx) += ipic.o
obj-$(CONFIG_FSL_SOC) += fsl_soc.o
-obj-$(CONFIG_TSI108_BRIDGE) += tsi108_common.o tsi108_pic.o
+obj-$(CONFIG_TSI108_BRIDGE) += tsi108_common.o tsi108_pci_int.o
diff -pNur -x project.pj linux-2.6.17-rc4-tun/arch/powerpc/sysdev/mpic.c linux-2.6.17-rc4-hpc2/arch/powerpc/sysdev/mpic.c
--- linux-2.6.17-rc4-tun/arch/powerpc/sysdev/mpic.c 2006-03-20 00:53:29.000000000 -0500
+++ linux-2.6.17-rc4-hpc2/arch/powerpc/sysdev/mpic.c 2006-05-29 16:07:03.000000000 -0400
@@ -81,7 +81,7 @@ static inline void _mpic_write(unsigned
static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
{
unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0;
- unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
+ unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * MPIC_GREG_IPI_STRIDE);
if (mpic->flags & MPIC_BROKEN_IPI)
be = !be;
@@ -90,7 +90,7 @@ static inline u32 _mpic_ipi_read(struct
static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value)
{
- unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
+ unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * MPIC_GREG_IPI_STRIDE);
_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value);
}
@@ -393,7 +393,11 @@ static inline struct mpic * mpic_from_ir
static inline void mpic_eoi(struct mpic *mpic)
{
mpic_cpu_write(MPIC_CPU_EOI, 0);
+#ifndef CONFIG_TSI108_BRIDGE
(void)mpic_cpu_read(MPIC_CPU_WHOAMI);
+#else
+ (void)mpic_cpu_read(MPIC_CPU_OUTPUT);
+#endif
}
#ifdef CONFIG_SMP
@@ -514,9 +518,26 @@ static void mpic_end_irq(unsigned int ir
}
#endif /* CONFIG_MPIC_BROKEN_U3 */
+#ifdef CONFIG_TSI108_BRIDGE
+ if ((irq_desc[irq].status & IRQ_LEVEL) != 0)
+#endif
mpic_eoi(mpic);
}
+#ifdef CONFIG_TSI108_BRIDGE
+static void mpic_ack_irq(unsigned int irq)
+{
+ struct mpic *mpic = mpic_from_irq(irq);
+
+#ifdef DEBUG_IRQ
+ DBG("%s: ack_irq: %d\n", mpic->name, irq);
+#endif
+
+ if ((irq_desc[irq].status & IRQ_LEVEL) == 0)
+ mpic_eoi(mpic);
+}
+#endif /* CONFIG_TSI108_BRIDGE */
+
#ifdef CONFIG_SMP
static void mpic_enable_ipi(unsigned int irq)
@@ -596,6 +617,9 @@ struct mpic * __init mpic_alloc(unsigned
mpic->hc_irq.enable = mpic_enable_irq;
mpic->hc_irq.disable = mpic_disable_irq;
mpic->hc_irq.end = mpic_end_irq;
+#ifdef CONFIG_TSI108_BRIDGE
+ mpic->hc_irq.ack = mpic_ack_irq;
+#endif
if (flags & MPIC_PRIMARY)
mpic->hc_irq.set_affinity = mpic_set_affinity;
#ifdef CONFIG_SMP
@@ -955,8 +979,13 @@ void mpic_send_ipi(unsigned int ipi_no,
DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
#endif
+#ifndef CONFIG_TSI108_BRIDGE
mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
+#else /* CONFIG_TSI108_BRIDGE */
+ mpic_write(mpic->gregs, MPIC_CPU_IPI_DISPATCH,
+ mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
+#endif /* !CONFIG_TSI108_BRIDGE */
}
int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs)
@@ -972,11 +1001,20 @@ int mpic_get_one_irq(struct mpic *mpic,
DBG("%s: cascading ...\n", mpic->name);
#endif
irq = mpic->cascade(regs, mpic->cascade_data);
+#ifdef DEBUG_LOW
+ DBG("%s: cascaded irq: %d\n", mpic->name, irq);
+#endif
+#ifndef CONFIG_TSI108_BRIDGE
mpic_eoi(mpic);
+#endif
return irq;
}
- if (unlikely(irq == MPIC_VEC_SPURRIOUS))
+ if (unlikely(irq == MPIC_VEC_SPURRIOUS)) {
+#ifdef CONFIG_TSI108_BRIDGE
+ mpic_eoi(mpic);
+#endif
return -1;
+ }
if (irq < MPIC_VEC_IPI_0) {
#ifdef DEBUG_IRQ
DBG("%s: irq %d\n", mpic->name, irq + mpic->irq_offset);
diff -pNur -x project.pj linux-2.6.17-rc4-tun/arch/powerpc/sysdev/tsi108_common.c linux-2.6.17-rc4-hpc2/arch/powerpc/sysdev/tsi108_common.c
--- linux-2.6.17-rc4-tun/arch/powerpc/sysdev/tsi108_common.c 2006-05-28 20:12:58.000000000 -0400
+++ linux-2.6.17-rc4-hpc2/arch/powerpc/sysdev/tsi108_common.c 2006-05-29 16:08:52.000000000 -0400
@@ -90,9 +90,13 @@ tsi108_direct_write_config(struct pci_bu
{
volatile unsigned char *cfg_addr;
+ if (ppc_md.pci_exclude_device)
+ if (ppc_md.pci_exclude_device(bus->number, devfunc))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number,
devfunc, offset) |
- (offset & 0x03));
+ (offset & 0x03));
#ifdef TSI108_PCI_DEBUG
printk("PCI CFG write : ");
@@ -172,6 +176,10 @@ tsi108_direct_read_config(struct pci_bus
volatile unsigned char *cfg_addr;
u32 temp;
+ if (ppc_md.pci_exclude_device)
+ if (ppc_md.pci_exclude_device(bus->number, devfn))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number,
devfn,
offset) | (offset &
diff -pNur -x project.pj linux-2.6.17-rc4-tun/arch/powerpc/sysdev/tsi108_pci_int.c linux-2.6.17-rc4-hpc2/arch/powerpc/sysdev/tsi108_pci_int.c
--- linux-2.6.17-rc4-tun/arch/powerpc/sysdev/tsi108_pci_int.c 1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.17-rc4-hpc2/arch/powerpc/sysdev/tsi108_pci_int.c 2006-05-29 16:09:04.000000000 -0400
@@ -0,0 +1,219 @@
+/*
+ * (C) Copyright 2005 Tundra Semiconductor Corp.
+ * Alex Bounine, <alexandreb@tundra.com).
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/*
+ * Tsi108 PCI Interrupt Handling (cascaded to MPIC)
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <asm/ptrace.h>
+#include <asm/signal.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+#include <asm/sections.h>
+#include <asm/hardirq.h>
+#include <asm/machdep.h>
+
+#include <asm/tsi108.h>
+#include <asm/tsi108_irq.h>
+
+#undef DEBUG
+#undef DBG_TSI108_INTERRUPT
+
+#ifdef DEBUG
+#define DBG(fmt...) do { printk(fmt); } while(0)
+#else
+#define DBG(fmt...) do { } while(0)
+#endif
+
+extern u32 get_vir_csrbase(void);
+extern u32 tsi108_read_reg(u32 reg_offset);
+extern void tsi108_write_reg(u32 reg_offset, u32 val);
+
+/*
+ * Low level utility functions
+ */
+
+static void tsi108_pci_int_mask(u_int irq)
+{
+ u_int irp_cfg;
+ int int_line = (irq - IRQ_PCI_INTAD_BASE);
+
+ irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
+ mb();
+ irp_cfg |= (1 << int_line); /* INTx_DIR = output */
+ irp_cfg &= ~(3 << (8 + (int_line * 2))); /* INTx_TYPE = unused */
+ tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg);
+ mb();
+ irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
+}
+
+static void tsi108_pci_int_unmask(u_int irq)
+{
+ u_int irp_cfg;
+ int int_line = (irq - IRQ_PCI_INTAD_BASE);
+
+ irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
+ mb();
+ irp_cfg &= ~(1 << int_line);
+ irp_cfg |= (3 << (8 + (int_line * 2)));
+ tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg);
+ mb();
+}
+
+static void init_pci_source(void)
+{
+ tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL,
+ 0x0000ff00);
+ tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE,
+ 0x00400000);
+ mb();
+}
+
+static inline int get_pci_source(void)
+{
+ u_int temp = 0;
+ int irq = -1;
+ int i;
+ u_int pci_irp_stat;
+ static int mask = 0;
+
+ /* Read PCI/X block interrupt status register */
+ pci_irp_stat = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT);
+ mb();
+
+ if (pci_irp_stat & TSI108_PCI_IRP_STAT_P_INT) {
+ /* Process Interrupt from PCI bus INTA# - INTD# lines */
+ temp =
+ tsi108_read_reg(TSI108_PCI_OFFSET +
+ TSI108_PCI_IRP_INTAD) & 0xf;
+ mb();
+ for (i = 0; i < 4; i++, mask++) {
+ if (temp & (1 << mask % 4)) {
+ irq = IRQ_PCI_INTA + mask % 4;
+ mask++;
+ break;
+ }
+ }
+ }
+#ifdef DBG_TSI108_INTERRUPT
+ else {
+ printk("TSI108_PIC: error in TSI108_PCI_IRP_STAT\n");
+ pci_irp_stat =
+ tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT);
+ temp =
+ tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_INTAD);
+ mb();
+ printk(">> stat=0x%08x intad=0x%08x ", pci_irp_stat, temp);
+ temp =
+ tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
+ mb();
+ printk("cfg_ctl=0x%08x ", temp);
+ temp =
+ tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE);
+ mb();
+ printk("irp_enable=0x%08x\n", temp);
+ }
+#endif /* DBG_TSI108_INTERRUPT */
+
+ return irq;
+}
+
+
+/*
+ * Linux descriptor level callbacks
+ */
+
+static void tsi108_pci_irq_enable(u_int irq)
+{
+ tsi108_pci_int_unmask(irq);
+}
+
+static void tsi108_pci_irq_disable(u_int irq)
+{
+ tsi108_pci_int_mask(irq);
+}
+
+static void tsi108_pci_irq_ack(u_int irq)
+{
+ tsi108_pci_int_mask(irq);
+}
+
+static void tsi108_pci_irq_end(u_int irq)
+{
+ /* Signal EOI to the Tsi108 interrupt controller. */
+ irq_desc[IRQ_TSI108_PCI].handler->end(IRQ_TSI108_PCI);
+ tsi108_pci_int_unmask(irq);
+}
+
+/*
+ * Interrupt controller descriptor for cascaded PCI interrupt controller.
+ */
+
+struct hw_interrupt_type tsi108_pci_irq = {
+ .typename = "tsi108_PCI_int",
+ .enable = tsi108_pci_irq_enable,
+ .disable = tsi108_pci_irq_disable,
+ .ack = tsi108_pci_irq_ack,
+ .end = tsi108_pci_irq_end,
+};
+
+/*
+ * Exported functions
+ */
+
+/*
+ * The Tsi108 PCI interrupts initialization routine.
+ *
+ * The INTA# - INTD# interrupts on the PCI bus are reported by the PCI block
+ * to the MPIC using single interrupt source (IRQ_TSI108_PCI). Therefore the
+ * PCI block has to be treated as a cascaded interrupt controller connected
+ * to the MPIC.
+ */
+
+void __init tsi108_pci_int_init(void)
+{
+ u_int i;
+
+ DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
+
+ for (i = 0; i < NUM_PCI_IRQS; i++) {
+ irq_desc[i + IRQ_PCI_INTAD_BASE].handler = &tsi108_pci_irq;
+ irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL;
+ }
+
+ init_pci_source();
+}
+
+int tsi108_irq_cascade(struct pt_regs *regs, void *unused)
+{
+ return get_pci_source();
+}
diff -pNur -x project.pj linux-2.6.17-rc4-tun/arch/powerpc/sysdev/tsi108_pic.c linux-2.6.17-rc4-hpc2/arch/powerpc/sysdev/tsi108_pic.c
--- linux-2.6.17-rc4-tun/arch/powerpc/sysdev/tsi108_pic.c 2006-05-28 20:13:07.000000000 -0400
+++ linux-2.6.17-rc4-hpc2/arch/powerpc/sysdev/tsi108_pic.c 1969-12-31 19:00:00.000000000 -0500
@@ -1,813 +0,0 @@
-/*
- * (C) Copyright 2005 Tundra Semiconductor Corp.
- * Alex Bounine, <alexandreb@tundra.com).
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
- */
-
-/*
- * Tsi108 Interrupt Controller Handling
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/sysdev.h>
-#include <asm/ptrace.h>
-#include <asm/signal.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/prom.h>
-#include <asm/sections.h>
-#include <asm/hardirq.h>
-#include <asm/machdep.h>
-
-#include <asm/tsi108.h>
-#include <asm/tsi108_irq.h>
-#include <asm/tsi108_pic.h>
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(fmt...) do { printk(fmt); } while(0)
-#else
-#define DBG(fmt...) do { } while(0)
-#endif
-
-extern u32 get_vir_csrbase(void);
-extern u32 tsi108_read_reg(u32 reg_offset);
-extern void tsi108_write_reg(u32 reg_offset, u32 val);
-
-static phys_addr_t tsi108_pic_phy_addr;
-static u32 tsi108_pic_vir_addr;
-
-static int tsi108_pic_cascade_irq = -1;
-static int (*tsi108_pic_cascade_fn) (struct pt_regs *);
-
-/* Global Operations */
-static void tsi108_pic_set_task_priority(u_int pri);
-static void tsi108_pic_set_spurious(u_int vector);
-void tsi108_pic_mask_all(void);
-
-/* Timer Interrupts */
-static void tsi108_pic_inittimer(u_int timer, u_int pri, u_int vector);
-static void tsi108_pic_maptimer(u_int timer, u_int cpumask);
-
-/* Interrupt Sources */
-static void tsi108_pic_enable_irq(u_int irq);
-static void tsi108_pic_disable_irq(u_int irq);
-static void tsi108_pic_initirq(u_int irq, u_int pri, u_int vector, int polarity,
- int is_level);
-static void tsi108_pic_mapirq(u_int irq, u_int cpumask, u_int keepmask);
-static void init_pci_source(void);
-static inline int get_pci_source(int vector);
-int tsi108_pic_set_irq_sense(int irq, int pol, int sense);
-
-/*
- * tsi108_pic interface routines
- */
-static void tsi108_pic_end_irq(unsigned int irq_nr);
-static void tsi108_pic_ack_irq(unsigned int irq_nr);
-void tsi108_pic_set_affinity(unsigned int irq_nr, unsigned long cpumask);
-
-static struct hw_interrupt_type tsi108_pic_irq = {
- "tsi108_pic",
- NULL,
- NULL,
- tsi108_pic_enable_irq,
- tsi108_pic_disable_irq,
- tsi108_pic_ack_irq,
- tsi108_pic_end_irq,
- NULL
-};
-
-static void tsi108_pci_irq_enable(u_int irq);
-static void tsi108_pci_irq_disable(u_int irq);
-static void tsi108_pci_irq_ack(u_int irq);
-static void tsi108_pci_irq_end(u_int irq);
-
-static struct hw_interrupt_type tsi108_pci_irq = {
- "tsi108_PCI_int",
- NULL,
- NULL,
- tsi108_pci_irq_enable,
- tsi108_pci_irq_disable,
- tsi108_pci_irq_ack,
- tsi108_pci_irq_end,
- NULL
-};
-
-#ifdef DBG_TSI108_INTERRUPT
-#define ASSERT(expr) if (!(expr)) { \
- printk("tsi108pic :" \
- "assertion failed! %s[%d]: %s\n", \
- __FUNCTION__, __LINE__, #expr); \
- dump_stack(); \
- }
-#else
-#define ASSERT(expr) do {} while (0)
-#endif
-
-static inline u_int get_vector_offset(u_int irq)
-{
- u_int offset;
-
- if (irq < TSI108_IRQ_BASE || irq >= IRQ_PCI_INTAD_BASE)
- return 0;
-
- if (irq < IRQ_TSI108_MBOX0)
- offset = TSI108_INT_IVPR(irq - TSI108_IRQ_BASE);
- else if (irq < IRQ_TSI108_DBELL0)
- offset = TSI108_INT_MBVPR(irq - IRQ_TSI108_MBOX0);
- else if (irq < IRQ_TSI108_TIMER0)
- offset = TSI108_INT_DVPR(irq - IRQ_TSI108_DBELL0);
- else
- offset = TSI108_INT_GTVPR(irq - IRQ_TSI108_TIMER0);
-
- return offset;
-}
-
-static inline u_int tsi108_pic_read_reg(u_int reg_offset)
-{
- return in_be32((volatile u32 *)(tsi108_pic_vir_addr + reg_offset));
-}
-
-static inline void tsi108_pic_write_reg(u_int reg_offset, u_int val)
-{
- out_be32((volatile u32 *)(tsi108_pic_vir_addr + reg_offset), val);
-}
-
-void tsi108_pic_reset(void)
-{
- tsi108_pic_write_reg(TSI108_INT_GCR, TSI108PIC_INT_GCR_R);
- while (tsi108_pic_read_reg(TSI108_INT_GCR) & TSI108PIC_INT_GCR_R)
- mb();
-}
-
-void tsi108_pic_set_output(int dest_num, u32 sense, u32 polarity)
-{
- u32 temp = 0;
- temp |= (IRQ_SENSE_LEVEL == sense) ?
- (TSI108PIC_INT_CSR_S_LEVEL) : (TSI108PIC_INT_CSR_S_EDGE);
- temp |= (IRQ_POLARITY_POSITIVE == polarity) ?
- (TSI108PIC_INT_CSR_P_HIGH) : (TSI108PIC_INT_CSR_P_LOW);
- tsi108_pic_write_reg(TSI108_INT_CSR(dest_num), temp);
- mb();
-}
-
-int tsi108_pic_source_cfg(int src_num, /* interrupt source number */
- u32 sense, /* interrupt source Sense */
- u32 polarity, /* interrupt source Polarity */
- TSI108_IRQ_MODE mode /* interrupt delivery Mode */
- )
-{
- unsigned temp;
-
- temp = tsi108_pic_read_reg(TSI108_INT_IVPR(src_num));
-
- if (temp & TSI108PIC_ACTIVITY) /* error if source is active */
- return -1;
-
- if (0 == (temp & TSI108PIC_MASK)) {
- temp |= TSI108PIC_MASK; /* mask IRQ prior making changes */
- tsi108_pic_write_reg(TSI108_INT_IVPR(src_num), temp);
- }
-
- temp &= ~(TSI108PIC_INT_IVPR_MODE |
- TSI108PIC_INT_IVPR_S | TSI108PIC_INT_IVPR_P);
-
- temp |= (IRQ_SENSE_LEVEL == sense) ?
- (TSI108PIC_INT_CSR_S_LEVEL) : (TSI108PIC_INT_CSR_S_EDGE);
- temp |= (IRQ_POLARITY_POSITIVE == polarity) ?
- (TSI108PIC_INT_CSR_P_HIGH) : (TSI108PIC_INT_CSR_P_LOW);
-
- tsi108_pic_write_reg(TSI108_INT_IVPR(src_num),
- TSI108PIC_MASK | (mode << 29) | temp);
- return (0);
-}
-
-int tsi108_pic_set_vector(int src_num, /* source number */
- int vect, /* vector number */
- int prio /* interrupt source priority */
- )
-{
- unsigned tmp;
-
- tmp = tsi108_pic_read_reg(TSI108_INT_IVPR(src_num));
-
- if (tmp & TSI108PIC_ACTIVITY) /* error if source is active */
- return -1;
-
- if (0 == (tmp & TSI108PIC_MASK)) {
- tmp |= TSI108PIC_MASK; /* mask IRQ prior making changes */
- tsi108_pic_write_reg(TSI108_INT_IVPR(src_num), tmp);
- }
-
- /* clear bits to be changed */
- tmp &= ~(TSI108PIC_VECTOR_MASK | TSI108PIC_PRIORITY_MASK);
-
- tmp |= (prio << 16) | vect;
- tsi108_pic_write_reg(TSI108_INT_IVPR(src_num), tmp);
- return 0;
-}
-
-void tsi108_pic_mask_all()
-{
- int i;
- unsigned int vp;
-
- /* Mask all external and internal interrupt sources */
- for (i = 0; i < TSI108PIC_MAX_SOURCES; i++) {
- vp = tsi108_pic_read_reg(TSI108_INT_IVPR(i));
- tsi108_pic_write_reg(TSI108_INT_IVPR(i), vp | TSI108PIC_MASK);
- mb();
-
- /* Make sure that irq is masked */
- do {
- vp = tsi108_pic_read_reg(TSI108_INT_IVPR(i));
- } while ((vp & TSI108PIC_ACTIVITY) && !(vp & TSI108PIC_MASK));
- }
-
- /* Mask all timer interrupts */
- for (i = 0; i < TSI108PIC_NUM_TIMERS; i++) {
- vp = tsi108_pic_read_reg(TSI108_INT_GTVPR(i));
- tsi108_pic_write_reg(TSI108_INT_GTVPR(i), vp | TSI108PIC_MASK);
- mb();
-
- do {
- vp = tsi108_pic_read_reg(TSI108_INT_GTVPR(i));
- } while ((vp & TSI108PIC_ACTIVITY) && !(vp & TSI108PIC_MASK));
- }
-
- /* Mask all doorbell interrupts */
- for (i = 0; i < TSI108PIC_NUM_DBELLS; i++) {
- vp = tsi108_pic_read_reg(TSI108_INT_DVPR(i));
- tsi108_pic_write_reg(TSI108_INT_IVPR(i), vp | TSI108PIC_MASK);
- mb();
-
- do {
- vp = tsi108_pic_read_reg(TSI108_INT_DVPR(i));
- } while ((vp & TSI108PIC_ACTIVITY) && !(vp & TSI108PIC_MASK));
- }
-
- /* Mask all mailbox interrupts */
- for (i = 0; i < 4; i++) {
- vp = tsi108_pic_read_reg(TSI108_INT_MBVPR(i));
- tsi108_pic_write_reg(TSI108_INT_MBVPR(i), vp | TSI108PIC_MASK);
- mb();
-
- do {
- vp = tsi108_pic_read_reg(TSI108_INT_MBVPR(i));
- } while ((vp & TSI108PIC_ACTIVITY) && !(vp & TSI108PIC_MASK));
- }
-}
-
-/*
- * The Tsi108 PC initialization routine.
- * A caller routine (usually from platform-specific code has to provide
- * sense/polarity configuration information for four external interrupt
- * sources INT0 - INT3. This should be done in form of four-byte array
- * (one byte per source ) that contains combination of sensitivity/polarity
- * flags defined in asm-ppc/irq.h.
- *
- * Example of PIC initialization call is shown below:
- *
- * u_char your_board_pic_initsenses[] __initdata = {
- * (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), // INT[0]
- * (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), // INT[1]
- * (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), // INT[2]
- * (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE) // INT[3]
- * };
- *
- * tsi108_pic_init(your_board_pic_initsenses);
- */
-
-void __init tsi108_pic_init(u_char * board_init_senses)
-{
- u_int i;
- u32 sense;
-
- struct device_node *tsi_pic;
- tsi_pic = of_find_node_by_type(NULL, "open-pic");
- if (tsi_pic) {
- unsigned int size;
- void *prop = get_property(tsi_pic, "reg", &size);
- tsi108_pic_phy_addr = of_translate_address(tsi_pic, prop);
- }
-
- DBG("%s: Tsi108 pic phy addr = 0x%x\n", __FUNCTION__,
- (u32) tsi108_pic_phy_addr);
- if (tsi108_pic_phy_addr == 0) {
- printk("No tsi108 PIC found !\n");
- return;
- }
-
- tsi108_pic_vir_addr = (u32) ioremap(tsi108_pic_phy_addr, 0x400);
-
- tsi108_pic_reset();
-
- if (ppc_md.progress)
- ppc_md.progress("tsi108_pic_init: enter", 0x122);
-
- /* Initialize timer interrupts */
- for (i = 0; i < TSI108PIC_NUM_TIMERS; i++) {
- /* Disabled, Priority 0 */
- tsi108_pic_inittimer(i, 0, IRQ_TSI108_TIMER0 + i);
- /* No processor */
- tsi108_pic_maptimer(i, 0);
- }
-
- /* Init board-specific external sources */
- for (i = 0; i < 4; i++) {
- sense = board_init_senses[i];
-
- if (sense & IRQ_SENSE_MASK)
- irq_desc[TSI108_IRQ(i)].status |= IRQ_LEVEL;
-
- /* Enabled, Priority 8 */
- tsi108_pic_initirq(i, 8, TSI108_IRQ(i),
- (sense & IRQ_POLARITY_MASK),
- (sense & IRQ_SENSE_MASK));
- /* Map to CPU #0 */
- tsi108_pic_mapirq(TSI108_IRQ(i), 1 << 0, 0);
- }
-
- /* Init remaining internal sources. */
- for (; i < TSI108PIC_MAX_SOURCES; i++) {
- /* Disabled, Priority 8, by default - Positive Edge */
- tsi108_pic_initirq(i, 8, TSI108_IRQ(i),
- IRQ_POLARITY_POSITIVE, IRQ_SENSE_EDGE);
- /* Map to CPU #0 */
- tsi108_pic_mapirq(TSI108_IRQ(i), (1 << 0), 0);
- }
-
- /*
- * Change sensitivity to level for sources that require it.
- */
-
- irq_desc[IRQ_TSI108_GIGE0].status |= IRQ_LEVEL;
- irq_desc[IRQ_TSI108_GIGE1].status |= IRQ_LEVEL;
- irq_desc[IRQ_TSI108_PCI].status |= IRQ_LEVEL;
-
- /* Init descriptors */
- for (i = 0; i < TSI108PIC_MAX_SOURCES; i++)
- irq_desc[i + TSI108_IRQ_BASE].handler = &tsi108_pic_irq;
-
- for (i = 0; i < NUM_PCI_IRQS; i++) {
- irq_desc[i + IRQ_PCI_INTAD_BASE].handler = &tsi108_pci_irq;
- irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL;
- }
-
- /* Initialize the spurious interrupt */
- tsi108_pic_set_spurious(TSI108_IRQ_SPURIOUS);
- tsi108_pic_set_task_priority(0);
-
- init_pci_source();
- tsi108_pic_enable_irq(IRQ_TSI108_PCI);
-
- i = tsi108_pic_read_reg(TSI108_INT_VECTOR(0));
- tsi108_pic_write_reg(TSI108_INT_EOI(0), 0);
-
- if (ppc_md.progress)
- ppc_md.progress("tsi108_pic_init: exit", 0x222);
-}
-
-/*
- * Find out the current interrupt
- */
-static u_int tsi108_pic_get_vect(void)
-{
- u_int vec;
-
- vec = tsi108_pic_read_reg(TSI108_INT_VECTOR(0)) & TSI108PIC_VECTOR_MASK;
-
-#ifdef DBG_TSI108_INTERRUPT
- if (vec == TSI108_IRQ_SPURIOUS)
- printk("TSI108: SPURIOUS vec=0x%08x\n", vec);
- else
- printk("TSI108: read vec=0x%08x\n", vec);
-#endif
- return (vec);
-}
-
-static inline void tsi108_pic_eoi(void)
-{
- tsi108_pic_write_reg(TSI108_INT_EOI(0), 0);
- mb();
-}
-
-static void __init tsi108_pic_set_task_priority(u_int pri)
-{
- ASSERT(pri >= 0 && pri < TSI108PIC_NUM_PRI);
-
- tsi108_pic_write_reg(TSI108_INT_TASKP(0),
- pri & TSI108PIC_INT_TASKP_TASKP);
- mb();
-}
-
-static void tsi108_pic_set_spurious(u_int vec)
-{
- ASSERT(vec == TSI108_IRQ_SPURIOUS);
- tsi108_pic_write_reg(TSI108_INT_SVR, vec);
- mb();
-}
-
-#ifdef CONFIG_SMP
-/*
- * Convert a cpu mask from logical to physical cpu numbers.
- */
-static inline u32 physmask(u32 cpumask)
-{
- int i;
- u32 mask = 0;
-
- for (i = 0; i < NR_CPUS; ++i, cpumask >>= 1)
- if (cpu_online(i))
- mask |= (cpumask & 1) << smp_hw_index[i];
- return mask;
-}
-#else
-#define physmask(cpumask) (cpumask)
-#endif
-
-/*
- * Initialize a timer interrupt (and disable it)
- *
- * timer: timer number
- * pri: interrupt source priority
- * vec: the vector it will produce
- */
-static void __init tsi108_pic_inittimer(u_int timer, u_int pri, u_int vec)
-{
- unsigned int gtvpr;
-
- ASSERT(timer >= 0 && timer < TSI108PIC_NUM_TIMERS);
- ASSERT(pri >= 0 && pri < TSI108PIC_NUM_PRI);
- ASSERT(vec >= 0 && vec < TSI108PIC_NUM_VECTORS);
-
- gtvpr = tsi108_pic_read_reg(TSI108_INT_GTVPR(timer));
- gtvpr &= ~(TSI108PIC_PRIORITY_MASK | TSI108PIC_VECTOR_MASK);
- gtvpr |= (pri << 16) | vec;
- tsi108_pic_write_reg(TSI108_INT_GTVPR(timer), gtvpr | TSI108PIC_MASK);
- mb();
-}
-
-/*
- * Map a timer interrupt to one or more CPUs
- */
-static void __init tsi108_pic_maptimer(u_int timer, u_int cpumask)
-{
- ASSERT(timer >= 0 && timer < TSI108PIC_NUM_TIMERS);
-
- tsi108_pic_write_reg(TSI108_INT_GTDR(timer), physmask(cpumask));
- mb();
-}
-
-/*
- * Initalize the interrupt source which will generate an NMI.
- * This raises the interrupt's priority from 8 to 9.
- *
- * irq: The logical IRQ which generates an NMI.
- */
-void __init tsi108_pic_init_nmi_irq(u_int irq)
-{
- u_int offset = get_vector_offset(irq);
- u_int vpr = tsi108_pic_read_reg(offset);
- vpr &= ~TSI108PIC_PRIORITY_MASK;
- tsi108_pic_write_reg(offset, vpr | (9 << 16));
- mb();
-}
-
-/*
- *
- * All functions below take an offset'ed irq argument
- *
- */
-
-/*
- * Hookup a cascade to the tsi108 PIC.
- */
-void __init
-tsi108_pic_hookup_cascade(u_int irq, char *name,
- int (*cascade_fn) (struct pt_regs *))
-{
- tsi108_pic_cascade_irq = irq;
- tsi108_pic_cascade_fn = cascade_fn;
- if (request_irq(irq, no_action, SA_INTERRUPT, name, NULL))
- printk("Unable to get Tsi108 PIC IRQ %d for cascade\n",
- irq - TSI108_IRQ_BASE);
-}
-
-/*
- * Enable/disable an external interrupt source
- *
- * Externally called, irq is an offseted system-wide interrupt number
- */
-static void tsi108_pic_enable_irq(u_int irq)
-{
- u32 offset = get_vector_offset(irq);
- u32 vpr = tsi108_pic_read_reg(offset);
-
- /*
- * Undo sensitivity change (see tsi108_pic_disable_irq())
- */
- if (irq_desc[irq].status & IRQ_LEVEL)
- vpr |= TSI108PIC_INT_IVPR_S;
-
- tsi108_pic_write_reg(offset, vpr & ~TSI108PIC_MASK);
- mb();
-}
-
-static void tsi108_pic_disable_irq(u_int irq)
-{
- u32 offset = get_vector_offset(irq);
- u32 vpr = tsi108_pic_read_reg(offset);
-
- /*
- * Switch level interrupt to edge sensitivity to avoid generation
- * of spurious interrupt request. See design note in Tsi108 PIC
- * section of Tsi108 manual.
- */
- if (irq_desc[irq].status & IRQ_LEVEL)
- vpr &= ~TSI108PIC_INT_IVPR_S;
-
- tsi108_pic_write_reg(offset, vpr | TSI108PIC_MASK);
- mb();
- vpr = tsi108_pic_read_reg(offset);
- if (!(vpr & TSI108PIC_MASK))
- printk("TSI108_PIC: Error - Unable disable IRQ %d\n", irq);
-}
-
-/*
- * Initialize an interrupt source (and disable it!)
- *
- * irq: Tsi108 PIC interrupt source number
- * pri: interrupt source priority
- * vec: the vector it will produce
- * pol: polarity (1 for positive, 0 for negative)
- * sense: 1 for level, 0 for edge
- */
-static void __init
-tsi108_pic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense)
-{
- unsigned int ivpr;
-
- ivpr = TSI108PIC_MASK | (pri << 16) | vec;
- ivpr |= (IRQ_SENSE_LEVEL == sense) ?
- TSI108PIC_INT_IVPR_S_LEVEL : TSI108PIC_INT_IVPR_S_EDGE;
- ivpr |= (IRQ_POLARITY_POSITIVE == pol) ?
- TSI108PIC_INT_IVPR_P_HIGH : TSI108PIC_INT_IVPR_P_LOW;
- tsi108_pic_write_reg(TSI108_INT_IVPR(irq), ivpr);
- mb();
-}
-
-int tsi108_pic_set_irq_sense(int irq, /* PIC source number */
- int pol, /* interrupt source polarity */
- int sense /* interrupt source sense */
- )
-{
- unsigned int ivpr;
-
- ivpr = tsi108_pic_read_reg(TSI108_INT_IVPR(irq));
-
- if (ivpr & TSI108PIC_ACTIVITY) /* error if source is active */
- return -1;
-
- if (0 == (ivpr & TSI108PIC_MASK)) {
- ivpr |= TSI108PIC_MASK; /* mask IRQ prior making changes */
- tsi108_pic_write_reg(TSI108_INT_IVPR(irq), ivpr);
- }
-
- /* clear bits to be changed */
- ivpr &= ~(TSI108PIC_INT_IVPR_P | TSI108PIC_INT_IVPR_S);
-
- ivpr |= (IRQ_SENSE_LEVEL == sense) ?
- TSI108PIC_INT_IVPR_S_LEVEL : TSI108PIC_INT_IVPR_S_EDGE;
- ivpr |= (IRQ_POLARITY_POSITIVE == pol) ?
- TSI108PIC_INT_IVPR_P_HIGH : TSI108PIC_INT_IVPR_P_LOW;
-
- tsi108_pic_write_reg(TSI108_INT_IVPR(irq), ivpr);
- return 0;
-}
-
-/*
- * Map an interrupt source to one or more CPUs
- */
-static void tsi108_pic_mapirq(u_int irq, u_int physmask, u_int keepmask)
-{
- u_int offset = get_vector_offset(irq);
-
- if (0 == offset)
- return;
- if (keepmask != 0)
- physmask |= tsi108_pic_read_reg(offset + 4);
- tsi108_pic_write_reg(offset + 4, physmask);
- mb();
-}
-
-/* No spinlocks, should not be necessary with the Tsi108 PIC
- * (1 register = 1 interrupt and we have the desc lock).
- */
-static void tsi108_pic_ack_irq(unsigned int irq_nr)
-{
- if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0)
- tsi108_pic_eoi();
-}
-
-static void tsi108_pic_end_irq(unsigned int irq_nr)
-{
- if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0)
- tsi108_pic_eoi();
-}
-
-void tsi108_pic_set_affinity(unsigned int irq_nr, unsigned long cpumask)
-{
- tsi108_pic_mapirq(irq_nr, physmask(cpumask), 0);
-}
-
-int tsi108_pic_get_irq(struct pt_regs *regs)
-{
- int vector = tsi108_pic_get_vect();
-
- if (vector == TSI108_IRQ_SPURIOUS) {
- vector = -1;
- }
-
- if (vector == IRQ_TSI108_PCI) {
- vector = get_pci_source(vector);
- }
-
- if (vector == -1) {
- tsi108_pic_write_reg(TSI108_INT_EOI(0), 0);
- }
-
- return vector;
-}
-
-static void tsi108_pci_int_mask(u_int irq)
-{
- u_int irp_cfg;
- int int_line = (irq - IRQ_PCI_INTAD_BASE);
-
- irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
- mb();
- irp_cfg |= (1 << int_line); /* INTx_DIR = output */
- irp_cfg &= ~(3 << (8 + (int_line * 2))); /* INTx_TYPE = unused */
- tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg);
- mb();
- irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
-}
-
-static void tsi108_pci_int_unmask(u_int irq)
-{
- u_int irp_cfg;
- int int_line = (irq - IRQ_PCI_INTAD_BASE);
-
- irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
- mb();
- irp_cfg &= ~(1 << int_line);
- irp_cfg |= (3 << (8 + (int_line * 2)));
- tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg);
- mb();
-}
-
-static void tsi108_pci_irq_enable(u_int irq)
-{
- tsi108_pci_int_unmask(irq);
-}
-
-static void tsi108_pci_irq_disable(u_int irq)
-{
- tsi108_pci_int_mask(irq);
-}
-
-static void tsi108_pci_irq_ack(u_int irq)
-{
- tsi108_pci_int_mask(irq);
-}
-
-static void tsi108_pci_irq_end(u_int irq)
-{
- tsi108_pic_eoi(); /* eoi IRQ_TSI108_PCI */
- tsi108_pci_int_unmask(irq);
-}
-
-static inline int get_pci_source(int vector)
-{
- u_int temp = 0;
- int irq = -1;
- int i;
- u_int pci_irp_stat;
- static int mask = 0;
-
- /* Read PCI/X block interrupt status register */
- pci_irp_stat = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT);
- mb();
-
- if (pci_irp_stat & TSI108_PCI_IRP_STAT_P_INT) {
- /* Process Interrupt from PCI bus INTA# - INTD# lines */
- temp =
- tsi108_read_reg(TSI108_PCI_OFFSET +
- TSI108_PCI_IRP_INTAD) & 0xf;
- mb();
- for (i = 0; i < 4; i++, mask++) {
- if (temp & (1 << mask % 4)) {
- irq = IRQ_PCI_INTA + mask % 4;
- mask++;
- break;
- }
- }
- }
-#ifdef DBG_TSI108_INTERRUPT
- else {
- printk("TSI108_PIC: error in TSI108_PCI_IRP_STAT\n");
- pci_irp_stat =
- tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT);
- temp =
- tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_INTAD);
- mb();
- printk(">> stat=0x%08x intad=0x%08x ", pci_irp_stat, temp);
- temp =
- tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL);
- mb();
- printk("cfg_ctl=0x%08x ", temp);
- temp =
- tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE);
- mb();
- printk("irp_enable=0x%08x\n", temp);
- }
-#endif /* DBG_TSI108_INTERRUPT */
-
- return irq;
-}
-
-static void init_pci_source(void)
-{
- tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL,
- 0x0000ff00);
- tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE,
- 0x00400000);
- mb();
-}
-
-static struct sysdev_class tsi108_pic_sysclass = {
- set_kset_name("tsi108_pic"),
-};
-
-static struct sys_device device_tsi108_pic = {
- .id = 0,
- .cls = &tsi108_pic_sysclass,
-};
-
-static struct sysdev_driver driver_tsi108_pic = {
-#ifdef CONFIG_PM /* FIXME: placeholder for future development */
- .suspend = &tsi108_pic_suspend,
- .resume = &tsi108_pic_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init init_tsi108_pic_sysfs(void)
-{
- int rc;
-
- if (!get_csrbase())
- return -ENODEV;
- printk(KERN_DEBUG "Registering tsi108_pic with sysfs...\n");
- rc = sysdev_class_register(&tsi108_pic_sysclass);
- if (rc) {
- printk(KERN_ERR "Failed registering tsi108_pic sys class\n");
- return -ENODEV;
- }
- rc = sysdev_register(&device_tsi108_pic);
- if (rc) {
- printk(KERN_ERR "Failed registering tsi108_pic sys device\n");
- return -ENODEV;
- }
- rc = sysdev_driver_register(&tsi108_pic_sysclass, &driver_tsi108_pic);
- if (rc) {
- printk(KERN_ERR "Failed registering tsi108_pic sys driver\n");
- return -ENODEV;
- }
- return 0;
-}
-
-subsys_initcall(init_tsi108_pic_sysfs);
diff -pNur -x project.pj linux-2.6.17-rc4-tun/include/asm-powerpc/mpic.h linux-2.6.17-rc4-hpc2/include/asm-powerpc/mpic.h
--- linux-2.6.17-rc4-tun/include/asm-powerpc/mpic.h 2006-03-20 00:53:29.000000000 -0500
+++ linux-2.6.17-rc4-hpc2/include/asm-powerpc/mpic.h 2006-05-29 16:11:03.000000000 -0400
@@ -4,6 +4,7 @@
#include <linux/irq.h>
+#ifndef CONFIG_TSI108_BRIDGE
/*
* Global registers
*/
@@ -37,6 +38,7 @@
#define MPIC_GREG_IPI_VECTOR_PRI_1 0x000b0
#define MPIC_GREG_IPI_VECTOR_PRI_2 0x000c0
#define MPIC_GREG_IPI_VECTOR_PRI_3 0x000d0
+#define MPIC_GREG_IPI_STRIDE 0x10
#define MPIC_GREG_SPURIOUS 0x000e0
#define MPIC_GREG_TIMER_FREQ 0x000f0
@@ -91,6 +93,87 @@
#define MPIC_VECPRI_SENSE_MASK 0x00400000
#define MPIC_IRQ_DESTINATION 0x00010
+#else /* CONFIG_TSI108_BRIDGE */
+
+/* Tsi108 implementation of MPIC has many differences form the original one */
+
+/*
+ * Global registers
+ */
+
+#define MPIC_GREG_BASE 0x00000
+
+#define MPIC_GREG_FEATURE_0 0x00000
+#define MPIC_GREG_FEATURE_LAST_SRC_MASK 0x07ff0000
+#define MPIC_GREG_FEATURE_LAST_SRC_SHIFT 16
+#define MPIC_GREG_FEATURE_LAST_CPU_MASK 0x00001f00
+#define MPIC_GREG_FEATURE_LAST_CPU_SHIFT 8
+#define MPIC_GREG_FEATURE_VERSION_MASK 0xff
+#define MPIC_GREG_GLOBAL_CONF_0 0x00004
+#define MPIC_GREG_GCONF_RESET 0x80000000
+#define MPIC_GREG_GCONF_8259_PTHROU_DIS 0x00000000
+#define MPIC_GREG_IPI_VECTOR_PRI_0 0x00204 /* Doorbell 0 */
+#define MPIC_GREG_IPI_VECTOR_PRI_1 0x00210 /* Doorbell 1 */
+#define MPIC_GREG_IPI_VECTOR_PRI_2 0x0021c /* Doorbell 2 */
+#define MPIC_GREG_IPI_VECTOR_PRI_3 0x00228 /* Doorbell 3 */
+#define MPIC_GREG_IPI_STRIDE 0x0c
+#define MPIC_GREG_SPURIOUS 0x00010
+#define MPIC_GREG_TIMER_FREQ 0x00014
+
+/*
+ * Timer registers
+ */
+#define MPIC_TIMER_BASE 0x0030
+#define MPIC_TIMER_STRIDE 0x10
+
+#define MPIC_TIMER_CURRENT_CNT 0x00000
+#define MPIC_TIMER_BASE_CNT 0x00004
+#define MPIC_TIMER_VECTOR_PRI 0x00008
+#define MPIC_TIMER_DESTINATION 0x0000c
+
+/*
+ * Per-Processor registers
+ */
+
+#define MPIC_CPU_THISBASE 0x00000
+#define MPIC_CPU_BASE 0x00300
+#define MPIC_CPU_STRIDE 0x00040
+
+#define MPIC_CPU_IPI_DISPATCH 0x00200
+#define MPIC_CPU_CURRENT_TASK_PRI 0x00000
+#define MPIC_CPU_TASKPRI_MASK 0x0000000f
+#define MPIC_CPU_INTACK 0x00004
+#define MPIC_CPU_EOI 0x00008
+#define MPIC_CPU_OUTPUT 0x0000c
+#define MPIC_OUTPUT_POLARITY_POSITIVE 0x00000001
+#define MPIC_OUTPUT_POLARITY_NEGATIVE 0x00000000
+#define MPIC_OUTPUT_POLARITY_MASK 0x00000001
+#define MPIC_OUTPUT_SENSE_LEVEL 0x00000002
+#define MPIC_OUTPUT_SENSE_EDGE 0x00000000
+#define MPIC_OUTPUT_SENSE_MASK 0x00000002
+
+/*
+ * Per-source registers
+ */
+
+#define MPIC_IRQ_BASE 0x00100
+#define MPIC_IRQ_STRIDE 0x00008
+#define MPIC_IRQ_VECTOR_PRI 0x00000
+#define MPIC_VECPRI_MASK 0x80000000
+#define MPIC_VECPRI_ACTIVITY 0x40000000 /* Read Only */
+#define MPIC_VECPRI_PRIORITY_MASK 0x000f0000
+#define MPIC_VECPRI_PRIORITY_SHIFT 16
+#define MPIC_VECPRI_VECTOR_MASK 0x000000ff
+#define MPIC_VECPRI_POLARITY_POSITIVE 0x01000000
+#define MPIC_VECPRI_POLARITY_NEGATIVE 0x00000000
+#define MPIC_VECPRI_POLARITY_MASK 0x01000000
+#define MPIC_VECPRI_SENSE_LEVEL 0x02000000
+#define MPIC_VECPRI_SENSE_EDGE 0x00000000
+#define MPIC_VECPRI_SENSE_MASK 0x02000000
+#define MPIC_IRQ_DESTINATION 0x00004
+
+#endif /* CONFIG_TSI108_BRIDGE */
+
#define MPIC_MAX_IRQ_SOURCES 2048
#define MPIC_MAX_CPUS 32
#define MPIC_MAX_ISU 32
diff -pNur -x project.pj linux-2.6.17-rc4-tun/include/asm-powerpc/tsi108_pic.h linux-2.6.17-rc4-hpc2/include/asm-powerpc/tsi108_pic.h
--- linux-2.6.17-rc4-tun/include/asm-powerpc/tsi108_pic.h 2006-05-28 20:13:07.000000000 -0400
+++ linux-2.6.17-rc4-hpc2/include/asm-powerpc/tsi108_pic.h 1969-12-31 19:00:00.000000000 -0500
@@ -1,232 +0,0 @@
-/*
- * (C) Copyright 2005 Tundra Semiconductor Corp.
- * Alex Bounine, <alexandreb@tundra.com).
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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
- */
-
-/*
- * arch/ppc/syslib/tsi108_pic.h - Tsi108 Interrupt Controller definitions
- */
-
-#ifndef _LINUX_TSI108_PIC_H
-#define _LINUX_TSI108_PIC_H
-
-#include <asm/tsi108_irq.h>
-
-#ifdef __KERNEL__
-
-/*
- * Tsi108 PIC supports up to 24 interrupt sources and up to 4 processors
- */
-
-#define TSI108PIC_MAX_SOURCES 24
-#define TSI108PIC_MAX_PROCESSORS 4
-
-#define TSI108PIC_NUM_TIMERS 4
-#define TSI108PIC_NUM_DBELLS 4
-#define TSI108PIC_NUM_PROC 4
-#define TSI108PIC_NUM_PRI 16
-#define TSI108PIC_NUM_VECTORS 256
-
-/*
- * Tsi108 PIC Register offsets within block.
- */
-
-/* Registers controlling sources */
-#define TSI108_INT_FRR (0x000)
-#define TSI108_INT_GCR (0x004)
-#define TSI108_INT_SVR (0x010)
-#define TSI108_INT_GTVPR(n) (0x38 + 0x10*(n))
-#define TSI108_INT_GTDR(n) (0x3C + 0x10*(n))
-#define TSI108_INT_IVPR(n) (0x100 + 0x8*(n))
-#define TSI108_INT_IDR(n) (0x104 + 0x8*(n))
-#define TSI108_INT_DVPR(n) (0x204 + 0xC*(n))
-#define TSI108_INT_DDR(n) (0x208 + 0xC*(n))
-#define TSI108_INT_MBVPR(n) (0x284 + 0x10*(n))
-#define TSI108_INT_MBDR(n) (0x288 + 0x10*(n))
-
-/* Registers controlling destinations */
-#define TSI108_INT_TASKP(n) (0x300 + 0x40*(n))
-#define TSI108_INT_VECTOR(n) (0x304 + 0x40*(n))
-#define TSI108_INT_EOI(n) (0x308 + 0x40*(n))
-#define TSI108_INT_CSR(n) (0x30C + 0x40*(n))
-
-/*
- * Generic definitions common for different types of interrupt
- * sources.
- */
-
-#define TSI108PIC_MASK (0x80000000)
-#define TSI108PIC_ACTIVITY (0x40000000)
-#define TSI108PIC_PRIORITY_MASK (0x000f0000)
-#define TSI108PIC_VECTOR_MASK (0x000000ff)
-
-/**********************************************************
- * Register Bit Masks definitions for every register
- */
-
-/* TSI108PIC_INT_FRR : Register Bits Masks Definitions */
-#define TSI108PIC_INT_FRR_VID (0x000000ff)
-#define TSI108PIC_INT_FRR_NCPU (0x00001f00)
-#define TSI108PIC_INT_FRR_NITM (0x0000e000)
-#define TSI108PIC_INT_FRR_NIRQ (0x07ff0000)
-#define TSI108PIC_INT_FRR_NIDOOR (0xe0000000)
-#define TSI108PIC_INT_FRR_RESERVED (0x18000000)
-
-/* TSI108PIC_INT_GCR : Register Bits Masks Definitions */
-#define TSI108PIC_INT_GCR_R (0x80000000)
-#define TSI108PIC_INT_GCR_RESERVED (0x7fffffff)
-
-/* TSI108PIC_INT_ICR : Register Bits Masks Definitions */
-#define TSI108PIC_INT_ICR_R (0x0000000f)
-#define TSI108PIC_INT_ICR_RESERVED (0xfffffff0)
-
-/* TSI108PIC_INT_MVI : Register Bits Masks Definitions */
-#define TSI108PIC_INT_MVI_VID (0x000000ff)
-#define TSI108PIC_INT_MVI_DID (0x0000ff00)
-#define TSI108PIC_INT_MVI_STEP (0x00ff0000)
-#define TSI108PIC_INT_MVI_RESERVED (0xff000000)
-
-/* TSI108PIC_INT_SVR : Register Bits Masks Definitions */
-#define TSI108PIC_INT_SVR_VECTOR (0x000000ff)
-#define TSI108PIC_INT_SVR_RESERVED (0xffffff00)
-
-/* TSI108PIC_INT_TFRR : Register Bits Masks Definitions */
-#define TSI108PIC_INT_TFRR_TIME_FREQ (0xffffffff)
-
-/* TSI108PIC_INT_SOFT_SET : Register Bits Masks Definitions */
-#define TSI108PIC_INT_SOFT_SET_S (0x00ffffff)
-#define TSI108PIC_INT_SOFT_SET_RESERVED (0xff000000)
-
-/* TSI108PIC_INT_SOFT_ENABLE : Register Bits Masks Definitions */
-#define TSI108PIC_INT_SOFT_ENABLE_EN (0x00ffffff)
-#define TSI108PIC_INT_SOFT_ENABLE_RESERVED (0xff000000)
-
-/* TSI108PIC_INT_GTCCR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_GTCCR_COUNT (0x7fffffff)
-#define TSI108PIC_INT_GTCCR_T (0x80000000)
-
-/* TSI108PIC_INT_GTBCR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_GTBCR_B_COUNT (0x7fffffff)
-#define TSI108PIC_INT_GTBCR_CI (0x80000000)
-
-/* TSI108PIC_INT_GTVPR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_GTVPR_VECTOR (0x000000ff)
-#define TSI108PIC_INT_GTVPR_PRIORITY (0x000f0000)
-#define TSI108PIC_INT_GTVPR_PRESCALE (0x00f00000)
-#define TSI108PIC_INT_GTVPR_A (0x40000000)
-#define TSI108PIC_INT_GTVPR_M (0x80000000)
-#define TSI108PIC_INT_GTVPR_RESERVED (0x3f00ff00)
-
-/* TSI108PIC_INT_GTDR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_GTDR_SEL_OUT (0x0000000f)
-#define TSI108PIC_INT_GTDR_RESERVED (0xfffffff0)
-
-/* TSI108PIC_INT_IVPR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_IVPR_VECTOR (0x000000ff)
-#define TSI108PIC_INT_IVPR_PRIORITY (0x000f0000)
-
-#define TSI108PIC_INT_IVPR_P (0x01000000)
-#define TSI108PIC_INT_IVPR_P_LOW (0 << 24)
-#define TSI108PIC_INT_IVPR_P_HIGH (1 << 24)
-
-#define TSI108PIC_INT_IVPR_S (0x02000000)
-#define TSI108PIC_INT_IVPR_S_EDGE (0 << 25)
-#define TSI108PIC_INT_IVPR_S_LEVEL (1 << 25)
-
-#define TSI108PIC_INT_IVPR_MODE (0x20000000)
-#define TSI108PIC_INT_IVPR_A (0x40000000)
-#define TSI108PIC_INT_IVPR_M (0x80000000)
-#define TSI108PIC_INT_IVPR_RESERVED (0x1cf0ff00)
-
-/* TSI108PIC_INT_IDR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_IDR_SEL_OUT (0x0000000f)
-#define TSI108PIC_INT_IDR_RESERVED (0xfffffff0)
-
-/* TSI108PIC_INT_DAR : Register Bits Masks Definitions */
-#define TSI108PIC_INT_DAR_A (0x0000000f)
-#define TSI108PIC_INT_DAR_RESERVED (0xfffffff0)
-
-/* TSI108PIC_INT_DVPR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_DVPR_VECTOR (0x000000ff)
-#define TSI108PIC_INT_DVPR_PRIORITY (0x000f0000)
-#define TSI108PIC_INT_DVPR_A (0x40000000)
-#define TSI108PIC_INT_DVPR_M (0x80000000)
-#define TSI108PIC_INT_DVPR_RESERVED (0x3ff0ff00)
-
-/* TSI108PIC_INT_DDR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_DDR_SEL_OUT (0x0000000f)
-#define TSI108PIC_INT_DDR_RESERVED (0xfffffff0)
-
-/* TSI108PIC_INT_DMR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_DMR_M (0xffffffff)
-
-/* TSI108PIC_INT_MBR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_MBR_M (0xffffffff)
-
-/* TSI108PIC_INT_MBVPR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_MBVPR_VECTOR (0x000000ff)
-#define TSI108PIC_INT_MBVPR_PRIORITY (0x000f0000)
-#define TSI108PIC_INT_MBVPR_A (0x40000000)
-#define TSI108PIC_INT_MBVPR_M (0x80000000)
-#define TSI108PIC_INT_MBVPR_RESERVED (0x3ff0ff00)
-
-/* TSI108PIC_INT_MBDR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_MBDR_SEL_OUT (0x0000000f)
-#define TSI108PIC_INT_MBDR_RESERVED (0xfffffff0)
-
-/* TSI108PIC_INT_TASKP(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_TASKP_TASKP (0x0000000f)
-#define TSI108PIC_INT_TASKP_RESERVED (0xfffffff0)
-
-/* TSI108PIC_INT_VECTOR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_VECTOR_VECTOR (0x000000ff)
-#define TSI108PIC_INT_VECTOR_LS_VECTOR (0xff000000)
-#define TSI108PIC_INT_VECTOR_RESERVED (0x00ffff00)
-
-/* TSI108PIC_INT_EOI(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_EOI_EOI (0x000000ff)
-#define TSI108PIC_INT_EOI_RESERVED (0xffffff00)
-
-/* TSI108PIC_INT_CSR(X) : Register Bits Masks Definitions */
-#define TSI108PIC_INT_CSR_RESERVED (0xfffffffc)
-
-#define TSI108PIC_INT_CSR_P (1 << 0)
-#define TSI108PIC_INT_CSR_P_LOW (0 << 0)
-#define TSI108PIC_INT_CSR_P_HIGH (1 << 0)
-
-#define TSI108PIC_INT_CSR_S (1 << 1)
-#define TSI108PIC_INT_CSR_S_EDGE (0 << 1)
-#define TSI108PIC_INT_CSR_S_LEVEL (1 << 1)
-
-extern void tsi108_pic_init(u_char * board_init_senses);
-extern void tsi108_pic_reset(void);
-extern void tsi108_pic_set_output(int dest_num, u32 sense, u32 polarity);
-extern int tsi108_pic_source_cfg(int src_num, u32 sense,
- u32 polarity, TSI108_IRQ_MODE mode);
-extern int tsi108_pic_set_vector(int src_num, int vect, int prio);
-extern void tsi108_pic_init_nmi_irq(u_int irq);
-extern void tsi108_pic_hookup_cascade(u_int irq, char *name,
- int (*cascade_fn) (struct pt_regs *));
-extern int tsi108_pic_get_irq(struct pt_regs *regs);
-
-#endif /* __KERNEL__ */
-
-#endif /* _LINUX_TSI108_PIC_H */
^ permalink raw reply
* Re: compact flash driver
From: John Wu @ 2006-05-31 3:18 UTC (permalink / raw)
To: KokHow Teh; +Cc: linuxppc-embedded
In-Reply-To: <OFC57CB4FF.BA62E59F-ON4825717D.0019F306@uk.marconicomms.com>
On Mon, 2006-05-29 at 12:45 +0800, KokHow Teh wrote:
>
> >Dear sir
> >Do you have compact flash card driver supported in u-boot.I need it.If
> ^^^^^^
> You have posted your question to the wrong list.
>
> >you don't have it .Can you tell me how the CF card initialize if you
> >know how to initialize it?
>
> Ask more specific question as to what hardware platform you are using.
> Specifically, which CF controller....
>
>
>
Hardware platform is dm320. Specifically is CF 3.0 memory mode.
^ permalink raw reply
* Re: [PATCH] Provide mechanism for editing builtin command-line in zImage binary.
From: Michal Ostrowski @ 2006-05-30 2:27 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <11489544631499-git-send-email-mostrows@watson.ibm.com>
For reference, below is a shell script I use to edit the command-line
embedded in a zImage.
--
Michal Ostrowski <mostrows@watson.ibm.com>
#!/bin/bash
#
# Copyright (C) 2006 Michal Ostrowski <mostrows@watson.ibm.com>, IBM Corp.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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
usage(){
echo 'set_builtin_cmdline [--cmd <file>] <input_obj> [<output_obj>]'
echo ' Sets the builtin command line embedded in an object file.'
echo
echo ' If <output_obj> is not specified, <input_obj> is modified'
echo ' in place.'
echo ' If --cmd <file> argument is present contents of embedded'
echo ' command line will be copied from <file>, otherwise from stdin.'
exit 1
}
cmd_file=
while case "$#" in 0) break ;; esac
do
case "$1" in
--cmd)
case "$#" in
1)
usage ;;
*)
cmd_file="$2";
shift;;
esac;;
*)
set x "$@"
shift
break ;;
esac
shift
done
if [ "$#" -lt 1 ]; then
echo "No input object specified." ;
usage;
fi
if [ "$#" -gt 2 ]; then
echo "Unrecognized arguments: $@";
usage;
fi
infile=$1
shift;
if [ ! -r "$infile" ] ; then
echo "Can't read '$infile'.";
usage;
fi
if [ "$#" -eq 0 ] ; then
outfile=$infile;
else
outfile=$1;
if ! cp $infile $outfile ; then
echo "Can't create output: '$outfile' $?"
usage;
fi
shift;
fi
offset=$(objdump -h $infile | \
gawk -- '{if($2=="__builtin_cmdline") {print strtonum("0x" $6);}}')
size=$(objdump -h $infile | \
gawk -- '{if($2=="__builtin_cmdline") {print strtonum("0x" $3);}}')
if [ "$cmd_file" ] ; then
[ -r "$cmd_file" ] || (echo "Can't read '$cmd_file'." ; usage);
cmdline=$(cat $cmd_file);
else
cmdline=$(cat);
fi
if [ "x$offset" != "x" ] ; then
if [ "$offset" -ne 0 ] ; then
set -e
# Zero the destination buffer first
exec 2>/dev/null
dd if=/dev/zero of=$outfile bs=1 seek=$offset conv=notrunc count=$size
echo -n "$cmdline" | \
dd of=$outfile bs=1 seek=$offset conv=notrunc count=$size
exit $?
fi
fi
^ permalink raw reply
* [PATCH] Provide mechanism for editing builtin command-line in zImage binary.
From: mostrows @ 2006-05-30 2:01 UTC (permalink / raw)
To: linuxppc-dev
zImage will store the builtin command-line in a dedicated section, allowing
it to be easily identified and edited with user-space tools.
zImage will set /chosen/bootargs to the stored builtin command-line setting,
if /chosen/bootargs is empty (emulating the behavior in prom_init.c).
Use of this mechanism avoids the need to modify firmware or rely on a
bootloader to customize kernel arguments (and overall system
behavior). The command line can be edited as needed when a zImage is
copied to a TFTP staging area for download by firmware.
--
Signed-off-by: Michal Ostrowski <mostrows@watson.ibm.com>
---
arch/powerpc/boot/Makefile | 3 ++-
arch/powerpc/boot/main.c | 28 ++++++++++++++++++++++++++++
arch/powerpc/boot/prom.h | 6 ++++++
3 files changed, 36 insertions(+), 1 deletions(-)
38d6b8581e01886e352b699c978a3a5ac6672622
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 840ae59..d7ba474 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -41,7 +41,8 @@ src-boot += $(zlib)
src-boot := $(addprefix $(obj)/, $(src-boot))
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
-BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
+BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) -I$(O)/include -I$(O)/include2\
+ -D__KERNEL__
quiet_cmd_copy_zlib = COPY $@
cmd_copy_zlib = sed "s@__attribute_used__@@;s@<linux/\([^>]\+\).*@\"\1\"@" $< > $@
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index 816446f..eef25de 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -10,6 +10,9 @@
*/
#include <stdarg.h>
#include <stddef.h>
+#include <linux/autoconf.h>
+#include <asm/setup.h>
+
#include "elf.h"
#include "page.h"
#include "string.h"
@@ -33,6 +36,16 @@ extern char _vmlinux_end[];
extern char _initrd_start[];
extern char _initrd_end[];
+#ifdef CONFIG_CMDLINE
+/* Putting this in a seperate section allows for simple tools to
+ * edit this setting after a build (i.e. as the kernel image is being deployed
+ * for booting.
+ */
+static char builtin_cmdline[COMMAND_LINE_SIZE]
+ __attribute__((section("__builtin_cmdline"))) = CONFIG_CMDLINE;
+#endif
+
+
struct addr_range {
unsigned long addr;
unsigned long size;
@@ -204,6 +217,19 @@ static int is_elf32(void *hdr)
return 1;
}
+void export_cmdline(void* chosen_handle)
+{
+#ifdef CONFIG_CMDLINE
+ int len;
+ char cmdline[COMMAND_LINE_SIZE];
+ len = getprop(chosen_handle, "bootargs", cmdline, sizeof(cmdline));
+ if ((len <= 0 || cmdline[0] == 0) && builtin_cmdline[0]) {
+ setprop(chosen_handle, "bootargs", builtin_cmdline,
+ strlen(builtin_cmdline)+1);
+ }
+#endif /* CONFIG_CMDLINE */
+}
+
void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
{
int len;
@@ -289,6 +315,8 @@ void start(unsigned long a1, unsigned lo
memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size);
}
+ export_cmdline(chosen_handle);
+
/* Skip over the ELF header */
#ifdef DEBUG
printf("... skipping 0x%lx bytes of ELF header\n\r",
diff --git a/arch/powerpc/boot/prom.h b/arch/powerpc/boot/prom.h
index 3e2ddd4..f613092 100644
--- a/arch/powerpc/boot/prom.h
+++ b/arch/powerpc/boot/prom.h
@@ -31,4 +31,10 @@ static inline int getprop(void *phandle,
return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
}
+static inline int setprop(void *phandle, const char *name,
+ void *buf, int buflen)
+{
+ return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
+}
+
#endif /* _PPC_BOOT_PROM_H_ */
--
1.1.4.g0b63-dirty
^ permalink raw reply related
* Re: [RFC/PATCH 0/8] Overhaul of virt IRQ configuration. / Kill ppc64_interrupt_controller.
From: Michal Ostrowski @ 2006-05-29 23:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1148938117.5959.24.camel@localhost.localdomain>
On Tue, 2006-05-30 at 07:28 +1000, Benjamin Herrenschmidt wrote:
> On Mon, 2006-05-29 at 16:41 -0400, Michal Ostrowski wrote:
> > The following set of patches is aimed at killing the
> > ppc64_interrupt_controller global variable, and similarly that various
> > global variables used to tweak the parameters of virtual IRQ re-mapping.
> > Instead each platform can use a single function to configure IRQ
> > re-mapping in "init_early()".
>
> .../...
>
> Hi ! Interesting.. I've start looking at reworking that with a slightly
> different approach though...
>
I'm in total agreement with your assessment of where things should go.
My main motivation here was to kill ppc64_interrupt_controller and to
consolidate our knowledge of the requirements of the different platforms
into a single interface (i.e. virt_irq_config).
As such I see this patch as either a first step, or clean-up along-side,
the changes you're considering.
I did consider at first making more changes than published here; in
particular to address the offsetting issue you and Paul have commented
on.
Current code such as:
virq = virt_irq_create_mapping(irq[0]);
...
np->intrs[intrcount].line = irq_offset_up(virq);
Should be more like:
np->intrs[intrcount].line = virt_irq_create_mapping(irq[0]);
(Where the knowledge regarding all remapping/offsetting is embedded
behind the remapping interfaces. We should kill irq_offset_{up,down}
and replace them with things such as real_irq_to_virt() and
virt_irq_to_real().)
The patches I've sent out were not intended to deal with this, as I
wanted to keep the change set focused and small. However, things similar
to what you've outlined I've been keeping in mind as potential follow-on
work; and I had intended these patches to facilitate that.
--
Michal Ostrowski <mostrows@watson.ibm.com>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox