aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--arch/sh/Kconfig3
-rw-r--r--arch/sh/boards/titan/setup.c27
-rw-r--r--arch/sh/drivers/pci/ops-titan.c24
-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
-rw-r--r--arch/sh/mm/Kconfig5
-rw-r--r--include/asm-sh/irq.h32
-rw-r--r--include/asm-sh/titan.h32
10 files changed, 165 insertions, 159 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 013732074d35..d83d64af31f2 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -375,6 +375,9 @@ config CPU_HAS_MASKREG_IRQ
375config CPU_HAS_INTC2_IRQ 375config CPU_HAS_INTC2_IRQ
376 bool 376 bool
377 377
378config CPU_HAS_IPR_IRQ
379 bool
380
378config CPU_HAS_SR_RB 381config CPU_HAS_SR_RB
379 bool "CPU has SR.RB" 382 bool "CPU has SR.RB"
380 depends on CPU_SH3 || CPU_SH4 383 depends on CPU_SH3 || CPU_SH4
diff --git a/arch/sh/boards/titan/setup.c b/arch/sh/boards/titan/setup.c
index a6046d93758b..6bcd939bfaed 100644
--- a/arch/sh/boards/titan/setup.c
+++ b/arch/sh/boards/titan/setup.c
@@ -1,26 +1,30 @@
1/* 1/*
2 * Setup for Titan 2 * arch/sh/boards/titan/setup.c - Setup for Titan
3 *
4 * Copyright (C) 2006 Jamie Lenehan
5 *
6 * 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 * for more details.
3 */ 9 */
4
5#include <linux/init.h> 10#include <linux/init.h>
6#include <asm/irq.h> 11#include <linux/irq.h>
7#include <asm/titan.h> 12#include <asm/titan.h>
8#include <asm/io.h> 13#include <asm/io.h>
9 14
10extern void __init pcibios_init_platform(void);
11
12static struct ipr_data titan_ipr_map[] = { 15static struct ipr_data titan_ipr_map[] = {
13 { TITAN_IRQ_WAN, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY }, 16 /* IRQ, IPR idx, shift, prio */
14 { TITAN_IRQ_LAN, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY }, 17 { TITAN_IRQ_WAN, 3, 12, 8 }, /* eth0 (WAN) */
15 { TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY }, 18 { TITAN_IRQ_LAN, 3, 8, 8 }, /* eth1 (LAN) */
16 { TITAN_IRQ_USB, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY }, 19 { TITAN_IRQ_MPCIA, 3, 4, 8 }, /* mPCI A (top) */
20 { TITAN_IRQ_USB, 3, 0, 8 }, /* mPCI B (bottom), USB */
17}; 21};
18 22
19static void __init init_titan_irq(void) 23static void __init init_titan_irq(void)
20{ 24{
21 /* enable individual interrupt mode for externals */ 25 /* enable individual interrupt mode for externals */
22 ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); 26 ipr_irq_enable_irlm();
23 27 /* register ipr irqs */
24 make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map)); 28 make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map));
25} 29}
26 30
@@ -47,6 +51,5 @@ struct sh_machine_vector mv_titan __initmv = {
47 .mv_ioport_map = titan_ioport_map, 51 .mv_ioport_map = titan_ioport_map,
48 52
49 .mv_init_irq = init_titan_irq, 53 .mv_init_irq = init_titan_irq,
50 .mv_init_pci = pcibios_init_platform,
51}; 54};
52ALIAS_MV(titan) 55ALIAS_MV(titan)
diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c
index cd56d53375e7..ac8ee2312cd8 100644
--- a/arch/sh/drivers/pci/ops-titan.c
+++ b/arch/sh/drivers/pci/ops-titan.c
@@ -15,25 +15,21 @@
15#include <linux/types.h> 15#include <linux/types.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/pci.h> 17#include <linux/pci.h>
18#include <asm/io.h> 18#include <linux/io.h>
19#include <asm/titan.h> 19#include <asm/titan.h>
20#include "pci-sh4.h" 20#include "pci-sh4.h"
21 21
22static char titan_irq_tab[] __initdata = {
23 TITAN_IRQ_WAN,
24 TITAN_IRQ_LAN,
25 TITAN_IRQ_MPCIA,
26 TITAN_IRQ_MPCIB,
27 TITAN_IRQ_USB,
28};
29
22int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) 30int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)
23{ 31{
24 int irq = -1; 32 int irq = titan_irq_tab[slot];
25
26 switch (slot) {
27 case 0: irq = TITAN_IRQ_WAN; break; /* eth0 (WAN) */
28 case 1: irq = TITAN_IRQ_LAN; break; /* eth1 (LAN) */
29 case 2: irq = TITAN_IRQ_MPCIA; break; /* mPCI A */
30 case 3: irq = TITAN_IRQ_MPCIB; break; /* mPCI B */
31 case 4: irq = TITAN_IRQ_USB; break; /* USB */
32 default:
33 printk(KERN_INFO "PCI: Bad IRQ mapping "
34 "request for slot %d\n", slot);
35 return -1;
36 }
37 33
38 printk("PCI: Mapping TITAN IRQ for slot %d, pin %c to irq %d\n", 34 printk("PCI: Mapping TITAN IRQ for slot %d, pin %c to irq %d\n",
39 slot, pin - 1 + 'A', irq); 35 slot, pin - 1 + 'A', irq);
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}
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 6cd6d0045d16..4e0362f50384 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -104,6 +104,7 @@ comment "SH-4 Processor Support"
104config CPU_SUBTYPE_SH7750 104config CPU_SUBTYPE_SH7750
105 bool "Support SH7750 processor" 105 bool "Support SH7750 processor"
106 select CPU_SH4 106 select CPU_SH4
107 select CPU_HAS_IPR_IRQ
107 help 108 help
108 Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU. 109 Select SH7750 if you have a 200 Mhz SH-4 HD6417750 CPU.
109 110
@@ -119,15 +120,18 @@ config CPU_SUBTYPE_SH7750R
119 bool "Support SH7750R processor" 120 bool "Support SH7750R processor"
120 select CPU_SH4 121 select CPU_SH4
121 select CPU_SUBTYPE_SH7750 122 select CPU_SUBTYPE_SH7750
123 select CPU_HAS_IPR_IRQ
122 124
123config CPU_SUBTYPE_SH7750S 125config CPU_SUBTYPE_SH7750S
124 bool "Support SH7750S processor" 126 bool "Support SH7750S processor"
125 select CPU_SH4 127 select CPU_SH4
126 select CPU_SUBTYPE_SH7750 128 select CPU_SUBTYPE_SH7750
129 select CPU_HAS_IPR_IRQ
127 130
128config CPU_SUBTYPE_SH7751 131config CPU_SUBTYPE_SH7751
129 bool "Support SH7751 processor" 132 bool "Support SH7751 processor"
130 select CPU_SH4 133 select CPU_SH4
134 select CPU_HAS_IPR_IRQ
131 help 135 help
132 Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU, 136 Select SH7751 if you have a 166 Mhz SH-4 HD6417751 CPU,
133 or if you have a HD6417751R CPU. 137 or if you have a HD6417751R CPU.
@@ -136,6 +140,7 @@ config CPU_SUBTYPE_SH7751R
136 bool "Support SH7751R processor" 140 bool "Support SH7751R processor"
137 select CPU_SH4 141 select CPU_SH4
138 select CPU_SUBTYPE_SH7751 142 select CPU_SUBTYPE_SH7751
143 select CPU_HAS_IPR_IRQ
139 144
140config CPU_SUBTYPE_SH7760 145config CPU_SUBTYPE_SH7760
141 bool "Support SH7760 processor" 146 bool "Support SH7760 processor"
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h
index f10cfc10227e..fd576088e47e 100644
--- a/include/asm-sh/irq.h
+++ b/include/asm-sh/irq.h
@@ -93,6 +93,12 @@
93#define NR_IRQS (ONCHIP_NR_IRQS + PINT_NR_IRQS + OFFCHIP_NR_IRQS) 93#define NR_IRQS (ONCHIP_NR_IRQS + PINT_NR_IRQS + OFFCHIP_NR_IRQS)
94 94
95/* 95/*
96 * Convert back and forth between INTEVT and IRQ values.
97 */
98#define evt2irq(evt) (((evt) >> 5) - 16)
99#define irq2evt(irq) (((irq) + 16) << 5)
100
101/*
96 * Simple Mask Register Support 102 * Simple Mask Register Support
97 */ 103 */
98extern void make_maskreg_irq(unsigned int irq); 104extern void make_maskreg_irq(unsigned int irq);
@@ -103,18 +109,36 @@ extern unsigned short *irq_mask_register;
103 */ 109 */
104void init_IRQ_pint(void); 110void init_IRQ_pint(void);
105 111
112/*
113 * The shift value is now the number of bits to shift, not the number of
114 * bits/4. This is to make it easier to read the value directly from the
115 * datasheets. The IPR address, addr, will be set from ipr_idx via the
116 * map_ipridx_to_addr function.
117 */
106struct ipr_data { 118struct ipr_data {
107 unsigned int irq; 119 unsigned int irq;
108 unsigned int addr; /* Address of Interrupt Priority Register */ 120 int ipr_idx; /* Index for the IPR registered */
109 int shift; /* Shifts of the 16-bit data */ 121 int shift; /* Number of bits to shift the data */
110 int priority; /* The priority */ 122 int priority; /* The priority */
123 unsigned int addr; /* Address of Interrupt Priority Register */
111}; 124};
112 125
113/* 126/*
127 * Given an IPR IDX, map the value to an IPR register address.
128 */
129unsigned int map_ipridx_to_addr(int idx);
130
131/*
132 * Enable individual interrupt mode for external IPR IRQs.
133 */
134void ipr_irq_enable_irlm(void);
135
136/*
114 * Function for "on chip support modules". 137 * Function for "on chip support modules".
115 */ 138 */
116extern void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs); 139void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs);
117extern void make_imask_irq(unsigned int irq); 140void make_imask_irq(unsigned int irq);
141void init_IRQ_ipr(void);
118 142
119struct intc2_data { 143struct intc2_data {
120 unsigned short irq; 144 unsigned short irq;
diff --git a/include/asm-sh/titan.h b/include/asm-sh/titan.h
index 270a4f4bc8a9..03f3583c8918 100644
--- a/include/asm-sh/titan.h
+++ b/include/asm-sh/titan.h
@@ -1,9 +1,8 @@
1/* 1/*
2 * Platform defintions for Titan 2 * Platform defintions for Titan
3 */ 3 */
4 4#ifndef _ASM_SH_TITAN_H
5#ifndef _ASM_SH_TITAN_TITAN_H 5#define _ASM_SH_TITAN_H
6#define _ASM_SH_TITAN_TITAN_H
7 6
8#define __IO_PREFIX titan 7#define __IO_PREFIX titan
9#include <asm/io_generic.h> 8#include <asm/io_generic.h>
@@ -15,29 +14,4 @@
15#define TITAN_IRQ_MPCIB 11 /* mPCI B */ 14#define TITAN_IRQ_MPCIB 11 /* mPCI B */
16#define TITAN_IRQ_USB 11 /* USB */ 15#define TITAN_IRQ_USB 11 /* USB */
17 16
18/* 17#endif /* __ASM_SH_TITAN_H */
19 * The external interrupt lines, these take up ints 0 - 15 inclusive
20 * depending on the priority for the interrupt. In fact the priority
21 * is the interrupt :-)
22 */
23#define IRL0_IRQ 0
24#define IRL0_IPR_ADDR INTC_IPRD
25#define IRL0_IPR_POS 3
26#define IRL0_PRIORITY 8
27
28#define IRL1_IRQ 1
29#define IRL1_IPR_ADDR INTC_IPRD
30#define IRL1_IPR_POS 2
31#define IRL1_PRIORITY 8
32
33#define IRL2_IRQ 2
34#define IRL2_IPR_ADDR INTC_IPRD
35#define IRL2_IPR_POS 1
36#define IRL2_PRIORITY 8
37
38#define IRL3_IRQ 3
39#define IRL3_IPR_ADDR INTC_IPRD
40#define IRL3_IPR_POS 0
41#define IRL3_PRIORITY 8
42
43#endif