aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/irq
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu/irq')
-rw-r--r--arch/sh/kernel/cpu/irq/Makefile5
-rw-r--r--arch/sh/kernel/cpu/irq/intc2.c6
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c14
-rw-r--r--arch/sh/kernel/cpu/irq/maskreg.c93
-rw-r--r--arch/sh/kernel/cpu/irq/pint.c8
5 files changed, 108 insertions, 18 deletions
diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile
index e3cccea15e1d..1c034c283f59 100644
--- a/arch/sh/kernel/cpu/irq/Makefile
+++ b/arch/sh/kernel/cpu/irq/Makefile
@@ -3,5 +3,6 @@
3# 3#
4obj-y += ipr.o imask.o 4obj-y += ipr.o imask.o
5 5
6obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o 6obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o
7obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o 7obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o
8obj-$(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 30064bf6e154..e30e4b7aa70e 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 {
241 /* 110-111 reserved/unused */ 241 /* 110-111 reserved/unused */
242#elif defined(CONFIG_CPU_SUBTYPE_SH7780) 242#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
243 { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2}, 243 { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2},
244#ifdef CONFIG_SH_RTC 244 { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY },
245 { RTC_IRQ, 4, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, 245 { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY },
246#endif 246 { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY },
247 { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, 247 { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
248 { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, 248 { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY },
249 { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, 249 { 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 0f545941fb4f..f785822cd5de 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 = {
57 57
58static void disable_ipr_irq(unsigned int irq) 58static void disable_ipr_irq(unsigned int irq)
59{ 59{
60 unsigned long val, flags; 60 unsigned long val;
61 unsigned int addr = ipr_data[irq].addr; 61 unsigned int addr = ipr_data[irq].addr;
62 unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift); 62 unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift);
63 63
64 /* Set the priority in IPR to 0 */ 64 /* Set the priority in IPR to 0 */
65 local_irq_save(flags);
66 val = ctrl_inw(addr); 65 val = ctrl_inw(addr);
67 val &= mask; 66 val &= mask;
68 ctrl_outw(val, addr); 67 ctrl_outw(val, addr);
69 local_irq_restore(flags);
70} 68}
71 69
72static void enable_ipr_irq(unsigned int irq) 70static void enable_ipr_irq(unsigned int irq)
73{ 71{
74 unsigned long val, flags; 72 unsigned long val;
75 unsigned int addr = ipr_data[irq].addr; 73 unsigned int addr = ipr_data[irq].addr;
76 int priority = ipr_data[irq].priority; 74 int priority = ipr_data[irq].priority;
77 unsigned short value = (priority << ipr_data[irq].shift); 75 unsigned short value = (priority << ipr_data[irq].shift);
78 76
79 /* Set priority in IPR back to original value */ 77 /* Set priority in IPR back to original value */
80 local_irq_save(flags);
81 val = ctrl_inw(addr); 78 val = ctrl_inw(addr);
82 val |= value; 79 val |= value;
83 ctrl_outw(val, addr); 80 ctrl_outw(val, addr);
84 local_irq_restore(flags);
85} 81}
86 82
87static void mask_and_ack_ipr(unsigned int irq) 83static void mask_and_ack_ipr(unsigned int irq)
@@ -89,6 +85,7 @@ static void mask_and_ack_ipr(unsigned int irq)
89 disable_ipr_irq(irq); 85 disable_ipr_irq(irq);
90 86
91#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ 87#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
88 defined(CONFIG_CPU_SUBTYPE_SH7706) || \
92 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) 89 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
93 /* This is needed when we use edge triggered setting */ 90 /* This is needed when we use edge triggered setting */
94 /* XXX: Is it really needed? */ 91 /* XXX: Is it really needed? */
@@ -123,7 +120,7 @@ void __init init_IRQ(void)
123#ifndef CONFIG_CPU_SUBTYPE_SH7780 120#ifndef CONFIG_CPU_SUBTYPE_SH7780
124 make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY); 121 make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY);
125 make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY); 122 make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY);
126#if defined(CONFIG_SH_RTC) 123#ifdef RTC_IRQ
127 make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); 124 make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY);
128#endif 125#endif
129 126
@@ -162,6 +159,7 @@ void __init init_IRQ(void)
162#endif 159#endif
163 160
164#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ 161#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \
162 defined(CONFIG_CPU_SUBTYPE_SH7706) || \
165 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) 163 defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705)
166 /* 164 /*
167 * Initialize the Interrupt Controller (INTC) 165 * Initialize the Interrupt Controller (INTC)
@@ -192,6 +190,8 @@ void __init init_IRQ(void)
192 /* Perform the machine specific initialisation */ 190 /* Perform the machine specific initialisation */
193 if (sh_mv.mv_init_irq != NULL) 191 if (sh_mv.mv_init_irq != NULL)
194 sh_mv.mv_init_irq(); 192 sh_mv.mv_init_irq();
193
194 irq_ctx_init(smp_processor_id());
195} 195}
196 196
197#if !defined(CONFIG_CPU_HAS_PINT_IRQ) 197#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 000000000000..492db31b3cab
--- /dev/null
+++ b/arch/sh/kernel/cpu/irq/maskreg.c
@@ -0,0 +1,93 @@
1/*
2 * Interrupt handling for Simple external interrupt mask register
3 *
4 * Copyright (C) 2001 A&D Co., Ltd. <http://www.aandd.co.jp>
5 *
6 * This is for the machine which have single 16 bit register
7 * for masking external IRQ individually.
8 * Each bit of the register is for masking each interrupt.
9 *
10 * This file may be copied or modified under the terms of the GNU
11 * General Public License. See linux/COPYING for more information.
12 */
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/irq.h>
16#include <asm/system.h>
17#include <asm/io.h>
18
19/* address of external interrupt mask register */
20unsigned long irq_mask_register;
21
22/* forward declaration */
23static unsigned int startup_maskreg_irq(unsigned int irq);
24static void shutdown_maskreg_irq(unsigned int irq);
25static void enable_maskreg_irq(unsigned int irq);
26static void disable_maskreg_irq(unsigned int irq);
27static void mask_and_ack_maskreg(unsigned int);
28static void end_maskreg_irq(unsigned int irq);
29
30/* hw_interrupt_type */
31static struct hw_interrupt_type maskreg_irq_type = {
32 .typename = "Mask Register",
33 .startup = startup_maskreg_irq,
34 .shutdown = shutdown_maskreg_irq,
35 .enable = enable_maskreg_irq,
36 .disable = disable_maskreg_irq,
37 .ack = mask_and_ack_maskreg,
38 .end = end_maskreg_irq
39};
40
41/* actual implementatin */
42static unsigned int startup_maskreg_irq(unsigned int irq)
43{
44 enable_maskreg_irq(irq);
45 return 0; /* never anything pending */
46}
47
48static void shutdown_maskreg_irq(unsigned int irq)
49{
50 disable_maskreg_irq(irq);
51}
52
53static void disable_maskreg_irq(unsigned int irq)
54{
55 unsigned short val, mask = 0x01 << irq;
56
57 BUG_ON(!irq_mask_register);
58
59 /* Set "irq"th bit */
60 val = ctrl_inw(irq_mask_register);
61 val |= mask;
62 ctrl_outw(val, irq_mask_register);
63}
64
65static void enable_maskreg_irq(unsigned int irq)
66{
67 unsigned short val, mask = ~(0x01 << irq);
68
69 BUG_ON(!irq_mask_register);
70
71 /* Clear "irq"th bit */
72 val = ctrl_inw(irq_mask_register);
73 val &= mask;
74 ctrl_outw(val, irq_mask_register);
75}
76
77static void mask_and_ack_maskreg(unsigned int irq)
78{
79 disable_maskreg_irq(irq);
80}
81
82static void end_maskreg_irq(unsigned int irq)
83{
84 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
85 enable_maskreg_irq(irq);
86}
87
88void make_maskreg_irq(unsigned int irq)
89{
90 disable_irq_nosync(irq);
91 irq_desc[irq].handler = &maskreg_irq_type;
92 disable_maskreg_irq(irq);
93}
diff --git a/arch/sh/kernel/cpu/irq/pint.c b/arch/sh/kernel/cpu/irq/pint.c
index 80cd8108d36a..17f47b373d6e 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 = {
48 48
49static void disable_pint_irq(unsigned int irq) 49static void disable_pint_irq(unsigned int irq)
50{ 50{
51 unsigned long val, flags; 51 unsigned long val;
52 52
53 local_irq_save(flags);
54 val = ctrl_inw(INTC_INTER); 53 val = ctrl_inw(INTC_INTER);
55 val &= ~(1 << (irq - PINT_IRQ_BASE)); 54 val &= ~(1 << (irq - PINT_IRQ_BASE));
56 ctrl_outw(val, INTC_INTER); /* disable PINTn */ 55 ctrl_outw(val, INTC_INTER); /* disable PINTn */
57 portcr_mask &= ~(3 << (irq - PINT_IRQ_BASE)*2); 56 portcr_mask &= ~(3 << (irq - PINT_IRQ_BASE)*2);
58 local_irq_restore(flags);
59} 57}
60 58
61static void enable_pint_irq(unsigned int irq) 59static void enable_pint_irq(unsigned int irq)
62{ 60{
63 unsigned long val, flags; 61 unsigned long val;
64 62
65 local_irq_save(flags);
66 val = ctrl_inw(INTC_INTER); 63 val = ctrl_inw(INTC_INTER);
67 val |= 1 << (irq - PINT_IRQ_BASE); 64 val |= 1 << (irq - PINT_IRQ_BASE);
68 ctrl_outw(val, INTC_INTER); /* enable PINTn */ 65 ctrl_outw(val, INTC_INTER); /* enable PINTn */
69 portcr_mask |= 3 << (irq - PINT_IRQ_BASE)*2; 66 portcr_mask |= 3 << (irq - PINT_IRQ_BASE)*2;
70 local_irq_restore(flags);
71} 67}
72 68
73static void mask_and_ack_pint(unsigned int irq) 69static void mask_and_ack_pint(unsigned int irq)