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 | |
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>
-rw-r--r-- | arch/sh/Kconfig | 3 | ||||
-rw-r--r-- | arch/sh/boards/titan/setup.c | 27 | ||||
-rw-r--r-- | arch/sh/drivers/pci/ops-titan.c | 24 | ||||
-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 | ||||
-rw-r--r-- | arch/sh/mm/Kconfig | 5 | ||||
-rw-r--r-- | include/asm-sh/irq.h | 32 | ||||
-rw-r--r-- | include/asm-sh/titan.h | 32 |
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 | |||
375 | config CPU_HAS_INTC2_IRQ | 375 | config CPU_HAS_INTC2_IRQ |
376 | bool | 376 | bool |
377 | 377 | ||
378 | config CPU_HAS_IPR_IRQ | ||
379 | bool | ||
380 | |||
378 | config CPU_HAS_SR_RB | 381 | config 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 | ||
10 | extern void __init pcibios_init_platform(void); | ||
11 | |||
12 | static struct ipr_data titan_ipr_map[] = { | 15 | static 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 | ||
19 | static void __init init_titan_irq(void) | 23 | static 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 | }; |
52 | ALIAS_MV(titan) | 55 | ALIAS_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 | ||
22 | static 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 | |||
22 | int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) | 30 | int __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 | # |
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 | } | ||
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" | |||
104 | config CPU_SUBTYPE_SH7750 | 104 | config 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 | ||
123 | config CPU_SUBTYPE_SH7750S | 125 | config 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 | ||
128 | config CPU_SUBTYPE_SH7751 | 131 | config 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 | ||
140 | config CPU_SUBTYPE_SH7760 | 145 | config 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 | */ |
98 | extern void make_maskreg_irq(unsigned int irq); | 104 | extern void make_maskreg_irq(unsigned int irq); |
@@ -103,18 +109,36 @@ extern unsigned short *irq_mask_register; | |||
103 | */ | 109 | */ |
104 | void init_IRQ_pint(void); | 110 | void 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 | */ | ||
106 | struct ipr_data { | 118 | struct 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 | */ | ||
129 | unsigned int map_ipridx_to_addr(int idx); | ||
130 | |||
131 | /* | ||
132 | * Enable individual interrupt mode for external IPR IRQs. | ||
133 | */ | ||
134 | void ipr_irq_enable_irlm(void); | ||
135 | |||
136 | /* | ||
114 | * Function for "on chip support modules". | 137 | * Function for "on chip support modules". |
115 | */ | 138 | */ |
116 | extern void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs); | 139 | void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs); |
117 | extern void make_imask_irq(unsigned int irq); | 140 | void make_imask_irq(unsigned int irq); |
141 | void init_IRQ_ipr(void); | ||
118 | 142 | ||
119 | struct intc2_data { | 143 | struct 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 | ||