aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
authorJamie Lenehan <lenehan@twibble.org>2006-12-05 22:05:02 -0500
committerPaul Mundt <lethal@linux-sh.org>2006-12-05 22:05:02 -0500
commitea0f8feaa041f3ccec3d6b8ee51325b177daef06 (patch)
tree261c7d75e5caccbaface63370bae029ecd81b98a /arch/sh/kernel
parentfe9687dec0400c6de7187ab5efa91facd958ca84 (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/Makefile3
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c103
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7750.c70
-rw-r--r--arch/sh/kernel/irq.c25
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#
4obj-y += ipr.o imask.o 4obj-y += imask.o
5 5
6obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o
6obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o 7obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o
7obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o 8obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o
8obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o 9obj-$(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 @@
25static void disable_ipr_irq(unsigned int irq) 25static 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
33static void enable_ipr_irq(unsigned int irq) 32static 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
41static struct irq_chip ipr_irq_chip = { 39static 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}
61EXPORT_SYMBOL(make_ipr_irq); 63EXPORT_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 */
67static 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
138void __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)
157int ipr_irq_demux(int irq) 66int 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
15static struct plat_sci_port sci_platform_data[] = { 17static 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
52static 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
76static 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
88static 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 */
96unsigned 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 */
107void ipr_irq_enable_irlm(void)
108{
109 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
110}
111
112void __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}
262EXPORT_SYMBOL(do_softirq); 262EXPORT_SYMBOL(do_softirq);
263#endif 263#endif
264
265void __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}