diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2006-09-28 08:29:59 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-09-28 08:29:59 -0400 |
commit | 185a257f2f73bcd89050ad02da5bedbc28fc43fa (patch) | |
tree | 5e32586114534ed3f2165614cba3d578f5d87307 /arch/sh/kernel/cpu/irq | |
parent | 3f1a9aaeffd8d1cbc5ab9776c45cbd66af1c9699 (diff) | |
parent | a77c64c1a641950626181b4857abb701d8f38ccc (diff) |
Merge branch 'master' into gfs2
Diffstat (limited to 'arch/sh/kernel/cpu/irq')
-rw-r--r-- | arch/sh/kernel/cpu/irq/Makefile | 5 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/irq/intc2.c | 6 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/irq/ipr.c | 14 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/irq/maskreg.c | 93 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/irq/pint.c | 8 |
5 files changed, 108 insertions, 18 deletions
diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile index e3cccea15e1..1c034c283f5 100644 --- a/arch/sh/kernel/cpu/irq/Makefile +++ b/arch/sh/kernel/cpu/irq/Makefile @@ -3,5 +3,6 @@ # obj-y += ipr.o imask.o -obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o -obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o +obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o +obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o +obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c index 30064bf6e15..e30e4b7aa70 100644 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ b/arch/sh/kernel/cpu/irq/intc2.c @@ -241,9 +241,9 @@ static struct intc2_init { /* 110-111 reserved/unused */ #elif defined(CONFIG_CPU_SUBTYPE_SH7780) { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2}, -#ifdef CONFIG_SH_RTC - { RTC_IRQ, 4, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, -#endif + { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, + { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY }, + { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY }, { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index 0f545941fb4..f785822cd5d 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -57,31 +57,27 @@ static struct hw_interrupt_type ipr_irq_type = { static void disable_ipr_irq(unsigned int irq) { - unsigned long val, flags; + unsigned long val; unsigned int addr = ipr_data[irq].addr; unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift); /* Set the priority in IPR to 0 */ - local_irq_save(flags); val = ctrl_inw(addr); val &= mask; ctrl_outw(val, addr); - local_irq_restore(flags); } static void enable_ipr_irq(unsigned int irq) { - unsigned long val, flags; + unsigned long val; unsigned int addr = ipr_data[irq].addr; int priority = ipr_data[irq].priority; unsigned short value = (priority << ipr_data[irq].shift); /* Set priority in IPR back to original value */ - local_irq_save(flags); val = ctrl_inw(addr); val |= value; ctrl_outw(val, addr); - local_irq_restore(flags); } static void mask_and_ack_ipr(unsigned int irq) @@ -89,6 +85,7 @@ static void mask_and_ack_ipr(unsigned int irq) disable_ipr_irq(irq); #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) /* This is needed when we use edge triggered setting */ /* XXX: Is it really needed? */ @@ -123,7 +120,7 @@ void __init init_IRQ(void) #ifndef CONFIG_CPU_SUBTYPE_SH7780 make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY); make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY); -#if defined(CONFIG_SH_RTC) +#ifdef RTC_IRQ make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); #endif @@ -162,6 +159,7 @@ void __init init_IRQ(void) #endif #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) /* * Initialize the Interrupt Controller (INTC) @@ -192,6 +190,8 @@ void __init init_IRQ(void) /* Perform the machine specific initialisation */ if (sh_mv.mv_init_irq != NULL) sh_mv.mv_init_irq(); + + irq_ctx_init(smp_processor_id()); } #if !defined(CONFIG_CPU_HAS_PINT_IRQ) diff --git a/arch/sh/kernel/cpu/irq/maskreg.c b/arch/sh/kernel/cpu/irq/maskreg.c new file mode 100644 index 00000000000..492db31b3ca --- /dev/null +++ b/arch/sh/kernel/cpu/irq/maskreg.c @@ -0,0 +1,93 @@ +/* + * Interrupt handling for Simple external interrupt mask register + * + * Copyright (C) 2001 A&D Co., Ltd. <http://www.aandd.co.jp> + * + * This is for the machine which have single 16 bit register + * for masking external IRQ individually. + * Each bit of the register is for masking each interrupt. + * + * This file may be copied or modified under the terms of the GNU + * General Public License. See linux/COPYING for more information. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <asm/system.h> +#include <asm/io.h> + +/* address of external interrupt mask register */ +unsigned long irq_mask_register; + +/* forward declaration */ +static unsigned int startup_maskreg_irq(unsigned int irq); +static void shutdown_maskreg_irq(unsigned int irq); +static void enable_maskreg_irq(unsigned int irq); +static void disable_maskreg_irq(unsigned int irq); +static void mask_and_ack_maskreg(unsigned int); +static void end_maskreg_irq(unsigned int irq); + +/* hw_interrupt_type */ +static struct hw_interrupt_type maskreg_irq_type = { + .typename = "Mask Register", + .startup = startup_maskreg_irq, + .shutdown = shutdown_maskreg_irq, + .enable = enable_maskreg_irq, + .disable = disable_maskreg_irq, + .ack = mask_and_ack_maskreg, + .end = end_maskreg_irq +}; + +/* actual implementatin */ +static unsigned int startup_maskreg_irq(unsigned int irq) +{ + enable_maskreg_irq(irq); + return 0; /* never anything pending */ +} + +static void shutdown_maskreg_irq(unsigned int irq) +{ + disable_maskreg_irq(irq); +} + +static void disable_maskreg_irq(unsigned int irq) +{ + unsigned short val, mask = 0x01 << irq; + + BUG_ON(!irq_mask_register); + + /* Set "irq"th bit */ + val = ctrl_inw(irq_mask_register); + val |= mask; + ctrl_outw(val, irq_mask_register); +} + +static void enable_maskreg_irq(unsigned int irq) +{ + unsigned short val, mask = ~(0x01 << irq); + + BUG_ON(!irq_mask_register); + + /* Clear "irq"th bit */ + val = ctrl_inw(irq_mask_register); + val &= mask; + ctrl_outw(val, irq_mask_register); +} + +static void mask_and_ack_maskreg(unsigned int irq) +{ + disable_maskreg_irq(irq); +} + +static void end_maskreg_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_maskreg_irq(irq); +} + +void make_maskreg_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].handler = &maskreg_irq_type; + disable_maskreg_irq(irq); +} diff --git a/arch/sh/kernel/cpu/irq/pint.c b/arch/sh/kernel/cpu/irq/pint.c index 80cd8108d36..17f47b373d6 100644 --- a/arch/sh/kernel/cpu/irq/pint.c +++ b/arch/sh/kernel/cpu/irq/pint.c @@ -48,26 +48,22 @@ static struct hw_interrupt_type pint_irq_type = { static void disable_pint_irq(unsigned int irq) { - unsigned long val, flags; + unsigned long val; - local_irq_save(flags); val = ctrl_inw(INTC_INTER); val &= ~(1 << (irq - PINT_IRQ_BASE)); ctrl_outw(val, INTC_INTER); /* disable PINTn */ portcr_mask &= ~(3 << (irq - PINT_IRQ_BASE)*2); - local_irq_restore(flags); } static void enable_pint_irq(unsigned int irq) { - unsigned long val, flags; + unsigned long val; - local_irq_save(flags); val = ctrl_inw(INTC_INTER); val |= 1 << (irq - PINT_IRQ_BASE); ctrl_outw(val, INTC_INTER); /* enable PINTn */ portcr_mask |= 3 << (irq - PINT_IRQ_BASE)*2; - local_irq_restore(flags); } static void mask_and_ack_pint(unsigned int irq) |