You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
(12) |
May
(82) |
Jun
(72) |
Jul
(39) |
Aug
(104) |
Sep
(61) |
Oct
(55) |
Nov
(101) |
Dec
(48) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(52) |
Feb
(67) |
Mar
(18) |
Apr
(16) |
May
(33) |
Jun
(12) |
Jul
(102) |
Aug
(168) |
Sep
(65) |
Oct
(60) |
Nov
(43) |
Dec
(121) |
2002 |
Jan
(69) |
Feb
(32) |
Mar
(90) |
Apr
(59) |
May
(45) |
Jun
(43) |
Jul
(33) |
Aug
(21) |
Sep
(11) |
Oct
(20) |
Nov
(26) |
Dec
(3) |
2003 |
Jan
(12) |
Feb
(18) |
Mar
(11) |
Apr
(11) |
May
(41) |
Jun
(76) |
Jul
(77) |
Aug
(15) |
Sep
(38) |
Oct
(56) |
Nov
(19) |
Dec
(39) |
2004 |
Jan
(17) |
Feb
(52) |
Mar
(36) |
Apr
(34) |
May
(48) |
Jun
(85) |
Jul
(38) |
Aug
(42) |
Sep
(41) |
Oct
(77) |
Nov
(27) |
Dec
(19) |
2005 |
Jan
(32) |
Feb
(35) |
Mar
(29) |
Apr
(8) |
May
(7) |
Jun
(31) |
Jul
(46) |
Aug
(93) |
Sep
(65) |
Oct
(85) |
Nov
(219) |
Dec
(47) |
2006 |
Jan
(170) |
Feb
(103) |
Mar
(49) |
Apr
(43) |
May
(45) |
Jun
(29) |
Jul
(77) |
Aug
(82) |
Sep
(43) |
Oct
(45) |
Nov
(26) |
Dec
(85) |
2007 |
Jan
(42) |
Feb
(48) |
Mar
(64) |
Apr
(31) |
May
(88) |
Jun
(53) |
Jul
(175) |
Aug
(212) |
Sep
(91) |
Oct
(103) |
Nov
(110) |
Dec
(5) |
2008 |
Jan
(20) |
Feb
(11) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(5) |
Sep
(3) |
Oct
(12) |
Nov
|
Dec
|
From: Markus B. <sup...@go...> - 2007-08-06 20:47:38
|
Hi, I tried to get earlyprintk running on SH7720 again and this time I was succ= essfull.=20 I don't know why it didn't work last time, because I did the same again. Everything is fine, so far. I was able to fix the error in the SH7720 setup which prevented booting. But, after that I realised that the board setup wasn't called anymore. When earlyprintk is disabled, the first lines of the bootlog are: [ =A0 =A00.000000] Linux version 2.6.23-rc1 (markus@linux-markus) (gcc vers= ion 3.4.6) #9 Fri Aug 3 11:09:01 CEST 2007 [ =A0 =A00.000000] Booting machvec: mpr2 [ =A0 =A00.000000] Magic Panel Release 2 A.2 The third line is from the board setup. After enabling earlyprintk: [ =A0 =A00.000000] Linux version 2.6.23-rc1 (markus@linux-markus) (gcc vers= ion 3.4.6) #8 Mon Aug 6 13:17:37 CEST 2007 [ =A0 =A00.000000] console [sercon0] enabled [ =A0 =A00.000000] Booting machvec: ./ Boot seemed to be quite normal, but LEDs and ethernet obviously didn't work. When I added sh_mv=3Dgeneric to the command line, the only noticeable diffe= rence was the line [ =A0 =A00.000000] Booting machvec: generic When I tried to specify any other string (including the correct mv_name) to= sh_mv=3D booting stopped after=20 [ =A0 =A00.000000] console [sercon0] enabled I added some debug outputs to get_mv_byname in machvec.c to see what strings get compared, but only=20 [ =A0 =A00.000000] ./ [ =A0 =A00.000000] <NULL> Seem to be there Problem occurs with gcc 3.4.6, 4.0.4, 4.1.2, only when earlyprintk is enabl= ed. Running "strings" on vmlinux shows that the board setup is really compiled = in. This are my changes to earlyprintk.c, but I'm really sure, they are not responsible for the problem. Can anybody reproduce this problem on another board? Any hints for fixing this bug? Regards Markus Note: This patch isn't meant for inclusion, but comments are of course wellcome. diff --git a/arch/sh/kernel/early_printk.c b/arch/sh/kernel/early_printk.c index 9833493..a0ff48c 100644 =2D-- a/arch/sh/kernel/early_printk.c +++ b/arch/sh/kernel/early_printk.c @@ -13,6 +13,7 @@ #include <linux/tty.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/delay.h> =20 #ifdef CONFIG_SH_STANDARD_BIOS #include <asm/sh_bios.h> @@ -62,6 +63,11 @@ static struct console bios_console =3D { #include <linux/serial_core.h> #include "../../../drivers/serial/sh-sci.h" =20 +#if defined(CONFIG_CPU_SUBTYPE_SH7720) +#define EPK_SCSMR_VALUE 0x000 +#define EPK_SCBRR_VALUE 0x00C +#endif + static struct uart_port scif_port =3D { .mapbase =3D CONFIG_EARLY_SCIF_CONSOLE_PORT, .membase =3D (char __iomem *)CONFIG_EARLY_SCIF_CONSOLE_PORT, @@ -69,7 +75,7 @@ static struct uart_port scif_port =3D { =20 static void scif_sercon_putc(int c) { =2D while (((sci_in(&scif_port, SCFDR) & 0x1f00 >> 8) =3D=3D 16)) + while (((sci_in(&scif_port, SCFDR) & 0x1f00 >> 8) >=3D 16)) ; =20 sci_out(&scif_port, SCxTDR, c); @@ -105,7 +111,24 @@ static struct console scif_console =3D { .index =3D -1, }; =20 =2D#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) +#if !defined(CONFIG_SH_STANDARD_BIOS) +#if defined(CONFIG_CPU_SUBTYPE_SH7720) +static void scif_sercon_init(char *s) +{ + ctrl_outw(0x0000, PORT_PTCR); + + sci_out(&scif_port, SCSCR, 0x0000 ); /* clear TE and RE */ + sci_out(&scif_port, SCFCR, 0x4006 ); /* reset through TCRST, TFRST, = RFRST */ + sci_out(&scif_port, SCSCR, 0x0000 ); /* select internal clock */ + sci_out(&scif_port, SCSMR, EPK_SCSMR_VALUE ); + sci_out(&scif_port, SCBRR, EPK_SCBRR_VALUE ); + + mdelay(1); + + sci_out(&scif_port, SCFCR, 0x0030 ); /* TTRG=3Db'11 */ + sci_out(&scif_port, SCSCR, 0x0030 ); /* TE, RE */ +} +#elif defined(CONFIG_CPU_SH4) #define DEFAULT_BAUD 115200 /* * Simple SCIF init, primarily aimed at SH7750 and other similar SH-4 @@ -146,7 +169,8 @@ static void scif_sercon_init(char *s) ctrl_outw(0, scif_port.mapbase + 36); ctrl_outw(0x30, scif_port.mapbase + 8); } =2D#endif /* CONFIG_CPU_SH4 && !CONFIG_SH_STANDARD_BIOS */ +#endif /* defined(CONFIG_CPU_SUBTYPE_SH7720) */ +#endif /* !defined(CONFIG_SH_STANDARD_BIOS) */ #endif /* CONFIG_EARLY_SCIF_CONSOLE */ =20 /* @@ -186,7 +210,8 @@ int __init setup_early_printk(char *buf) if (!strncmp(buf, "serial", 6)) { early_console =3D &scif_console; =20 =2D#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_STANDARD_BIOS) +#if (defined(CONFIG_CPU_SH4) || defined(CONFIG_CPU_SUBTYPE_SH7720)) && \ + !defined(CONFIG_SH_STANDARD_BIOS) scif_sercon_init(buf + 6); #endif } |
From: Paul M. <le...@li...> - 2007-08-06 10:36:58
|
On Mon, Aug 06, 2007 at 06:47:14PM +0900, Paul Mundt wrote: > On Mon, Aug 06, 2007 at 06:33:10PM +0900, Magnus Damm wrote: > > I understand that you want to setup your priorities somehow, but I > > think there must exist better and cleaner ways to do it. I know Paul > > was thinking about adding some function to set interrupt priority > > similar to set_irq_type(), but I wonder if it may be better to allow > > the user to select the priorities from sysfs or something. Probably > > not, at least not as a first step. > > > > So if some generic function like set_irq_type() could be used that > > would be great - otherwise I think just adding some intc specific > > function is good enough. So this is what I would prefer something like > > this: > > > > void board_irq_setup() > > { > > /* first register the board specific interrupts */ > > register_intc_controller(&intc_desc); > > > > /* then setup interrupt priorities for this board */ > > set_irq_priority(STNIC_IRQ, 12); > > set_irq_priority(CF_IRQ, 3); > > } > > > > Does that solve what you are want to do? > > > > Speaking about interrupt priorities, the irq code in > > arch/sh/boards/se/770x/irq.c seem to set a priority that is very > > similar to the IRQ value. Do you know anything about this? Is this > > priority value similar by pure coincidence, or is this related to the > > IRL interrupt number? > > > Yes, I was thinking of something like the following. > > This does restrict the range of allowable priorities at request_irq() > time, but if someone has a use case for an explicit priority, > set_irq_prio() can be used for kicking that down to the chip handler. > > I would wager that 99.99999% of all use cases will fit in with > default/high/low priorities, though. If someone has a non-academic use > case that won't fit in this model, I'd be interested in hearing it. > Reworked it a bit: http://marc.info/?l=linux-kernel&m=118639637304482&w=2 |
From: Paul M. <le...@li...> - 2007-08-06 09:48:05
|
On Mon, Aug 06, 2007 at 06:33:10PM +0900, Magnus Damm wrote: > I understand that you want to setup your priorities somehow, but I > think there must exist better and cleaner ways to do it. I know Paul > was thinking about adding some function to set interrupt priority > similar to set_irq_type(), but I wonder if it may be better to allow > the user to select the priorities from sysfs or something. Probably > not, at least not as a first step. > > So if some generic function like set_irq_type() could be used that > would be great - otherwise I think just adding some intc specific > function is good enough. So this is what I would prefer something like > this: > > void board_irq_setup() > { > /* first register the board specific interrupts */ > register_intc_controller(&intc_desc); > > /* then setup interrupt priorities for this board */ > set_irq_priority(STNIC_IRQ, 12); > set_irq_priority(CF_IRQ, 3); > } > > Does that solve what you are want to do? > > Speaking about interrupt priorities, the irq code in > arch/sh/boards/se/770x/irq.c seem to set a priority that is very > similar to the IRQ value. Do you know anything about this? Is this > priority value similar by pure coincidence, or is this related to the > IRL interrupt number? > Yes, I was thinking of something like the following. This does restrict the range of allowable priorities at request_irq() time, but if someone has a use case for an explicit priority, set_irq_prio() can be used for kicking that down to the chip handler. I would wager that 99.99999% of all use cases will fit in with default/high/low priorities, though. If someone has a non-academic use case that won't fit in this model, I'd be interested in hearing it. -- diff --git a/include/linux/irq.h b/include/linux/irq.h index 1695054..1f7578e 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -45,6 +45,11 @@ typedef void fastcall (*irq_flow_handler_t)(unsigned int irq, #define IRQ_TYPE_SENSE_MASK 0x0000000f /* Mask of the above */ #define IRQ_TYPE_PROBE 0x00000010 /* Probing in progress */ +/* IRQ priorities */ +#define IRQ_PRIO_NONE 0x00000000 /* Default priority */ +#define IRQ_PRIO_HIGH 0x00000001 /* High priority */ +#define IRQ_PRIO_LOW 0x00000002 /* Low priority */ + /* Internal flags */ #define IRQ_INPROGRESS 0x00000100 /* IRQ handler active - do not enter! */ #define IRQ_DISABLED 0x00000200 /* IRQ disabled - do not enter! */ @@ -91,6 +96,7 @@ struct msi_desc; * @retrigger: resend an IRQ to the CPU * @set_type: set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ * @set_wake: enable/disable power-management wake-on of an IRQ + * @set_prio: set the priority of an IRQ * * @release: release function solely used by UML * @typename: obsoleted by name, kept as migration helper @@ -113,6 +119,7 @@ struct irq_chip { int (*retrigger)(unsigned int irq); int (*set_type)(unsigned int irq, unsigned int flow_type); int (*set_wake)(unsigned int irq, unsigned int on); + int (*set_prio)(unsigned int irq, unsigned int prio); /* Currently used only by UML, might disappear one day.*/ #ifdef CONFIG_IRQ_RELEASE_METHOD @@ -379,6 +386,7 @@ extern int set_irq_data(unsigned int irq, void *data); extern int set_irq_chip_data(unsigned int irq, void *data); extern int set_irq_type(unsigned int irq, unsigned int type); extern int set_irq_msi(unsigned int irq, struct msi_desc *entry); +extern int set_irq_prio(unsigned int irq, unsigned int prio); #define get_irq_chip(irq) (irq_desc[irq].chip) #define get_irq_chip_data(irq) (irq_desc[irq].chip_data) diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 615ce97..fa7df4d 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -141,6 +141,32 @@ int set_irq_type(unsigned int irq, unsigned int type) EXPORT_SYMBOL(set_irq_type); /** + * set_irq_prio - set the irq priority for an irq + * @irq: irq number + * @prio: interrupt priority - see include/linux/irq.h + */ +int set_irq_prio(unsigned int irq, unsigned int prio) +{ + struct irq_desc *desc; + unsigned long flags; + int ret = -ENXIO; + + if (irq >= NR_IRQS) { + printk(KERN_ERR "Trying to set irq priority for IRQ%d\n", irq); + return -ENODEV; + } + + desc = irq_desc + irq; + if (desc->chip->set_prio) { + spin_lock_irqsave(&desc->lock, flags); + ret = desc->chip->set_prio(irq, prio); + spin_unlock_irqrestore(&desc->lock, flags); + } + return ret; +} +EXPORT_SYMBOL(set_irq_prio); + +/** * set_irq_data - set irq type data for an irq * @irq: Interrupt number * @data: Pointer to interrupt specific data |
From: Magnus D. <mag...@gm...> - 2007-08-06 09:37:39
|
Hi everyone, Thanks for your comments Iwamatsu-san! On 8/4/07, Nobuhiro Iwamatsu <he...@t-...> wrote: > Hi, > > On Mon, 30 Jul 2007 19:38:06 +0900 > Magnus Damm <mag...@gm...> wrote: > > > sh: simplify board specific interrupt code for solution engine 7780 > > > > The new intc code handles IRQ3 and IRQ7 in the cpu specific code already, > > so there is no reason to duplicate that here. > > > > Signed-off-by: Magnus Damm <da...@ig...> > > --- > Thank you for your patch. > > I have some comments. > In mounting your IRQ, the priority level is not change. > (The priority level is not change from 2. ) Uhm, yes - the priorities are lost with this patch. > I thought the interrupt priority level to be to be wanted change from > the setting of the board side. I think we should stop and zoom out a bit here. I believe that adjustable interrupt priorities are a good idea, and so far we've kept them in the board specific code for board specific interrupts. But we may want to setup the priorities for other interrupts too - cpu specific interrupts for instance - and there is no good way to do that now. > For example ... > > diff --git a/arch/sh/boards/se/7780/irq.c b/arch/sh/boards/se/7780/irq.c > index 6bd70da..e412063 100644 > --- a/arch/sh/boards/se/7780/irq.c > +++ b/arch/sh/boards/se/7780/irq.c > @@ -16,11 +16,31 @@ > #include <asm/io.h> > #include <asm/se7780.h> > > +/* > + * FIXME > + * copy from arch/sh/kernel/cpu/sh4a/setup-sh7780.c > + */ > +enum { > + IRQ0 = 16 , IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, > +}; I understand that you want to setup your priorities somehow, but I think there must exist better and cleaner ways to do it. I know Paul was thinking about adding some function to set interrupt priority similar to set_irq_type(), but I wonder if it may be better to allow the user to select the priorities from sysfs or something. Probably not, at least not as a first step. So if some generic function like set_irq_type() could be used that would be great - otherwise I think just adding some intc specific function is good enough. So this is what I would prefer something like this: void board_irq_setup() { /* first register the board specific interrupts */ register_intc_controller(&intc_desc); /* then setup interrupt priorities for this board */ set_irq_priority(STNIC_IRQ, 12); set_irq_priority(CF_IRQ, 3); } Does that solve what you are want to do? Speaking about interrupt priorities, the irq code in arch/sh/boards/se/770x/irq.c seem to set a priority that is very similar to the IRQ value. Do you know anything about this? Is this priority value similar by pure coincidence, or is this related to the IRL interrupt number? Thanks! / magnus |
From: Paul M. <le...@li...> - 2007-08-06 04:48:14
|
Throwing the SH-X3 proto board in to IRQ_MODE_IRL3210 mode results in the following oops: Unable to handle kernel NULL pointer dereference at virtual address 0000000c pc = 8c009ecc *pde = 00000000 Oops: 0000 [#1] Modules linked in: Pid : 1, Comm: swapper PC is at intc_set_sense+0x98/0x148 PC : 8c009ecc SP : 8c64fdf4 SR : 400000f0 TEA : 0000000c Not tainted R0 : 00000000 R1 : 0000000c R2 : 00000000 R3 : 00000000 R4 : 00000000 R5 : 00000001 R6 : 00000000 R7 : 00010000 R8 : 8c2266f8 R9 : 00000004 R10 : 00010000 R11 : 0000000f R12 : 0000001c R13 : 00000000 R14 : 8c64fdf4 MACH: 000002c7 MACL: 000004d0 GBR : 00000000 PR : 8c036118 Call trace: [<8c036118>] setup_irq+0xbc/0x18c [<8c03634a>] request_irq+0x7e/0xb4 [<8c10e8d4>] smc_interrupt+0x0/0x808 ... Disabling the ->set_type() assignment works as expected, so it's just a problem with the sense registers. The smc91x IRQ is 14. |
From: Paul M. <le...@li...> - 2007-08-04 12:51:30
|
On Sat, Aug 04, 2007 at 08:54:36AM +0100, Adrian McMenamin wrote: > On Sat, 2007-08-04 at 12:06 +0900, Paul Mundt wrote: > > On Fri, Aug 03, 2007 at 08:26:17PM +0100, Adrian McMenamin wrote: > > > +static void mach_reboot_fixups(void) > > > +{ > > > + if (mach_is_dreamcast()) { > > > + writel(0x00007611, 0xA05F6890); > > > + } > > > +} > > > + > > Whether it's only the dreamcast or not is irrelevant, why bother adding > > abstraction if you intend to add pointless hacks that completely > > side-steps it? > > > > I don't understand the point you are trying to make. Please explain with > more clarity. What have I completely side stepped? I have followed, > broadly, the same pattern used in i386. Just that there, afaics, they > pick up on various PCI cards as the basis on which to modify the reboot. > You've introduced infrastructure to permit different machine types to provide their own reboot hooks, and instead of actually providing a machine-specific implementation, you've just hacked the native implementation ith machine-type checks. This is conceptually no different from your previous hack of sprinkling Dreamcast hooks in process.c. The entire point of this abstraction is so that you can push what logic you need down in to your board directory and _not_ have to shove this sort of pointless crap in to the common code. > > > diff --git a/include/asm-sh/emergency-restart.h > > > b/include/asm-sh/emergency-restart.h > > > index 108d8c4..d6bec92 100644 > > > --- a/include/asm-sh/emergency-restart.h > > > +++ b/include/asm-sh/emergency-restart.h > > > @@ -1,6 +1,6 @@ > > > -#ifndef _ASM_EMERGENCY_RESTART_H > > > -#define _ASM_EMERGENCY_RESTART_H > > > +#ifndef _ASM_SH_EMERGENCY_RESTART_H > > > +#define _ASM_SH_EMERGENCY_RESTART_H > > > > > > -#include <asm-generic/emergency-restart.h> > > > +extern void machine_emergency_restart(void); > > > > > > -#endif /* _ASM_EMERGENCY_RESTART_H */ > > > +#endif /* _ASM_SH_EMERGENCY_RESTART_H */ > > > > > Pointless. Separating out machine_emergency_restart() buys us nothing, > > leave this alone and just kill it off from the machine_ops entirely. > > You've also ignored my earlier mail where I suggested this and killing > > off some of the other ops we had no use for (as well as consolidating > > machine_crash_shutdown()). I do wish you would read these things and wait > > until there's been a resolution one way or another. > > I haven't ignored it. It was just explained with your customary > clarity :) If there was something you were unclear about, perhaps you should have asked for clarification instead of ignoring it? I didn't think any of these points were terribly difficult to parse. |
From: Adrian M. <ad...@ne...> - 2007-08-04 07:55:04
|
On Sat, 2007-08-04 at 12:06 +0900, Paul Mundt wrote: > On Fri, Aug 03, 2007 at 08:26:17PM +0100, Adrian McMenamin wrote: > > diff --git a/arch/sh/boards/dreamcast/Makefile > > b/arch/sh/boards/dreamcast/Makefile > > index e6fcd3d..7b97546 100644 > > --- a/arch/sh/boards/dreamcast/Makefile > > +++ b/arch/sh/boards/dreamcast/Makefile > > @@ -2,5 +2,5 @@ > > # Makefile for the Sega Dreamcast specific parts of the kernel > > # > > > > -obj-y := setup.o irq.o rtc.o reboot.o > > +obj-y := setup.o irq.o rtc.o > > > > You've created this diff against a bogus kernel. True. My apologies - I missed that. > > > diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile > > index bdb30ba..7ab2359 100644 > > --- a/arch/sh/kernel/Makefile > > +++ b/arch/sh/kernel/Makefile .... > > > > void machine_crash_shutdown(struct pt_regs *regs) > > { > > You've missed machine_crash_shutdown(). > Apologies - though I am a bit puzzled as why the code compiled and linked with the two definitions, but that's not much of an excuse. > > +static void mach_reboot_fixups(void) > > +{ > > + if (mach_is_dreamcast()) { > > + writel(0x00007611, 0xA05F6890); > > + } > > +} > > + > Whether it's only the dreamcast or not is irrelevant, why bother adding > abstraction if you intend to add pointless hacks that completely > side-steps it? > I don't understand the point you are trying to make. Please explain with more clarity. What have I completely side stepped? I have followed, broadly, the same pattern used in i386. Just that there, afaics, they pick up on various PCI cards as the basis on which to modify the reboot. > > diff --git a/include/asm-sh/emergency-restart.h > > b/include/asm-sh/emergency-restart.h > > index 108d8c4..d6bec92 100644 > > --- a/include/asm-sh/emergency-restart.h > > +++ b/include/asm-sh/emergency-restart.h > > @@ -1,6 +1,6 @@ > > -#ifndef _ASM_EMERGENCY_RESTART_H > > -#define _ASM_EMERGENCY_RESTART_H > > +#ifndef _ASM_SH_EMERGENCY_RESTART_H > > +#define _ASM_SH_EMERGENCY_RESTART_H > > > > -#include <asm-generic/emergency-restart.h> > > +extern void machine_emergency_restart(void); > > > > -#endif /* _ASM_EMERGENCY_RESTART_H */ > > +#endif /* _ASM_SH_EMERGENCY_RESTART_H */ > > > Pointless. Separating out machine_emergency_restart() buys us nothing, > leave this alone and just kill it off from the machine_ops entirely. > You've also ignored my earlier mail where I suggested this and killing > off some of the other ops we had no use for (as well as consolidating > machine_crash_shutdown()). I do wish you would read these things and wait > until there's been a resolution one way or another. I haven't ignored it. It was just explained with your customary clarity :) |
From: Paul M. <le...@li...> - 2007-08-04 03:07:13
|
On Fri, Aug 03, 2007 at 08:26:17PM +0100, Adrian McMenamin wrote: > diff --git a/arch/sh/boards/dreamcast/Makefile > b/arch/sh/boards/dreamcast/Makefile > index e6fcd3d..7b97546 100644 > --- a/arch/sh/boards/dreamcast/Makefile > +++ b/arch/sh/boards/dreamcast/Makefile > @@ -2,5 +2,5 @@ > # Makefile for the Sega Dreamcast specific parts of the kernel > # > > -obj-y := setup.o irq.o rtc.o reboot.o > +obj-y := setup.o irq.o rtc.o > You've created this diff against a bogus kernel. > diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile > index bdb30ba..7ab2359 100644 > --- a/arch/sh/kernel/Makefile > +++ b/arch/sh/kernel/Makefile > @@ -5,15 +5,11 @@ > extra-y := head.o init_task.o vmlinux.lds > > obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process.o ptrace.o \ > - semaphore.o setup.o signal.o sys_sh.o syscalls.o \ > + reboot.o semaphore.o setup.o signal.o sys_sh.o syscalls.o \ > time.o topology.o traps.o > > obj-y += cpu/ timers/ > > -ifneq ($(CONFIG_SH_DREAMCAST),y) > - obj-y += reboot.o > -endif > - > obj-$(CONFIG_VSYSCALL) += vsyscall/ > > obj-$(CONFIG_SMP) += smp.o > diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c > index 790ed69..201b370 100644 > --- a/arch/sh/kernel/machine_kexec.c > +++ b/arch/sh/kernel/machine_kexec.c > @@ -29,9 +29,6 @@ extern const unsigned char relocate_new_kernel[]; > extern const unsigned int relocate_new_kernel_size; > extern void *gdb_vbr_vector; > > -void machine_shutdown(void) > -{ > -} > > void machine_crash_shutdown(struct pt_regs *regs) > { You've missed machine_crash_shutdown(). > +static void mach_reboot_fixups(void) > +{ > + if (mach_is_dreamcast()) { > + writel(0x00007611, 0xA05F6890); > + } > +} > + Whether it's only the dreamcast or not is irrelevant, why bother adding abstraction if you intend to add pointless hacks that completely side-steps it? > diff --git a/include/asm-sh/emergency-restart.h > b/include/asm-sh/emergency-restart.h > index 108d8c4..d6bec92 100644 > --- a/include/asm-sh/emergency-restart.h > +++ b/include/asm-sh/emergency-restart.h > @@ -1,6 +1,6 @@ > -#ifndef _ASM_EMERGENCY_RESTART_H > -#define _ASM_EMERGENCY_RESTART_H > +#ifndef _ASM_SH_EMERGENCY_RESTART_H > +#define _ASM_SH_EMERGENCY_RESTART_H > > -#include <asm-generic/emergency-restart.h> > +extern void machine_emergency_restart(void); > > -#endif /* _ASM_EMERGENCY_RESTART_H */ > +#endif /* _ASM_SH_EMERGENCY_RESTART_H */ > Pointless. Separating out machine_emergency_restart() buys us nothing, leave this alone and just kill it off from the machine_ops entirely. You've also ignored my earlier mail where I suggested this and killing off some of the other ops we had no use for (as well as consolidating machine_crash_shutdown()). I do wish you would read these things and wait until there's been a resolution one way or another. |
From: Adrian M. <lkm...@gm...> - 2007-08-03 19:26:29
|
(This code is closely modelled on the i386 machine-ops, though currently the only board specific fixup is for the Dreamcast and so there is not a separate set of mach fixups.) This needs to be tested against a wide range of SH boards and would be good to go in -mm if Paul acks it. Add machine-ops code to the SH code base, allowing board specific reboot and halt code. Currently only Dreamcast specific warm reboot fixup in code. Signed-off by: Adrian McMenamin <ad...@mc...> diff --git a/arch/sh/boards/dreamcast/Makefile b/arch/sh/boards/dreamcast/Makefile index e6fcd3d..7b97546 100644 --- a/arch/sh/boards/dreamcast/Makefile +++ b/arch/sh/boards/dreamcast/Makefile @@ -2,5 +2,5 @@ # Makefile for the Sega Dreamcast specific parts of the kernel # -obj-y := setup.o irq.o rtc.o reboot.o +obj-y := setup.o irq.o rtc.o diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index bdb30ba..7ab2359 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -5,15 +5,11 @@ extra-y := head.o init_task.o vmlinux.lds obj-y := debugtraps.o io.o io_generic.o irq.o machvec.o process.o ptrace.o \ - semaphore.o setup.o signal.o sys_sh.o syscalls.o \ + reboot.o semaphore.o setup.o signal.o sys_sh.o syscalls.o \ time.o topology.o traps.o obj-y += cpu/ timers/ -ifneq ($(CONFIG_SH_DREAMCAST),y) - obj-y += reboot.o -endif - obj-$(CONFIG_VSYSCALL) += vsyscall/ obj-$(CONFIG_SMP) += smp.o diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c index 790ed69..201b370 100644 --- a/arch/sh/kernel/machine_kexec.c +++ b/arch/sh/kernel/machine_kexec.c @@ -29,9 +29,6 @@ extern const unsigned char relocate_new_kernel[]; extern const unsigned int relocate_new_kernel_size; extern void *gdb_vbr_vector; -void machine_shutdown(void) -{ -} void machine_crash_shutdown(struct pt_regs *regs) { diff --git a/arch/sh/kernel/reboot.c b/arch/sh/kernel/reboot.c new file mode 100644 index 0000000..c6247ae --- /dev/null +++ b/arch/sh/kernel/reboot.c @@ -0,0 +1,107 @@ +/* + * linux/arch/sh/kernel/reboot.c + * + * Essentially copied from i386 code + * and process.c + * + * Copyright (C) 1995 Linus Torvalds + * + * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima + * Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC + * Copyright (C) 2002 - 2007 Paul Mundt + * Copyright 2007 Adrian McMenamin + * + * Licensed under the terms of version 2 of GNU GPL + */ + +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/init.h> +#include <asm/io.h> +#include <asm/reboot.h> + +/* + * Power off function, if any + */ +void (*pm_power_off)(void); +EXPORT_SYMBOL(pm_power_off); + +/* fixups for individual machines - + * in i386 this is in a file of its own + * but we only have the Dreamcast for now. + */ + +static void mach_reboot_fixups(void) +{ + if (mach_is_dreamcast()) { + writel(0x00007611, 0xA05F6890); + } +} + +static void native_machine_shutdown(void) +{ +} + +static void native_machine_emergency_restart(void) +{ + mach_reboot_fixups(); + /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */ + asm volatile("ldc %0, sr\n\t" + "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001)); +} + +static void native_machine_restart(char * __unused) +{ + native_machine_shutdown(); + native_machine_emergency_restart(); +} + +static void native_machine_halt(void) +{ + local_irq_disable(); + + while (1) + cpu_sleep(); +} + +static void native_machine_power_off(void) +{ + if (pm_power_off) { + native_machine_shutdown(); + pm_power_off(); + } +} + +struct machine_ops machine_ops = { + .power_off = native_machine_power_off, + .shutdown = native_machine_shutdown, + .emergency_restart = native_machine_emergency_restart, + .restart = native_machine_restart, + .halt = native_machine_halt, +}; + +void machine_power_off(void) +{ + machine_ops.power_off(); +} + +void machine_shutdown(void) +{ + machine_ops.shutdown(); +} + +void machine_emergency_restart(void) +{ + machine_ops.emergency_restart(); +} + +void machine_restart(char *cmd) +{ + machine_ops.restart(cmd); +} + +void machine_halt(void) +{ + machine_ops.halt(); +} diff --git a/include/asm-sh/emergency-restart.h b/include/asm-sh/emergency-restart.h index 108d8c4..d6bec92 100644 --- a/include/asm-sh/emergency-restart.h +++ b/include/asm-sh/emergency-restart.h @@ -1,6 +1,6 @@ -#ifndef _ASM_EMERGENCY_RESTART_H -#define _ASM_EMERGENCY_RESTART_H +#ifndef _ASM_SH_EMERGENCY_RESTART_H +#define _ASM_SH_EMERGENCY_RESTART_H -#include <asm-generic/emergency-restart.h> +extern void machine_emergency_restart(void); -#endif /* _ASM_EMERGENCY_RESTART_H */ +#endif /* _ASM_SH_EMERGENCY_RESTART_H */ |
From: Nobuhiro I. <he...@t-...> - 2007-08-03 15:33:38
|
Hi, On Mon, 30 Jul 2007 19:38:06 +0900 Magnus Damm <mag...@gm...> wrote: > sh: simplify board specific interrupt code for solution engine 7780 > > The new intc code handles IRQ3 and IRQ7 in the cpu specific code already, > so there is no reason to duplicate that here. > > Signed-off-by: Magnus Damm <da...@ig...> > --- Thank you for your patch. I have some comments. In mounting your IRQ, the priority level is not change. (The priority level is not change from 2. ) I thought the interrupt priority level to be to be wanted change from the setting of the board side. For example ... diff --git a/arch/sh/boards/se/7780/irq.c b/arch/sh/boards/se/7780/irq.c index 6bd70da..e412063 100644 --- a/arch/sh/boards/se/7780/irq.c +++ b/arch/sh/boards/se/7780/irq.c @@ -16,11 +16,31 @@ #include <asm/io.h> #include <asm/se7780.h> +/* + * FIXME + * copy from arch/sh/kernel/cpu/sh4a/setup-sh7780.c + */ +enum { + IRQ0 = 16 , IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7, +}; + /* * Initialize IRQ setting */ void __init init_se7780_IRQ(void) { + /* priority level to board */ + static struct intc_prio plat_prio[] = { + INTC_PRIO(IRQ0, 3), + INTC_PRIO(IRQ1, 3), + INTC_PRIO(IRQ2, 3), + INTC_PRIO(IRQ3, 3), + INTC_PRIO(IRQ4, 3), + INTC_PRIO(IRQ5, 3), + INTC_PRIO(IRQ6, 3), + INTC_PRIO(IRQ7, 3), + }; + /* enable all interrupt at FPGA */ ctrl_outw(0, FPGA_INTMSK1); /* mask SM501 interrupt */ @@ -42,5 +62,7 @@ void __init init_se7780_IRQ(void) /* FPGA + 0x0A */ ctrl_outw((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3); - plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-7 */ + /* install handlers for IRQ0-7 */ + plat_irq_setup_pins(IRQ_MODE_IRQ + , plat_prio, sizeof(plat_prio)/sizeof(*plat_prio)); } diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index a4127ec..3ffac0c 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -264,10 +264,15 @@ void __init plat_irq_setup(void) register_intc_controller(&intc_desc); } -void __init plat_irq_setup_pins(int mode) +void __init plat_irq_setup_pins(int mode , struct intc_prio *plat_prio , int plat_size) { + switch (mode) { case IRQ_MODE_IRQ: + if(plat_prio != NULL){ + intc_irq_desc.priorities = plat_prio; + intc_irq_desc.nr_priorities = plat_size; + } register_intc_controller(&intc_irq_desc); break; case IRQ_MODE_IRL7654: diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index a4086ea..0d74f30 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h @@ -95,6 +95,6 @@ void __init plat_irq_setup(void); enum { IRQ_MODE_IRQ, IRQ_MODE_IRQ7654, IRQ_MODE_IRQ3210, IRQ_MODE_IRL7654, IRQ_MODE_IRL3210 }; -void __init plat_irq_setup_pins(int mode); +void __init plat_irq_setup_pins(int mode , struct intc_prio *plat_prio, int plat_size); #endif /* __ASM_SH_HW_IRQ_H */ Thanks, Nobuhiro -- Nobuhiro Iwamatsu he...@t-... iwa...@de... GPG ID : 3170EBE9 |
From: Magnus D. <mag...@gm...> - 2007-08-03 08:02:38
|
On 8/3/07, Paul Mundt <le...@li...> wrote: > On Fri, Aug 03, 2007 at 01:32:58PM +0900, Magnus Damm wrote: > > sh: intc - convert board specific r2d code > > > > This patch converts the board specific interrupt code for r2d to make use of > > intc. While at it we remove CONFIG_RTS7751R2D_REV11 to avoid confusion and > > to support both R2D-1 and R2D-PLUS boards using the same binary. > > > > - Two sets of interrupt tables exist - one for R2D-1 and one for R2D-PLUS. > > - R2D-1 and R2D-PLUS use the same irq constants. > > - R2D-1 has AX88796 support, R2D-PLUS does not hook up that IRQ. > > - R2D-PLUS has KEY support, R2D-1 does not hook up that IRQ. > > - The number and order of IRQ values are disconnected from register bits. > > - Interrupt sources now start from IRQ 100. > > - The machvec demux function converts from irlm IRQ 0-14 to IRQ 100++. > > > > Tested on R2D-1 and R2D-PLUS boards. > > > Hmm.. While it's an interesting approach, not having these as initdata is > worrying. We only require one set of IRL<->IRQ mappings, vector/mask > information, etc. and as these are quite weighty to begin with, we do not > want to be making this an exponential thing when there are board > revisions. I can live with having the tables present and discarding the > unused ones, but not having all of the unused tables resident (you'll > just have to flag them all as initdata and copy out the tables you care > about, as per the version register). The kernel is bloated enough without > adding to it. One side of me agrees with you that this approach doesn't scale and we should be concerned about the memory footprint. Another side thinks that this a development platform and if we use a few kilobytes more memory it's not the end of the world. Especially if it is makes maintaining these boards an easier task. And regarding the scalability - that we can fix that when it becomes a problem. OTOH, I do think you are right that having the tables as initdata would make sense. Maybe converting the intc code to copy out the needed tables would be nice... That way we can mark all intc tables as initdata. Regarding R2D-1 and R2D-PLUS support - after thinking a bit I must say that this is most likely exactly what we should use multiple machvecs for. If we could combine multiple machvecs with a probe() or something that can detect boards, then we could just have two separate boards - one for R2D-1 and one for R2D-PLUS. That would make sense for highlander as well... / magnus |
From: Paul M. <le...@li...> - 2007-08-03 05:34:43
|
On Wed, Aug 01, 2007 at 12:31:42PM +0900, Magnus Damm wrote: > sh: intc - fix IRQ4 and IRQ5 typo on sh3 On Fri, Aug 03, 2007 at 12:53:15AM +0900, Magnus Damm wrote: > sh: intc - remove redundant irq code for sh03, snapgear and titan On Fri, Aug 03, 2007 at 12:58:53AM +0900, Magnus Damm wrote: > sh: intc - remove redundant irq code for shmin On Fri, Aug 03, 2007 at 01:27:59PM +0900, Magnus Damm wrote: > sh: intc - add single bitmap register support On Fri, Aug 03, 2007 at 01:30:01PM +0900, Magnus Damm wrote: > sh: intc - convert voyagergx code On Fri, Aug 03, 2007 at 01:35:31PM +0900, Magnus Damm wrote: > sh: remove intc2 code Queued for 2.6.24, thanks. |
From: Paul M. <le...@li...> - 2007-08-03 05:07:09
|
On Fri, Aug 03, 2007 at 01:32:58PM +0900, Magnus Damm wrote: > sh: intc - convert board specific r2d code > > This patch converts the board specific interrupt code for r2d to make use of > intc. While at it we remove CONFIG_RTS7751R2D_REV11 to avoid confusion and > to support both R2D-1 and R2D-PLUS boards using the same binary. > > - Two sets of interrupt tables exist - one for R2D-1 and one for R2D-PLUS. > - R2D-1 and R2D-PLUS use the same irq constants. > - R2D-1 has AX88796 support, R2D-PLUS does not hook up that IRQ. > - R2D-PLUS has KEY support, R2D-1 does not hook up that IRQ. > - The number and order of IRQ values are disconnected from register bits. > - Interrupt sources now start from IRQ 100. > - The machvec demux function converts from irlm IRQ 0-14 to IRQ 100++. > > Tested on R2D-1 and R2D-PLUS boards. > Hmm.. While it's an interesting approach, not having these as initdata is worrying. We only require one set of IRL<->IRQ mappings, vector/mask information, etc. and as these are quite weighty to begin with, we do not want to be making this an exponential thing when there are board revisions. I can live with having the tables present and discarding the unused ones, but not having all of the unused tables resident (you'll just have to flag them all as initdata and copy out the tables you care about, as per the version register). The kernel is bloated enough without adding to it. |
From: Paul M. <le...@li...> - 2007-08-03 04:57:03
|
On Fri, Aug 03, 2007 at 06:54:31AM +0200, Markus Brunner wrote: > On Friday 03 August 2007, Paul Mundt wrote: > > How about something like this? I'll toss it in the 2.6.23 queue if it's > > fine for you, so rtc-sh doesn't end up being useless on these CPUs in > > 2.6.23 :-) > [snip] > But I don't see where you set the capability for SH4. I guess this was just a > proof of concept and you will add that. > RTC_DEF_CAPABILITIES |
From: Markus B. <sup...@go...> - 2007-08-03 04:50:33
|
On Friday 03 August 2007, Paul Mundt wrote: > How about something like this? I'll toss it in the 2.6.23 queue if it's > fine for you, so rtc-sh doesn't end up being useless on these CPUs in > 2.6.23 :-) Of course it's fine for me. Your solution doesn't need that hidden Kconfig option, so I would also prefer yours. But I don't see where you set the capability for SH4. I guess this was just a proof of concept and you will add that. > > -- > > arch/sh/kernel/cpu/sh3/setup-sh7705.c | 12 ++++++-- > arch/sh/kernel/cpu/sh3/setup-sh7710.c | 10 ++++++ > drivers/rtc/rtc-sh.c | 51 > ++++++++++++++++++++++------------ include/asm-sh/rtc.h | > 6 ++++ > 4 files changed, 58 insertions(+), 21 deletions(-) |
From: Paul M. <pau...@re...> - 2007-08-03 04:43:07
|
On Fri, Aug 03, 2007 at 12:33:06AM -0400, Mike Frysinger wrote: > On Friday 03 August 2007, Paul Mundt wrote: > > In any event, supporting multiple boards is fairly trivial, but you give > > up link-time size savings and push most of that down to freeing of init > > memory. It works out the same in the end, the main factor is how > > constrained you are in kernel size. Some platforms (ie, hppa) also make > > function pointers quite expensive, so there are also performance > > reasons why you may wish to avoid the extra layer of indirection. > > thanks, i'll keep these things in mind ... the reason we dont have multiple > board support is lack of customer demand -- we have yet to find one who said > they wanted/needed this. as soon as one does though, we'll most likely go > down that route (and steal ideas from people like sh who've already done it). I generally use it more for new CPU/board support, it's fairly convenient to be able to switch between board-specific I/O ops and the generic ones. This can save quite a bit of time if you have both PIO and MMIO to contend with, particularly on brain-dead SuperIOs interfaced with a disagreeable-but-fixed buswidth. Though when faced with these things, you would be much better off simply prying the entire SuperIO package off of your board and running far away, or barring that, throwing the board away. |
From: Mike F. <va...@ge...> - 2007-08-03 04:39:59
|
On Thursday 02 August 2007, Adrian McMenamin wrote: > +void machine_emergency_restart(void) > +{ > + =A0 =A0 =A0 =A0machine_ops.emergency_restart(); > +} you used spaces here instead of a tab =2Dmike |
From: Magnus D. <mag...@gm...> - 2007-08-03 04:36:50
|
sh: remove intc2 code There is no point in keeping around the now unused intc2 code. Signed-off-by: Magnus Damm <da...@ig...> --- arch/sh/Kconfig | 3 - arch/sh/kernel/cpu/irq/Makefile | 1 arch/sh/kernel/cpu/irq/intc2.c | 86 --------------------------------------- arch/sh/mm/Kconfig | 1 include/asm-sh/hw_irq.h | 18 -------- 5 files changed, 109 deletions(-) --- 0004/arch/sh/Kconfig +++ work/arch/sh/Kconfig 2007-07-30 16:54:56.000000000 +0900 @@ -181,9 +181,6 @@ config CPU_HAS_MASKREG_IRQ config CPU_HAS_INTC_IRQ bool -config CPU_HAS_INTC2_IRQ - bool - config CPU_HAS_IPR_IRQ bool --- 0001/arch/sh/kernel/cpu/irq/Makefile +++ work/arch/sh/kernel/cpu/irq/Makefile 2007-07-30 16:55:07.000000000 +0900 @@ -6,4 +6,3 @@ obj-y += imask.o obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o obj-$(CONFIG_CPU_HAS_INTC_IRQ) += intc.o -obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o --- 0001/arch/sh/kernel/cpu/irq/intc2.c +++ /dev/null 2007-07-30 10:04:31.554482719 +0900 @@ -1,86 +0,0 @@ -/* - * Interrupt handling for INTC2-based IRQ. - * - * Copyright (C) 2001 David J. Mckay (dav...@st...) - * Copyright (C) 2005, 2006 Paul Mundt (le...@li...) - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * These are the "new Hitachi style" interrupts, as present on the - * Hitachi 7751, the STM ST40 STB1, SH7760, and SH7780. - */ -#include <linux/kernel.h> -#include <linux/interrupt.h> -#include <linux/io.h> -#include <asm/smp.h> - -static inline struct intc2_desc *get_intc2_desc(unsigned int irq) -{ - struct irq_chip *chip = get_irq_chip(irq); - return (void *)((char *)chip - offsetof(struct intc2_desc, chip)); -} - -static void disable_intc2_irq(unsigned int irq) -{ - struct intc2_data *p = get_irq_chip_data(irq); - struct intc2_desc *d = get_intc2_desc(irq); - - ctrl_outl(1 << p->msk_shift, d->msk_base + p->msk_offset + - (hard_smp_processor_id() * 4)); -} - -static void enable_intc2_irq(unsigned int irq) -{ - struct intc2_data *p = get_irq_chip_data(irq); - struct intc2_desc *d = get_intc2_desc(irq); - - ctrl_outl(1 << p->msk_shift, d->mskclr_base + p->msk_offset + - (hard_smp_processor_id() * 4)); -} - -/* - * Setup an INTC2 style interrupt. - * NOTE: Unlike IPR interrupts, parameters are not shifted by this code, - * allowing the use of the numbers straight out of the datasheet. - * For example: - * PIO1 which is INTPRI00[19,16] and INTMSK00[13] - * would be: ^ ^ ^ ^ - * | | | | - * { 84, 0, 16, 0, 13 }, - * - * in the intc2_data table. - */ -void register_intc2_controller(struct intc2_desc *desc) -{ - int i; - - desc->chip.mask = disable_intc2_irq; - desc->chip.unmask = enable_intc2_irq; - desc->chip.mask_ack = disable_intc2_irq; - - for (i = 0; i < desc->nr_irqs; i++) { - unsigned long ipr, flags; - struct intc2_data *p = desc->intc2_data + i; - - disable_irq_nosync(p->irq); - - if (desc->prio_base) { - /* Set the priority level */ - local_irq_save(flags); - - ipr = ctrl_inl(desc->prio_base + p->ipr_offset); - ipr &= ~(0xf << p->ipr_shift); - ipr |= p->priority << p->ipr_shift; - ctrl_outl(ipr, desc->prio_base + p->ipr_offset); - - local_irq_restore(flags); - } - - set_irq_chip_and_handler_name(p->irq, &desc->chip, - handle_level_irq, "level"); - set_irq_chip_data(p->irq, p); - - disable_intc2_irq(p->irq); - } -} --- 0005/arch/sh/mm/Kconfig +++ work/arch/sh/mm/Kconfig 2007-07-30 16:54:50.000000000 +0900 @@ -32,7 +32,6 @@ config CPU_SH4AL_DSP config CPU_SUBTYPE_ST40 bool select CPU_SH4 - select CPU_HAS_INTC2_IRQ config CPU_SHX2 bool --- 0002/include/asm-sh/hw_irq.h +++ work/include/asm-sh/hw_irq.h 2007-07-30 16:55:19.000000000 +0900 @@ -6,24 +6,6 @@ extern atomic_t irq_err_count; -struct intc2_data { - unsigned short irq; - unsigned char ipr_offset, ipr_shift; - unsigned char msk_offset, msk_shift; - unsigned char priority; -}; - -struct intc2_desc { - unsigned long prio_base; - unsigned long msk_base; - unsigned long mskclr_base; - struct intc2_data *intc2_data; - unsigned int nr_irqs; - struct irq_chip chip; -}; - -void register_intc2_controller(struct intc2_desc *); - struct ipr_data { unsigned char irq; unsigned char ipr_idx; /* Index for the IPR registered */ |
From: Magnus D. <mag...@gm...> - 2007-08-03 04:34:16
|
sh: intc - convert board specific r2d code This patch converts the board specific interrupt code for r2d to make use of intc. While at it we remove CONFIG_RTS7751R2D_REV11 to avoid confusion and to support both R2D-1 and R2D-PLUS boards using the same binary. - Two sets of interrupt tables exist - one for R2D-1 and one for R2D-PLUS. - R2D-1 and R2D-PLUS use the same irq constants. - R2D-1 has AX88796 support, R2D-PLUS does not hook up that IRQ. - R2D-PLUS has KEY support, R2D-1 does not hook up that IRQ. - The number and order of IRQ values are disconnected from register bits. - Interrupt sources now start from IRQ 100. - The machvec demux function converts from irlm IRQ 0-14 to IRQ 100++. Tested on R2D-1 and R2D-PLUS boards. Signed-off-by: Magnus Damm <da...@ig...> --- Needs single bitmap register support in intc plus new voyagergx code. arch/sh/Kconfig | 1 arch/sh/boards/renesas/rts7751r2d/Kconfig | 12 -- arch/sh/boards/renesas/rts7751r2d/irq.c | 155 ++++++++++++++++++++--------- arch/sh/boards/renesas/rts7751r2d/setup.c | 8 - arch/sh/drivers/pci/ops-rts7751r2d.c | 8 - include/asm-sh/rts7751r2d.h | 65 +++++------- 6 files changed, 144 insertions(+), 105 deletions(-) --- 0001/arch/sh/Kconfig +++ work/arch/sh/Kconfig 2007-08-02 20:50:10.000000000 +0900 @@ -397,7 +397,6 @@ config SH_LBOX_RE2 endmenu source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" -source "arch/sh/boards/renesas/rts7751r2d/Kconfig" source "arch/sh/boards/renesas/r7780rp/Kconfig" menu "Timer and clock configuration" --- 0001/arch/sh/boards/renesas/rts7751r2d/Kconfig +++ /dev/null 2007-07-30 10:04:31.554482719 +0900 @@ -1,12 +0,0 @@ -if SH_RTS7751R2D - -menu "RTS7751R2D options" - -config RTS7751R2D_REV11 - bool "RTS7751R2D Rev. 1.1 board support" - help - Selecting this option will support version rev. 1.1. -endmenu - -endif - --- 0005/arch/sh/boards/renesas/rts7751r2d/irq.c +++ work/arch/sh/boards/renesas/rts7751r2d/irq.c 2007-08-02 20:50:10.000000000 +0900 @@ -16,67 +16,128 @@ #include <asm/voyagergx.h> #include <asm/rts7751r2d.h> -#if defined(CONFIG_RTS7751R2D_REV11) -static int mask_pos[] = {11, 9, 8, 12, 10, 6, 5, 4, 7, 14, 13, 0, 0, 0, 0}; -#else -static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0}; -#endif +#define R2D_NR_IRL 13 -static void enable_rts7751r2d_irq(unsigned int irq) -{ - /* Set priority in IPR back to original value */ - ctrl_outw(ctrl_inw(IRLCNTR1) | (1 << mask_pos[irq]), IRLCNTR1); -} +enum { + UNUSED = 0, -static void disable_rts7751r2d_irq(unsigned int irq) -{ - /* Set the priority in IPR to 0 */ - ctrl_outw(ctrl_inw(IRLCNTR1) & (0xffff ^ (1 << mask_pos[irq])), - IRLCNTR1); -} + /* board specific interrupt sources (R2D-1 and R2D-PLUS) */ + EXT, /* EXT_INT0-3 */ + RTC_T, RTC_A, /* Real Time Clock */ + AX88796, /* Ethernet controller (R2D-1 board) */ + KEY, /* Key input (R2D-PLUS board) */ + SDCARD, /* SD Card */ + CF_CD, CF_IDE, /* CF Card Detect + CF IDE */ + SM501, /* SM501 aka Voyager */ + PCI_INTD_RTL8139, /* Ethernet controller */ + PCI_INTC_PCI1520, /* Cardbus/PCMCIA bridge */ + PCI_INTB_RTL8139, /* Ethernet controller with HUB (R2D-PLUS board) */ + PCI_INTB_SLOT, /* PCI Slot 3.3v (R2D-1 board) */ + PCI_INTA_SLOT, /* PCI Slot 3.3v */ + TP, /* Touch Panel */ +}; + +/* Vectors for R2D-1 */ +static struct intc_vect vectors_r2d_1[] = { + INTC_IRQ(EXT, IRQ_EXT), + INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A), + INTC_IRQ(AX88796, IRQ_AX88796), INTC_IRQ(SDCARD, IRQ_SDCARD), + INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE), /* ng */ + INTC_IRQ(SM501, IRQ_VOYAGER), + INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD), + INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC), + INTC_IRQ(PCI_INTB_SLOT, IRQ_PCI_INTB), + INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA), + INTC_IRQ(TP, IRQ_TP), +}; + +/* IRLMSK mask register layout for R2D-1 */ +static struct intc_mask_reg mask_registers_r2d_1[] = { + { 0xa4000000, 1, 16, /* IRLMSK */ + { TP, PCI_INTA_SLOT, PCI_INTB_SLOT, + PCI_INTC_PCI1520, PCI_INTD_RTL8139, + SM501, CF_IDE, CF_CD, SDCARD, AX88796, + RTC_A, RTC_T, 0, 0, 0, EXT } }, +}; + +/* IRLn to IRQ table for R2D-1 */ +static unsigned char irl2irq_r2d_1[R2D_NR_IRL] = { + IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC, + IRQ_VOYAGER, IRQ_AX88796, IRQ_RTC_A, IRQ_RTC_T, + IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT, + IRQ_TP, +}; + +static DECLARE_INTC_DESC(intc_desc_r2d_1, "r2d-1", vectors_r2d_1, + NULL, NULL, mask_registers_r2d_1, NULL, NULL); + +/* Vectors for R2D-PLUS */ +static struct intc_vect vectors_r2d_plus[] = { + INTC_IRQ(EXT, IRQ_EXT), + INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A), + INTC_IRQ(KEY, IRQ_KEY), INTC_IRQ(SDCARD, IRQ_SDCARD), + INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE), + INTC_IRQ(SM501, IRQ_VOYAGER), + INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD), + INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC), + INTC_IRQ(PCI_INTB_RTL8139, IRQ_PCI_INTB), + INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA), + INTC_IRQ(TP, IRQ_TP), +}; + +/* IRLMSK mask register layout for R2D-PLUS */ +static struct intc_mask_reg mask_registers_r2d_plus[] = { + { 0xa4000000, 1, 16, /* IRLMSK */ + { TP, PCI_INTA_SLOT, PCI_INTB_RTL8139, + PCI_INTC_PCI1520, PCI_INTD_RTL8139, + SM501, CF_IDE, CF_CD, SDCARD, KEY, + RTC_A, RTC_T, 0, 0, 0, EXT } }, +}; + +/* IRLn to IRQ table for R2D-PLUS */ +static unsigned char irl2irq_r2d_plus[R2D_NR_IRL] = { + IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC, + IRQ_VOYAGER, IRQ_KEY, IRQ_RTC_A, IRQ_RTC_T, + IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT, + IRQ_TP, +}; + +static DECLARE_INTC_DESC(intc_desc_r2d_plus, "r2d-plus", vectors_r2d_plus, + NULL, NULL, mask_registers_r2d_plus, NULL, NULL); + +static unsigned char *irl2irq; int rts7751r2d_irq_demux(int irq) { - return irq; -} + if (!irl2irq || irq >= R2D_NR_IRL) + return irq; -static struct irq_chip rts7751r2d_irq_chip __read_mostly = { - .name = "rts7751r2d", - .mask = disable_rts7751r2d_irq, - .unmask = enable_rts7751r2d_irq, - .mask_ack = disable_rts7751r2d_irq, -}; + return irl2irq[irq]; +} /* * Initialize IRQ setting */ void __init init_rts7751r2d_IRQ(void) { - int i; + struct intc_desc *d; - /* IRL0=KEY Input - * IRL1=Ethernet - * IRL2=CF Card - * IRL3=CF Card Insert - * IRL4=PCMCIA - * IRL5=VOYAGER - * IRL6=RTC Alarm - * IRL7=RTC Timer - * IRL8=SD Card - * IRL9=PCI Slot #1 - * IRL10=PCI Slot #2 - * IRL11=Extention #0 - * IRL12=Extention #1 - * IRL13=Extention #2 - * IRL14=Extention #3 - */ - - for (i=0; i<15; i++) { - disable_irq_nosync(i); - set_irq_chip_and_handler_name(i, &rts7751r2d_irq_chip, - handle_level_irq, "level"); - enable_rts7751r2d_irq(i); + switch (ctrl_inw(PA_BVERREG)) { + case 0x10: + printk(KERN_INFO "Using R2D-PLUS interrupt controller.\n"); + d = &intc_desc_r2d_plus; + irl2irq = irl2irq_r2d_plus; + break; + + case 0x11: + printk(KERN_INFO "Using R2D-1 interrupt controller.\n"); + d = &intc_desc_r2d_1; + irl2irq = irl2irq_r2d_1; + break; + default: + return; } + register_intc_controller(d); setup_voyagergx_irq(); } --- 0005/arch/sh/boards/renesas/rts7751r2d/setup.c +++ work/arch/sh/boards/renesas/rts7751r2d/setup.c 2007-08-02 20:50:10.000000000 +0900 @@ -54,11 +54,7 @@ static struct resource cf_ide_resources[ .flags = IORESOURCE_MEM, }, [2] = { -#ifdef CONFIG_RTS7751R2D_REV11 - .start = 1, -#else - .start = 2, -#endif + .start = IRQ_CF_IDE, .flags = IORESOURCE_IRQ, }, }; @@ -147,7 +143,7 @@ static int __init rts7751r2d_devices_set { int ret; - if (ctrl_inw(PA_BVERREG) == 0x10) { /* only working on R2D-PLUS */ + if (ctrl_inw(PA_BVERREG) == 0x10) { /* R2D-PLUS */ ret = platform_device_register(&cf_ide_device); if (ret) return ret; --- 0001/arch/sh/drivers/pci/ops-rts7751r2d.c +++ work/arch/sh/drivers/pci/ops-rts7751r2d.c 2007-08-02 20:50:10.000000000 +0900 @@ -19,10 +19,10 @@ #include "pci-sh4.h" static u8 rts7751r2d_irq_tab[] __initdata = { - IRQ_PCISLOT1, - IRQ_PCISLOT2, - IRQ_PCMCIA, - IRQ_PCIETH, + IRQ_PCI_INTA, + IRQ_PCI_INTB, + IRQ_PCI_INTC, + IRQ_PCI_INTD, }; int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) --- 0002/include/asm-sh/rts7751r2d.h +++ work/include/asm-sh/rts7751r2d.h 2007-08-02 20:50:10.000000000 +0900 @@ -9,7 +9,7 @@ * Renesas Technology Sales RTS7751R2D support */ -/* Box specific addresses. */ +/* Board specific addresses. */ #define PA_BCR 0xa4000000 /* FPGA */ #define PA_IRLMON 0xa4000002 /* Interrupt Status control */ @@ -20,19 +20,19 @@ #define PA_RTCCE 0xa400000c /* RTC(9701) Enable control */ #define PA_PCICD 0xa400000e /* PCI Extention detect control */ #define PA_VOYAGERRTS 0xa4000020 /* VOYAGER Reset control */ -#if defined(CONFIG_RTS7751R2D_REV11) -#define PA_AXRST 0xa4000022 /* AX_LAN Reset control */ -#define PA_CFRST 0xa4000024 /* CF Reset control */ -#define PA_ADMRTS 0xa4000026 /* SD Reset control */ -#define PA_EXTRST 0xa4000028 /* Extention Reset control */ -#define PA_CFCDINTCLR 0xa400002a /* CF Insert Interrupt clear */ -#else -#define PA_CFRST 0xa4000022 /* CF Reset control */ -#define PA_ADMRTS 0xa4000024 /* SD Reset control */ -#define PA_EXTRST 0xa4000026 /* Extention Reset control */ -#define PA_CFCDINTCLR 0xa4000028 /* CF Insert Interrupt clear */ -#define PA_KEYCTLCLR 0xa400002a /* Key Interrupt clear */ -#endif + +#define PA_R2D1_AXRST 0xa4000022 /* AX_LAN Reset control */ +#define PA_R2D1_CFRST 0xa4000024 /* CF Reset control */ +#define PA_R2D1_ADMRTS 0xa4000026 /* SD Reset control */ +#define PA_R2D1_EXTRST 0xa4000028 /* Extention Reset control */ +#define PA_R2D1_CFCDINTCLR 0xa400002a /* CF Insert Interrupt clear */ + +#define PA_R2DPLUS_CFRST 0xa4000022 /* CF Reset control */ +#define PA_R2DPLUS_ADMRTS 0xa4000024 /* SD Reset control */ +#define PA_R2DPLUS_EXTRST 0xa4000026 /* Extention Reset control */ +#define PA_R2DPLUS_CFCDINTCLR 0xa4000028 /* CF Insert Interrupt clear */ +#define PA_R2DPLUS_KEYCTLCLR 0xa400002a /* Key Interrupt clear */ + #define PA_POWOFF 0xa4000030 /* Board Power OFF control */ #define PA_VERREG 0xa4000032 /* FPGA Version Register */ #define PA_INPORT 0xa4000034 /* KEY Input Port control */ @@ -46,27 +46,22 @@ #define IRLCNTR1 (PA_BCR + 0) /* Interrupt Control Register1 */ -#if defined(CONFIG_RTS7751R2D_REV11) -#define IRQ_PCIETH 0 /* PCI Ethernet IRQ */ -#define IRQ_CFCARD 1 /* CF Card IRQ */ -#define IRQ_CFINST 2 /* CF Card Insert IRQ */ -#define IRQ_PCMCIA 3 /* PCMCIA IRQ */ -#define IRQ_VOYAGER 4 /* VOYAGER IRQ */ -#define IRQ_ONETH 5 /* On board Ethernet IRQ */ -#else -#define IRQ_KEYIN 0 /* Key Input IRQ */ -#define IRQ_PCIETH 1 /* PCI Ethernet IRQ */ -#define IRQ_CFCARD 2 /* CF Card IRQ */ -#define IRQ_CFINST 3 /* CF Card Insert IRQ */ -#define IRQ_PCMCIA 4 /* PCMCIA IRQ */ -#define IRQ_VOYAGER 5 /* VOYAGER IRQ */ -#endif -#define IRQ_RTCALM 6 /* RTC Alarm IRQ */ -#define IRQ_RTCTIME 7 /* RTC Timer IRQ */ -#define IRQ_SDCARD 8 /* SD Card IRQ */ -#define IRQ_PCISLOT1 9 /* PCI Slot #1 IRQ */ -#define IRQ_PCISLOT2 10 /* PCI Slot #2 IRQ */ -#define IRQ_EXTENTION 11 /* EXTn IRQ */ +#define R2D_FPGA_IRQ_BASE 100 + +#define IRQ_VOYAGER (R2D_FPGA_IRQ_BASE + 0) +#define IRQ_EXT (R2D_FPGA_IRQ_BASE + 1) +#define IRQ_TP (R2D_FPGA_IRQ_BASE + 2) +#define IRQ_RTC_T (R2D_FPGA_IRQ_BASE + 3) +#define IRQ_RTC_A (R2D_FPGA_IRQ_BASE + 4) +#define IRQ_SDCARD (R2D_FPGA_IRQ_BASE + 5) +#define IRQ_CF_CD (R2D_FPGA_IRQ_BASE + 6) +#define IRQ_CF_IDE (R2D_FPGA_IRQ_BASE + 7) +#define IRQ_AX88796 (R2D_FPGA_IRQ_BASE + 8) +#define IRQ_KEY (R2D_FPGA_IRQ_BASE + 9) +#define IRQ_PCI_INTA (R2D_FPGA_IRQ_BASE + 10) +#define IRQ_PCI_INTB (R2D_FPGA_IRQ_BASE + 11) +#define IRQ_PCI_INTC (R2D_FPGA_IRQ_BASE + 12) +#define IRQ_PCI_INTD (R2D_FPGA_IRQ_BASE + 13) /* arch/sh/boards/renesas/rts7751r2d/irq.c */ void init_rts7751r2d_IRQ(void); |
From: Mike F. <va...@ge...> - 2007-08-03 04:32:36
|
On Friday 03 August 2007, Paul Mundt wrote: > While it's not really a problem these days, old versions of GCC used to > have some problems with the attribute -- hence the comment above the > cond_syscall() definition (asm/unistd.h), which has since been copied > verbatim by almost every other platform, sh and blackfin included ;-) when i see things like that i blame the consultants who started the Blackfi= n=20 port ;) > Hypervisors like to overload these as well, Xen has its own set of > machine_ops on i386 for example. So unless you forsee caring about > virtualization or supporting multiple machines, there's probably not a > lot of gain in doing this for Blackfin. > > In any event, supporting multiple boards is fairly trivial, but you give > up link-time size savings and push most of that down to freeing of init > memory. It works out the same in the end, the main factor is how > constrained you are in kernel size. Some platforms (ie, hppa) also make > function pointers quite expensive, so there are also performance > reasons why you may wish to avoid the extra layer of indirection. thanks, i'll keep these things in mind ... the reason we dont have multiple= =20 board support is lack of customer demand -- we have yet to find one who sai= d=20 they wanted/needed this. as soon as one does though, we'll most likely go= =20 down that route (and steal ideas from people like sh who've already done it= ). =2Dmike |
From: Magnus D. <mag...@gm...> - 2007-08-03 04:31:17
|
sh: intc - convert voyagergx code This patch converts the sh-specific voyagergx interrupt code to make use of intc. A lot of "interesting" old cruft gets replaced with intc tables and some simple demux code. - All interrupt sources in the sm501 data sheet are now in the header file. - The number and order of IRQ values are disconnected from register bits. - Interrupt sources now start from IRQ 200. - set_irq_chained_handler() is now used to hook up the demux function. In the future it would probably make sense to move the interrupt demuxer into into the mfd driver, but this is probably a nice step in the right direction until that happens. Tested on a R2D-1 board using the serial port hooked up to the sm501. Signed-off-by: Magnus Damm <da...@ig...> --- Needs single bitmap register support in intc. arch/sh/boards/renesas/rts7751r2d/irq.c | 6 arch/sh/boards/renesas/rts7751r2d/setup.c | 5 arch/sh/cchips/voyagergx/irq.c | 184 ++++++++--------------------- include/asm-sh/voyagergx.h | 39 +++++- 4 files changed, 93 insertions(+), 141 deletions(-) --- 0001/arch/sh/boards/renesas/rts7751r2d/irq.c +++ work/arch/sh/boards/renesas/rts7751r2d/irq.c 2007-08-02 19:11:29.000000000 +0900 @@ -13,6 +13,7 @@ #include <linux/irq.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <asm/voyagergx.h> #include <asm/rts7751r2d.h> #if defined(CONFIG_RTS7751R2D_REV11) @@ -21,9 +22,6 @@ static int mask_pos[] = {11, 9, 8, 12, 1 static int mask_pos[] = {6, 11, 9, 8, 12, 10, 5, 4, 7, 14, 13, 0, 0, 0, 0}; #endif -extern int voyagergx_irq_demux(int irq); -extern void setup_voyagergx_irq(void); - static void enable_rts7751r2d_irq(unsigned int irq) { /* Set priority in IPR back to original value */ @@ -39,7 +37,7 @@ static void disable_rts7751r2d_irq(unsig int rts7751r2d_irq_demux(int irq) { - return voyagergx_irq_demux(irq); + return irq; } static struct irq_chip rts7751r2d_irq_chip __read_mostly = { --- 0001/arch/sh/boards/renesas/rts7751r2d/setup.c +++ work/arch/sh/boards/renesas/rts7751r2d/setup.c 2007-08-02 19:10:16.000000000 +0900 @@ -82,7 +82,7 @@ static struct plat_serial8250_port uart_ .membase = (void __iomem *)VOYAGER_UART_BASE, .mapbase = VOYAGER_UART_BASE, .iotype = UPIO_MEM, - .irq = VOYAGER_UART0_IRQ, + .irq = IRQ_SM501_U0, .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, .regshift = 2, .uartclk = (9600 * 16), @@ -125,7 +125,7 @@ static struct resource sm501_resources[] .flags = IORESOURCE_MEM, }, [2] = { - .start = 32, + .start = IRQ_SM501_CV, .flags = IORESOURCE_IRQ, }, }; @@ -180,7 +180,6 @@ static void __init rts7751r2d_setup(char static struct sh_machine_vector mv_rts7751r2d __initmv = { .mv_name = "RTS7751R2D", .mv_setup = rts7751r2d_setup, - .mv_nr_irqs = 72, .mv_init_irq = init_rts7751r2d_IRQ, .mv_irq_demux = rts7751r2d_irq_demux, --- 0001/arch/sh/cchips/voyagergx/irq.c +++ work/arch/sh/cchips/voyagergx/irq.c 2007-08-02 19:10:16.000000000 +0900 @@ -23,149 +23,79 @@ #include <asm/voyagergx.h> #include <asm/rts7751r2d.h> -static void disable_voyagergx_irq(unsigned int irq) -{ - unsigned long val; - unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); - - pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); - val = readl((void __iomem *)VOYAGER_INT_MASK); - val &= ~mask; - writel(val, (void __iomem *)VOYAGER_INT_MASK); -} - -static void enable_voyagergx_irq(unsigned int irq) -{ - unsigned long val; - unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); - - pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); - val = readl((void __iomem *)VOYAGER_INT_MASK); - val |= mask; - writel(val, (void __iomem *)VOYAGER_INT_MASK); -} - -static void mask_and_ack_voyagergx(unsigned int irq) -{ - disable_voyagergx_irq(irq); -} +enum { + UNUSED = 0, -static void end_voyagergx_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_voyagergx_irq(irq); -} - -static unsigned int startup_voyagergx_irq(unsigned int irq) -{ - enable_voyagergx_irq(irq); - return 0; -} - -static void shutdown_voyagergx_irq(unsigned int irq) -{ - disable_voyagergx_irq(irq); -} + /* voyager specific interrupt sources */ + UP, G54, G53, G52, G51, G50, G49, G48, + I2C, PW, DMA, PCI, I2S, AC, US, + U1, U0, CV, MC, S1, S0, + UH, TWOD, ZD, PV, CI, +}; -static struct hw_interrupt_type voyagergx_irq_type = { - .typename = "VOYAGERGX-IRQ", - .startup = startup_voyagergx_irq, - .shutdown = shutdown_voyagergx_irq, - .enable = enable_voyagergx_irq, - .disable = disable_voyagergx_irq, - .ack = mask_and_ack_voyagergx, - .end = end_voyagergx_irq, +static struct intc_vect vectors[] = { + INTC_IRQ(UP, IRQ_SM501_UP), INTC_IRQ(G54, IRQ_SM501_G54), + INTC_IRQ(G53, IRQ_SM501_G53), INTC_IRQ(G52, IRQ_SM501_G52), + INTC_IRQ(G51, IRQ_SM501_G51), INTC_IRQ(G50, IRQ_SM501_G50), + INTC_IRQ(G49, IRQ_SM501_G49), INTC_IRQ(G48, IRQ_SM501_G48), + INTC_IRQ(I2C, IRQ_SM501_I2C), INTC_IRQ(PW, IRQ_SM501_PW), + INTC_IRQ(DMA, IRQ_SM501_DMA), INTC_IRQ(PCI, IRQ_SM501_PCI), + INTC_IRQ(I2S, IRQ_SM501_I2S), INTC_IRQ(AC, IRQ_SM501_AC), + INTC_IRQ(US, IRQ_SM501_US), INTC_IRQ(U1, IRQ_SM501_U1), + INTC_IRQ(U0, IRQ_SM501_U0), INTC_IRQ(CV, IRQ_SM501_CV), + INTC_IRQ(MC, IRQ_SM501_MC), INTC_IRQ(S1, IRQ_SM501_S1), + INTC_IRQ(S0, IRQ_SM501_S0), INTC_IRQ(UH, IRQ_SM501_UH), + INTC_IRQ(TWOD, IRQ_SM501_2D), INTC_IRQ(ZD, IRQ_SM501_ZD), + INTC_IRQ(PV, IRQ_SM501_PV), INTC_IRQ(CI, IRQ_SM501_CI), }; -static irqreturn_t voyagergx_interrupt(int irq, void *dev_id) -{ - printk(KERN_INFO - "VoyagerGX: spurious interrupt, status: 0x%x\n", - (unsigned int)readl((void __iomem *)INT_STATUS)); - return IRQ_HANDLED; -} +static struct intc_mask_reg mask_registers[] = { + { VOYAGER_INT_MASK, 1, 32, /* "Interrupt Mask", MMIO_base + 0x30 */ + { UP, G54, G53, G52, G51, G50, G49, G48, + I2C, PW, 0, DMA, PCI, I2S, AC, US, + 0, 0, U1, U0, CV, MC, S1, S0, + 0, UH, 0, 0, TWOD, ZD, PV, CI } }, +}; -static struct { - int (*func)(int, void *); - void *dev; -} voyagergx_demux[VOYAGER_IRQ_NUM]; +static DECLARE_INTC_DESC(intc_desc, "voyagergx", vectors, + NULL, NULL, mask_registers, NULL, NULL); -void voyagergx_register_irq_demux(int irq, - int (*demux)(int irq, void *dev), void *dev) -{ - voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = demux; - voyagergx_demux[irq - VOYAGER_IRQ_BASE].dev = dev; -} - -void voyagergx_unregister_irq_demux(int irq) -{ - voyagergx_demux[irq - VOYAGER_IRQ_BASE].func = 0; -} +static unsigned int voyagergx_stat2irq[32] = { + IRQ_SM501_CI, IRQ_SM501_PV, IRQ_SM501_ZD, IRQ_SM501_2D, + 0, 0, IRQ_SM501_UH, 0, + IRQ_SM501_S0, IRQ_SM501_S1, IRQ_SM501_MC, IRQ_SM501_CV, + IRQ_SM501_U0, IRQ_SM501_U1, 0, 0, + IRQ_SM501_US, IRQ_SM501_AC, IRQ_SM501_I2S, IRQ_SM501_PCI, + IRQ_SM501_DMA, 0, IRQ_SM501_PW, IRQ_SM501_I2C, + IRQ_SM501_G48, IRQ_SM501_G49, IRQ_SM501_G50, IRQ_SM501_G51, + IRQ_SM501_G52, IRQ_SM501_G53, IRQ_SM501_G54, IRQ_SM501_UP +}; -int voyagergx_irq_demux(int irq) +static void voyagergx_irq_demux(unsigned int irq, struct irq_desc *desc) { - - if (irq == IRQ_VOYAGER ) { - unsigned long i = 0, bit __attribute__ ((unused)); - unsigned long val = readl((void __iomem *)INT_STATUS); - - if (val & (1 << 1)) - i = 1; - else if (val & (1 << 2)) - i = 2; - else if (val & (1 << 6)) - i = 6; - else if (val & (1 << 10)) - i = 10; - else if (val & (1 << 11)) - i = 11; - else if (val & (1 << 12)) - i = 12; - else if (val & (1 << 17)) - i = 17; - else - printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val); - pr_debug("voyagergx_irq_demux %ld \n", i); - if (i < VOYAGER_IRQ_NUM) { - irq = VOYAGER_IRQ_BASE + i; - if (voyagergx_demux[i].func != 0) - irq = voyagergx_demux[i].func(irq, - voyagergx_demux[i].dev); + unsigned long intv = ctrl_inl(INT_STATUS); + struct irq_desc *ext_desc; + unsigned int ext_irq; + unsigned int k = 0; + + while (intv) { + ext_irq = voyagergx_stat2irq[k]; + if (ext_irq && (intv & 1)) { + ext_desc = irq_desc + ext_irq; + handle_level_irq(ext_irq, ext_desc); } + intv >>= 1; + k++; } - return irq; } -static struct irqaction irq0 = { - .name = "voyagergx", - .handler = voyagergx_interrupt, - .flags = IRQF_DISABLED, - .mask = CPU_MASK_NONE, -}; - void __init setup_voyagergx_irq(void) { - int i, flag; - - printk(KERN_INFO "VoyagerGX configured at 0x%x on irq %d(mapped into %d to %d)\n", - VOYAGER_BASE, + printk(KERN_INFO "VoyagerGX on irq %d (mapped into %d to %d)\n", IRQ_VOYAGER, VOYAGER_IRQ_BASE, VOYAGER_IRQ_BASE + VOYAGER_IRQ_NUM - 1); - for (i=0; i<VOYAGER_IRQ_NUM; i++) { - flag = 0; - switch (VOYAGER_IRQ_BASE + i) { - case VOYAGER_USBH_IRQ: - case VOYAGER_8051_IRQ: - case VOYAGER_UART0_IRQ: - case VOYAGER_UART1_IRQ: - case VOYAGER_AC97_IRQ: - flag = 1; - } - if (flag == 1) - irq_desc[VOYAGER_IRQ_BASE + i].chip = &voyagergx_irq_type; - } - - setup_irq(IRQ_VOYAGER, &irq0); + register_intc_controller(&intc_desc); + set_irq_chained_handler(IRQ_VOYAGER, voyagergx_irq_demux); } --- 0001/include/asm-sh/voyagergx.h +++ work/include/asm-sh/voyagergx.h 2007-08-02 19:10:16.000000000 +0900 @@ -27,13 +27,35 @@ #define VOYAGER_UART_BASE (0x30000 + VOYAGER_BASE) #define VOYAGER_AC97_BASE (0xa0000 + VOYAGER_BASE) -#define VOYAGER_IRQ_NUM 32 -#define VOYAGER_IRQ_BASE 50 -#define VOYAGER_USBH_IRQ VOYAGER_IRQ_BASE + 6 -#define VOYAGER_8051_IRQ VOYAGER_IRQ_BASE + 10 -#define VOYAGER_UART0_IRQ VOYAGER_IRQ_BASE + 12 -#define VOYAGER_UART1_IRQ VOYAGER_IRQ_BASE + 13 -#define VOYAGER_AC97_IRQ VOYAGER_IRQ_BASE + 17 +#define VOYAGER_IRQ_NUM 26 +#define VOYAGER_IRQ_BASE 200 + +#define IRQ_SM501_UP (VOYAGER_IRQ_BASE + 0) +#define IRQ_SM501_G54 (VOYAGER_IRQ_BASE + 1) +#define IRQ_SM501_G53 (VOYAGER_IRQ_BASE + 2) +#define IRQ_SM501_G52 (VOYAGER_IRQ_BASE + 3) +#define IRQ_SM501_G51 (VOYAGER_IRQ_BASE + 4) +#define IRQ_SM501_G50 (VOYAGER_IRQ_BASE + 5) +#define IRQ_SM501_G49 (VOYAGER_IRQ_BASE + 6) +#define IRQ_SM501_G48 (VOYAGER_IRQ_BASE + 7) +#define IRQ_SM501_I2C (VOYAGER_IRQ_BASE + 8) +#define IRQ_SM501_PW (VOYAGER_IRQ_BASE + 9) +#define IRQ_SM501_DMA (VOYAGER_IRQ_BASE + 10) +#define IRQ_SM501_PCI (VOYAGER_IRQ_BASE + 11) +#define IRQ_SM501_I2S (VOYAGER_IRQ_BASE + 12) +#define IRQ_SM501_AC (VOYAGER_IRQ_BASE + 13) +#define IRQ_SM501_US (VOYAGER_IRQ_BASE + 14) +#define IRQ_SM501_U1 (VOYAGER_IRQ_BASE + 15) +#define IRQ_SM501_U0 (VOYAGER_IRQ_BASE + 16) +#define IRQ_SM501_CV (VOYAGER_IRQ_BASE + 17) +#define IRQ_SM501_MC (VOYAGER_IRQ_BASE + 18) +#define IRQ_SM501_S1 (VOYAGER_IRQ_BASE + 19) +#define IRQ_SM501_S0 (VOYAGER_IRQ_BASE + 20) +#define IRQ_SM501_UH (VOYAGER_IRQ_BASE + 21) +#define IRQ_SM501_2D (VOYAGER_IRQ_BASE + 22) +#define IRQ_SM501_ZD (VOYAGER_IRQ_BASE + 23) +#define IRQ_SM501_PV (VOYAGER_IRQ_BASE + 24) +#define IRQ_SM501_CI (VOYAGER_IRQ_BASE + 25) /* ----- MISC controle register ------------------------------ */ #define MISC_CTRL (0x000004 + VOYAGER_BASE) @@ -313,4 +335,7 @@ void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t); int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t); +/* arch/sh/cchips/voyagergx/irq.c */ +void setup_voyagergx_irq(void); + #endif /* _VOYAGER_GX_REG_H */ |
From: Magnus D. <mag...@gm...> - 2007-08-03 04:29:15
|
sh: intc - add single bitmap register support This patch adds single bitmap register support to intc. The current code only handles 16 and 32 bit registers where a set bit means interrupt enabled, but this is easy to extend in the future. The INTC_IRQ() macro is also added to provide a way to hook in interrupt controllers for FPGAs in boards or companion chips. Signed-off-by: Magnus Damm <da...@ig...> --- arch/sh/kernel/cpu/irq/intc.c | 73 ++++++++++++++++++++++++++++++++++------- include/asm-sh/hw_irq.h | 1 2 files changed, 63 insertions(+), 11 deletions(-) --- 0001/arch/sh/kernel/cpu/irq/intc.c +++ work/arch/sh/kernel/cpu/irq/intc.c 2007-08-02 18:59:35.000000000 +0900 @@ -87,40 +87,71 @@ static void enable_prio_32(struct intc_d ctrl_outl(set_prio_field(desc, ctrl_inl(addr), prio, data), addr); } -static void disable_mask_8(struct intc_desc *desc, unsigned int data) +static void write_set_reg_8(struct intc_desc *desc, unsigned int data) { ctrl_outb(1 << _INTC_BIT(data), _INTC_PTR(desc, mask_regs, data)->set_reg); } -static void enable_mask_8(struct intc_desc *desc, unsigned int data) +static void write_clr_reg_8(struct intc_desc *desc, unsigned int data) { ctrl_outb(1 << _INTC_BIT(data), _INTC_PTR(desc, mask_regs, data)->clr_reg); } -static void disable_mask_32(struct intc_desc *desc, unsigned int data) +static void write_set_reg_32(struct intc_desc *desc, unsigned int data) { ctrl_outl(1 << _INTC_BIT(data), _INTC_PTR(desc, mask_regs, data)->set_reg); } -static void enable_mask_32(struct intc_desc *desc, unsigned int data) +static void write_clr_reg_32(struct intc_desc *desc, unsigned int data) { ctrl_outl(1 << _INTC_BIT(data), _INTC_PTR(desc, mask_regs, data)->clr_reg); } +static void or_set_reg_16(struct intc_desc *desc, unsigned int data) +{ + unsigned long addr = _INTC_PTR(desc, mask_regs, data)->set_reg; + + ctrl_outw(ctrl_inw(addr) | 1 << _INTC_BIT(data), addr); +} + +static void and_set_reg_16(struct intc_desc *desc, unsigned int data) +{ + unsigned long addr = _INTC_PTR(desc, mask_regs, data)->set_reg; + + ctrl_outw(ctrl_inw(addr) & ~(1 << _INTC_BIT(data)), addr); +} + +static void or_set_reg_32(struct intc_desc *desc, unsigned int data) +{ + unsigned long addr = _INTC_PTR(desc, mask_regs, data)->set_reg; + + ctrl_outl(ctrl_inl(addr) | 1 << _INTC_BIT(data), addr); +} + +static void and_set_reg_32(struct intc_desc *desc, unsigned int data) +{ + unsigned long addr = _INTC_PTR(desc, mask_regs, data)->set_reg; + + ctrl_outl(ctrl_inl(addr) & ~(1 << _INTC_BIT(data)), addr); +} + enum { REG_FN_ERROR=0, - REG_FN_MASK_8, REG_FN_MASK_32, + REG_FN_DUAL_8, REG_FN_DUAL_32, + REG_FN_ENA_16, REG_FN_ENA_32, REG_FN_PRIO_16, REG_FN_PRIO_32 }; static struct { void (*enable)(struct intc_desc *, unsigned int); void (*disable)(struct intc_desc *, unsigned int); } intc_reg_fns[] = { - [REG_FN_MASK_8] = { enable_mask_8, disable_mask_8 }, - [REG_FN_MASK_32] = { enable_mask_32, disable_mask_32 }, + [REG_FN_DUAL_8] = { write_clr_reg_8, write_set_reg_8 }, + [REG_FN_DUAL_32] = { write_clr_reg_32, write_set_reg_32 }, + [REG_FN_ENA_16] = { or_set_reg_16, and_set_reg_16 }, + [REG_FN_ENA_32] = { or_set_reg_32, and_set_reg_32 }, [REG_FN_PRIO_16] = { enable_prio_16, disable_prio_16 }, [REG_FN_PRIO_32] = { enable_prio_32, disable_prio_32 }, }; @@ -218,13 +249,13 @@ static int intc_set_sense(unsigned int i return -EINVAL; } -static unsigned int __init intc_find_mask_handler(unsigned int width) +static unsigned int __init intc_find_dual_handler(unsigned int width) { switch (width) { case 8: - return REG_FN_MASK_8; + return REG_FN_DUAL_8; case 32: - return REG_FN_MASK_32; + return REG_FN_DUAL_32; } BUG(); @@ -244,6 +275,19 @@ static unsigned int __init intc_find_pri return REG_FN_ERROR; } +static unsigned int __init intc_find_ena_handler(unsigned int width) +{ + switch (width) { + case 16: + return REG_FN_ENA_16; + case 32: + return REG_FN_ENA_32; + } + + BUG(); + return REG_FN_ERROR; +} + static intc_enum __init intc_grp_id(struct intc_desc *desc, intc_enum enum_id) { struct intc_group *g = desc->groups; @@ -301,7 +345,14 @@ static unsigned int __init intc_mask_dat if (mr->enum_ids[j] != enum_id) continue; - fn = intc_find_mask_handler(mr->reg_width); + switch (mr->clr_reg) { + case 1: /* 1 = enabled interrupt - "enable" register */ + fn = intc_find_ena_handler(mr->reg_width); + break; + default: + fn = intc_find_dual_handler(mr->reg_width); + } + if (fn == REG_FN_ERROR) return 0; --- 0004/include/asm-sh/hw_irq.h +++ work/include/asm-sh/hw_irq.h 2007-08-02 14:03:09.000000000 +0900 @@ -31,6 +31,7 @@ struct intc_vect { }; #define INTC_VECT(enum_id, vect) { enum_id, vect } +#define INTC_IRQ(enum_id, irq) INTC_VECT(enum_id, irq2evt(irq)) struct intc_prio { intc_enum enum_id; |
From: Paul M. <le...@li...> - 2007-08-03 04:25:01
|
On Fri, Aug 03, 2007 at 12:09:51AM -0400, Mike Frysinger wrote: > On Friday 03 August 2007, Paul Mundt wrote: > > On Thu, Aug 02, 2007 at 11:56:49PM -0400, Mike Frysinger wrote: > > > On Thursday 02 August 2007, Adrian McMenamin wrote: > > > > This patch adds a set machine-ops callbacks > > > > > > what is the advantage here over using weaks ? seems like weaks would be > > > simpler and better because you could cull the default ones at link time > > > if a board provided its own ... > > > > Multiple machine support, basically. Weak symbols won't work for the case > > where multiple boards are linked in to the same image. We can have > > multiple machvecs packed in at once and simply discard the ones we don't > > care about at boot time (as per arch/sh/kernel/machvec.c). > > ah, i'd forgotten about that aspect ... is that the only upside ? i'm > debating doing this in Blackfin and at the moment i'd just use weaks since we > have no infrastructure to do multiple board support and we dont have plans to > add it anytime soon ... Hypervisors like to overload these as well, Xen has its own set of machine_ops on i386 for example. So unless you forsee caring about virtualization or supporting multiple machines, there's probably not a lot of gain in doing this for Blackfin. While it's not really a problem these days, old versions of GCC used to have some problems with the attribute -- hence the comment above the cond_syscall() definition (asm/unistd.h), which has since been copied verbatim by almost every other platform, sh and blackfin included ;-) In any event, supporting multiple boards is fairly trivial, but you give up link-time size savings and push most of that down to freeing of init memory. It works out the same in the end, the main factor is how constrained you are in kernel size. Some platforms (ie, hppa) also make function pointers quite expensive, so there are also performance reasons why you may wish to avoid the extra layer of indirection. |
From: Mike F. <va...@ge...> - 2007-08-03 04:09:22
|
On Friday 03 August 2007, Paul Mundt wrote: > On Thu, Aug 02, 2007 at 11:56:49PM -0400, Mike Frysinger wrote: > > On Thursday 02 August 2007, Adrian McMenamin wrote: > > > This patch adds a set machine-ops callbacks > > > > what is the advantage here over using weaks ? seems like weaks would be > > simpler and better because you could cull the default ones at link time > > if a board provided its own ... > > Multiple machine support, basically. Weak symbols won't work for the case > where multiple boards are linked in to the same image. We can have > multiple machvecs packed in at once and simply discard the ones we don't > care about at boot time (as per arch/sh/kernel/machvec.c). ah, i'd forgotten about that aspect ... is that the only upside ? i'm=20 debating doing this in Blackfin and at the moment i'd just use weaks since = we=20 have no infrastructure to do multiple board support and we dont have plans = to=20 add it anytime soon ... =2Dmike |
From: Paul M. <le...@li...> - 2007-08-03 04:02:51
|
On Thu, Aug 02, 2007 at 11:56:49PM -0400, Mike Frysinger wrote: > On Thursday 02 August 2007, Adrian McMenamin wrote: > > This patch adds a set machine-ops callbacks > > what is the advantage here over using weaks ? seems like weaks would be > simpler and better because you could cull the default ones at link time if a > board provided its own ... Multiple machine support, basically. Weak symbols won't work for the case where multiple boards are linked in to the same image. We can have multiple machvecs packed in at once and simply discard the ones we don't care about at boot time (as per arch/sh/kernel/machvec.c). |