diff options
author | Jamie Lenehan <lenehan@twibble.org> | 2006-12-05 22:05:02 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2006-12-05 22:05:02 -0500 |
commit | ea0f8feaa041f3ccec3d6b8ee51325b177daef06 (patch) | |
tree | 261c7d75e5caccbaface63370bae029ecd81b98a /arch/sh/kernel | |
parent | fe9687dec0400c6de7187ab5efa91facd958ca84 (diff) |
sh: sh775x/titan fixes for irq header changes.
The following moves the creation of IPR interupts into setup-7750.c
and updates a few other things to make it all work after the "Drop
CPU subtype IRQ headers" commit. It boots and runs fine on my titan
board.
- adds an ipr_idx to the ipr_data and uses a function in the subtype
code to calculate the address of the IPR registers
- adds a function to enable individual interrupt mode for externals
in the subtype code and calls that from the titan board code
instead of doing it directly.
- I changed the shift in the ipr_data to be the actual # of bits to
shift, instead of the numnber / 4 - made it easier to match with
the manual.
Signed-off-by: Jamie Lenehan <lenehan@twibble.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/cpu/irq/Makefile | 3 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/irq/ipr.c | 103 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/setup-sh7750.c | 70 | ||||
-rw-r--r-- | arch/sh/kernel/irq.c | 25 |
4 files changed, 101 insertions, 100 deletions
diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile index 1c034c283f59..0049d217561a 100644 --- a/arch/sh/kernel/cpu/irq/Makefile +++ b/arch/sh/kernel/cpu/irq/Makefile | |||
@@ -1,8 +1,9 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the Linux/SuperH CPU-specifc IRQ handlers. | 2 | # Makefile for the Linux/SuperH CPU-specifc IRQ handlers. |
3 | # | 3 | # |
4 | obj-y += ipr.o imask.o | 4 | obj-y += imask.o |
5 | 5 | ||
6 | obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o | ||
6 | obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o | 7 | obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o |
7 | obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o | 8 | obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o |
8 | obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o | 9 | obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o |
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index a181ccdf2906..35eb5751a3aa 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c | |||
@@ -25,17 +25,15 @@ | |||
25 | static void disable_ipr_irq(unsigned int irq) | 25 | static void disable_ipr_irq(unsigned int irq) |
26 | { | 26 | { |
27 | struct ipr_data *p = get_irq_chip_data(irq); | 27 | struct ipr_data *p = get_irq_chip_data(irq); |
28 | int shift = p->shift*4; | ||
29 | /* Set the priority in IPR to 0 */ | 28 | /* Set the priority in IPR to 0 */ |
30 | ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << shift)), p->addr); | 29 | ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr); |
31 | } | 30 | } |
32 | 31 | ||
33 | static void enable_ipr_irq(unsigned int irq) | 32 | static void enable_ipr_irq(unsigned int irq) |
34 | { | 33 | { |
35 | struct ipr_data *p = get_irq_chip_data(irq); | 34 | struct ipr_data *p = get_irq_chip_data(irq); |
36 | int shift = p->shift*4; | ||
37 | /* Set priority in IPR back to original value */ | 35 | /* Set priority in IPR back to original value */ |
38 | ctrl_outw(ctrl_inw(p->addr) | (p->priority << shift), p->addr); | 36 | ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr); |
39 | } | 37 | } |
40 | 38 | ||
41 | static struct irq_chip ipr_irq_chip = { | 39 | static struct irq_chip ipr_irq_chip = { |
@@ -51,6 +49,10 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) | |||
51 | 49 | ||
52 | for (i = 0; i < nr_irqs; i++) { | 50 | for (i = 0; i < nr_irqs; i++) { |
53 | unsigned int irq = table[i].irq; | 51 | unsigned int irq = table[i].irq; |
52 | table[i].addr = map_ipridx_to_addr(table[i].ipr_idx); | ||
53 | /* could the IPR index be mapped, if not we ignore this */ | ||
54 | if (table[i].addr == 0) | ||
55 | continue; | ||
54 | disable_irq_nosync(irq); | 56 | disable_irq_nosync(irq); |
55 | set_irq_chip_and_handler_name(irq, &ipr_irq_chip, | 57 | set_irq_chip_and_handler_name(irq, &ipr_irq_chip, |
56 | handle_level_irq, "level"); | 58 | handle_level_irq, "level"); |
@@ -60,99 +62,6 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) | |||
60 | } | 62 | } |
61 | EXPORT_SYMBOL(make_ipr_irq); | 63 | EXPORT_SYMBOL(make_ipr_irq); |
62 | 64 | ||
63 | /* | ||
64 | * XXX: Move this garbage in to the drivers, and kill off the ridiculous CPU | ||
65 | * subtype checks. | ||
66 | */ | ||
67 | static struct ipr_data sys_ipr_map[] = { | ||
68 | #ifndef CONFIG_CPU_SUBTYPE_SH7780 | ||
69 | { TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY }, | ||
70 | { TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY }, | ||
71 | #ifdef RTC_IRQ | ||
72 | { RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY }, | ||
73 | #endif | ||
74 | #ifdef SCI_ERI_IRQ | ||
75 | { SCI_ERI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, | ||
76 | { SCI_RXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, | ||
77 | { SCI_TXI_IRQ, SCI_IPR_ADDR, SCI_IPR_POS, SCI_PRIORITY }, | ||
78 | #endif | ||
79 | #ifdef SCIF1_ERI_IRQ | ||
80 | { SCIF1_ERI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, | ||
81 | { SCIF1_RXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, | ||
82 | { SCIF1_BRI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, | ||
83 | { SCIF1_TXI_IRQ, SCIF1_IPR_ADDR, SCIF1_IPR_POS, SCIF1_PRIORITY }, | ||
84 | #endif | ||
85 | #ifdef SCIF2_ERI_IRQ | ||
86 | { SCIF2_ERI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, | ||
87 | { SCIF2_RXI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, | ||
88 | { SCIF2_BRI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, | ||
89 | { SCIF2_TXI_IRQ, SCIF2_IPR_ADDR, SCIF2_IPR_POS, SCIF2_PRIORITY }, | ||
90 | #endif | ||
91 | #ifdef SCIF3_ERI_IRQ | ||
92 | { SCIF3_ERI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, | ||
93 | { SCIF3_RXI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, | ||
94 | { SCIF3_BRI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, | ||
95 | { SCIF3_TXI_IRQ, SCIF3_IPR_ADDR, SCIF3_IPR_POS, SCIF3_PRIORITY }, | ||
96 | #endif | ||
97 | #if defined(CONFIG_CPU_SUBTYPE_SH7300) | ||
98 | { SCIF0_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, SCIF0_PRIORITY }, | ||
99 | { DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, | ||
100 | { DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY }, | ||
101 | { VIO_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY }, | ||
102 | #endif | ||
103 | #ifdef SCIF_ERI_IRQ | ||
104 | { SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, | ||
105 | { SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, | ||
106 | { SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, | ||
107 | { SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY }, | ||
108 | #endif | ||
109 | #ifdef IRDA_ERI_IRQ | ||
110 | { IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, | ||
111 | { IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, | ||
112 | { IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, | ||
113 | { IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY }, | ||
114 | #endif | ||
115 | #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ | ||
116 | defined(CONFIG_CPU_SUBTYPE_SH7706) || \ | ||
117 | defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) | ||
118 | /* | ||
119 | * Initialize the Interrupt Controller (INTC) | ||
120 | * registers to their power on values | ||
121 | */ | ||
122 | |||
123 | /* | ||
124 | * Enable external irq (INTC IRQ mode). | ||
125 | * You should set corresponding bits of PFC to "00" | ||
126 | * to enable these interrupts. | ||
127 | */ | ||
128 | { IRQ0_IRQ, IRQ0_IPR_ADDR, IRQ0_IPR_POS, IRQ0_PRIORITY }, | ||
129 | { IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY }, | ||
130 | { IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY }, | ||
131 | { IRQ3_IRQ, IRQ3_IPR_ADDR, IRQ3_IPR_POS, IRQ3_PRIORITY }, | ||
132 | { IRQ4_IRQ, IRQ4_IPR_ADDR, IRQ4_IPR_POS, IRQ4_PRIORITY }, | ||
133 | { IRQ5_IRQ, IRQ5_IPR_ADDR, IRQ5_IPR_POS, IRQ5_PRIORITY }, | ||
134 | #endif | ||
135 | #endif | ||
136 | }; | ||
137 | |||
138 | void __init init_IRQ(void) | ||
139 | { | ||
140 | make_ipr_irq(sys_ipr_map, ARRAY_SIZE(sys_ipr_map)); | ||
141 | |||
142 | #ifdef CONFIG_CPU_HAS_PINT_IRQ | ||
143 | init_IRQ_pint(); | ||
144 | #endif | ||
145 | |||
146 | #ifdef CONFIG_CPU_HAS_INTC2_IRQ | ||
147 | init_IRQ_intc2(); | ||
148 | #endif | ||
149 | /* Perform the machine specific initialisation */ | ||
150 | if (sh_mv.mv_init_irq != NULL) | ||
151 | sh_mv.mv_init_irq(); | ||
152 | |||
153 | irq_ctx_init(smp_processor_id()); | ||
154 | } | ||
155 | |||
156 | #if !defined(CONFIG_CPU_HAS_PINT_IRQ) | 65 | #if !defined(CONFIG_CPU_HAS_PINT_IRQ) |
157 | int ipr_irq_demux(int irq) | 66 | int ipr_irq_demux(int irq) |
158 | { | 67 | { |
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 50812d57c1c1..bbcb06f18b04 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * SH7750/SH7751 Setup | 2 | * SH7750/SH7751 Setup |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Paul Mundt | 4 | * Copyright (C) 2006 Paul Mundt |
5 | * Copyright (C) 2006 Jamie Lenehan | ||
5 | * | 6 | * |
6 | * This file is subject to the terms and conditions of the GNU General Public | 7 | * This file is subject to the terms and conditions of the GNU General Public |
7 | * License. See the file "COPYING" in the main directory of this archive | 8 | * License. See the file "COPYING" in the main directory of this archive |
@@ -10,6 +11,7 @@ | |||
10 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
12 | #include <linux/serial.h> | 13 | #include <linux/serial.h> |
14 | #include <linux/io.h> | ||
13 | #include <asm/sci.h> | 15 | #include <asm/sci.h> |
14 | 16 | ||
15 | static struct plat_sci_port sci_platform_data[] = { | 17 | static struct plat_sci_port sci_platform_data[] = { |
@@ -46,3 +48,71 @@ static int __init sh7750_devices_setup(void) | |||
46 | ARRAY_SIZE(sh7750_devices)); | 48 | ARRAY_SIZE(sh7750_devices)); |
47 | } | 49 | } |
48 | __initcall(sh7750_devices_setup); | 50 | __initcall(sh7750_devices_setup); |
51 | |||
52 | static struct ipr_data sh7750_ipr_map[] = { | ||
53 | /* IRQ, IPR-idx, shift, priority */ | ||
54 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ | ||
55 | { 17, 0, 12, 2 }, /* TMU1 TUNI */ | ||
56 | { 18, 0, 4, 2 }, /* TMU2 TUNI */ | ||
57 | { 19, 0, 4, 2 }, /* TMU2 TIPCI */ | ||
58 | { 27, 1, 12, 2 }, /* WDT ITI */ | ||
59 | { 20, 0, 0, 2 }, /* RTC ATI (alarm) */ | ||
60 | { 21, 0, 0, 2 }, /* RTC PRI (period) */ | ||
61 | { 22, 0, 0, 2 }, /* RTC CUI (carry) */ | ||
62 | { 23, 1, 4, 3 }, /* SCI ERI */ | ||
63 | { 24, 1, 4, 3 }, /* SCI RXI */ | ||
64 | { 25, 1, 4, 3 }, /* SCI TXI */ | ||
65 | { 40, 2, 4, 3 }, /* SCIF ERI */ | ||
66 | { 41, 2, 4, 3 }, /* SCIF RXI */ | ||
67 | { 42, 2, 4, 3 }, /* SCIF BRI */ | ||
68 | { 43, 2, 4, 3 }, /* SCIF TXI */ | ||
69 | { 34, 2, 8, 7 }, /* DMAC DMTE0 */ | ||
70 | { 35, 2, 8, 7 }, /* DMAC DMTE1 */ | ||
71 | { 36, 2, 8, 7 }, /* DMAC DMTE2 */ | ||
72 | { 37, 2, 8, 7 }, /* DMAC DMTE3 */ | ||
73 | { 28, 2, 8, 7 }, /* DMAC DMAE */ | ||
74 | }; | ||
75 | |||
76 | static struct ipr_data sh7751_ipr_map[] = { | ||
77 | { 44, 2, 8, 7 }, /* DMAC DMTE4 */ | ||
78 | { 45, 2, 8, 7 }, /* DMAC DMTE5 */ | ||
79 | { 46, 2, 8, 7 }, /* DMAC DMTE6 */ | ||
80 | { 47, 2, 8, 7 }, /* DMAC DMTE7 */ | ||
81 | /* The following use INTC_INPRI00 for masking, which is a 32-bit | ||
82 | register, not a 16-bit register like the IPRx registers, so it | ||
83 | would need special support */ | ||
84 | /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */ | ||
85 | /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */ | ||
86 | }; | ||
87 | |||
88 | static unsigned long ipr_offsets[] = { | ||
89 | 0xffd00004UL, /* 0: IPRA */ | ||
90 | 0xffd00008UL, /* 1: IPRB */ | ||
91 | 0xffd0000cUL, /* 2: IPRC */ | ||
92 | 0xffd00010UL, /* 3: IPRD */ | ||
93 | }; | ||
94 | |||
95 | /* given the IPR index return the address of the IPR register */ | ||
96 | unsigned int map_ipridx_to_addr(int idx) | ||
97 | { | ||
98 | if (idx >= ARRAY_SIZE(ipr_offsets)) | ||
99 | return 0; | ||
100 | return ipr_offsets[idx]; | ||
101 | } | ||
102 | |||
103 | #define INTC_ICR 0xffd00000UL | ||
104 | #define INTC_ICR_IRLM (1<<7) | ||
105 | |||
106 | /* enable individual interrupt mode for external interupts */ | ||
107 | void ipr_irq_enable_irlm(void) | ||
108 | { | ||
109 | ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); | ||
110 | } | ||
111 | |||
112 | void __init init_IRQ_ipr() | ||
113 | { | ||
114 | make_ipr_irq(sh7750_ipr_map, ARRAY_SIZE(sh7750_ipr_map)); | ||
115 | #ifdef CONFIG_CPU_SUBTYPE_SH7751 | ||
116 | make_ipr_irq(sh7751_ipr_map, ARRAY_SIZE(sh7751_ipr_map)); | ||
117 | #endif | ||
118 | } | ||
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 46a19e07abd3..67be2b6e8cd1 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <linux/kernel_stat.h> | 12 | #include <linux/kernel_stat.h> |
13 | #include <linux/seq_file.h> | 13 | #include <linux/seq_file.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <asm/irq.h> | 15 | #include <linux/irq.h> |
16 | #include <asm/processor.h> | 16 | #include <asm/processor.h> |
17 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
18 | #include <asm/thread_info.h> | 18 | #include <asm/thread_info.h> |
@@ -112,7 +112,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, | |||
112 | #endif | 112 | #endif |
113 | 113 | ||
114 | #ifdef CONFIG_CPU_HAS_INTEVT | 114 | #ifdef CONFIG_CPU_HAS_INTEVT |
115 | irq = (ctrl_inl(INTEVT) >> 5) - 16; | 115 | irq = evt2irq(ctrl_inl(INTEVT)); |
116 | #else | 116 | #else |
117 | irq = r4; | 117 | irq = r4; |
118 | #endif | 118 | #endif |
@@ -261,3 +261,24 @@ asmlinkage void do_softirq(void) | |||
261 | } | 261 | } |
262 | EXPORT_SYMBOL(do_softirq); | 262 | EXPORT_SYMBOL(do_softirq); |
263 | #endif | 263 | #endif |
264 | |||
265 | void __init init_IRQ(void) | ||
266 | { | ||
267 | #ifdef CONFIG_CPU_HAS_PINT_IRQ | ||
268 | init_IRQ_pint(); | ||
269 | #endif | ||
270 | |||
271 | #ifdef CONFIG_CPU_HAS_INTC2_IRQ | ||
272 | init_IRQ_intc2(); | ||
273 | #endif | ||
274 | |||
275 | #ifdef CONFIG_CPU_HAS_IPR_IRQ | ||
276 | init_IRQ_ipr(); | ||
277 | #endif | ||
278 | |||
279 | /* Perform the machine specific initialisation */ | ||
280 | if (sh_mv.mv_init_irq) | ||
281 | sh_mv.mv_init_irq(); | ||
282 | |||
283 | irq_ctx_init(smp_processor_id()); | ||
284 | } | ||