diff options
author | Magnus Damm <damm@igel.co.jp> | 2007-06-15 05:56:19 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2007-06-15 05:56:19 -0400 |
commit | 68abdbbb03476a60d932eeba0035dd5069afec38 (patch) | |
tree | de3854f76d6d9aec121c432a3cd276bb756003c9 /arch | |
parent | 50f63f2518ee68bc132d357d2b6fdb7f60ef79e0 (diff) |
sh: rework ipr code
This patch reworks the ipr code by grouping the offset array together
with the ipr_data structure in a new data structure called ipr_desc.
This new structure also contains the name of the controller in struct
irq_chip. The idea behind putting struct irq_chip in there is that we
can use offsetof() to locate the base addresses in the irq_chip
callbacks. This strategy has much in common with the recently merged
intc2 code.
One logic change has been made - the original ipr code enabled the
interrupts by default but with this patch they are all disabled by
default.
Signed-off-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sh/boards/se/770x/irq.c | 124 | ||||
-rw-r--r-- | arch/sh/boards/se/7722/irq.c | 15 | ||||
-rw-r--r-- | arch/sh/boards/se/7751/irq.c | 59 | ||||
-rw-r--r-- | arch/sh/boards/sh03/setup.c | 28 | ||||
-rw-r--r-- | arch/sh/boards/shmin/setup.c | 30 | ||||
-rw-r--r-- | arch/sh/boards/snapgear/setup.c | 28 | ||||
-rw-r--r-- | arch/sh/boards/titan/setup.c | 22 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/irq/ipr.c | 59 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh2/setup-sh7619.c | 24 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 24 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/setup-sh7705.c | 40 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/setup-sh7709.c | 84 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/setup-sh7710.c | 42 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/setup-sh7750.c | 58 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/setup-sh7760.c | 32 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 21 |
16 files changed, 404 insertions, 286 deletions
diff --git a/arch/sh/boards/se/770x/irq.c b/arch/sh/boards/se/770x/irq.c index c8eccff77a04..cdb0807928a5 100644 --- a/arch/sh/boards/se/770x/irq.c +++ b/arch/sh/boards/se/770x/irq.c | |||
@@ -15,46 +15,7 @@ | |||
15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
16 | #include <asm/se.h> | 16 | #include <asm/se.h> |
17 | 17 | ||
18 | /* | 18 | static struct ipr_data ipr_irq_table[] = { |
19 | * If the problem of make_ipr_irq is solved, | ||
20 | * this code will become unnecessary. :-) | ||
21 | */ | ||
22 | static void se770x_disable_ipr_irq(unsigned int irq) | ||
23 | { | ||
24 | struct ipr_data *p = get_irq_chip_data(irq); | ||
25 | |||
26 | ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr); | ||
27 | } | ||
28 | |||
29 | static void se770x_enable_ipr_irq(unsigned int irq) | ||
30 | { | ||
31 | struct ipr_data *p = get_irq_chip_data(irq); | ||
32 | |||
33 | ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr); | ||
34 | } | ||
35 | |||
36 | static struct irq_chip se770x_irq_chip = { | ||
37 | .name = "MS770xSE-FPGA", | ||
38 | .mask = se770x_disable_ipr_irq, | ||
39 | .unmask = se770x_enable_ipr_irq, | ||
40 | .mask_ack = se770x_disable_ipr_irq, | ||
41 | }; | ||
42 | |||
43 | void make_se770x_irq(struct ipr_data *table, unsigned int nr_irqs) | ||
44 | { | ||
45 | int i; | ||
46 | |||
47 | for (i = 0; i < nr_irqs; i++) { | ||
48 | unsigned int irq = table[i].irq; | ||
49 | disable_irq_nosync(irq); | ||
50 | set_irq_chip_and_handler_name(irq, &se770x_irq_chip, | ||
51 | handle_level_irq, "level"); | ||
52 | set_irq_chip_data(irq, &table[i]); | ||
53 | se770x_enable_ipr_irq(irq); | ||
54 | } | ||
55 | } | ||
56 | |||
57 | static struct ipr_data se770x_ipr_map[] = { | ||
58 | /* | 19 | /* |
59 | * Super I/O (Just mimic PC): | 20 | * Super I/O (Just mimic PC): |
60 | * 1: keyboard | 21 | * 1: keyboard |
@@ -68,46 +29,67 @@ static struct ipr_data se770x_ipr_map[] = { | |||
68 | */ | 29 | */ |
69 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) | 30 | #if defined(CONFIG_CPU_SUBTYPE_SH7705) |
70 | /* This is default value */ | 31 | /* This is default value */ |
71 | { 13, 0, 8, 0x0f-13 ,BCR_ILCRA}, | 32 | { 13, 0, 8, 0x0f-13, }, |
72 | { 5 , 0, 4, 0x0f- 5 ,BCR_ILCRA}, | 33 | { 5 , 0, 4, 0x0f- 5, }, |
73 | { 10, 0, 0, 0x0f-10, BCR_ILCRB}, | 34 | { 10, 1, 0, 0x0f-10, }, |
74 | { 7 , 0, 4, 0x0f- 7, BCR_ILCRC}, | 35 | { 7 , 2, 4, 0x0f- 7, }, |
75 | { 3 , 0, 0, 0x0f- 3, BCR_ILCRC}, | 36 | { 3 , 2, 0, 0x0f- 3, }, |
76 | { 1 , 0, 12, 0x0f- 1, BCR_ILCRD}, | 37 | { 1 , 3, 12, 0x0f- 1, }, |
77 | { 12, 0, 4, 0x0f-12, BCR_ILCRD}, /* LAN */ | 38 | { 12, 3, 4, 0x0f-12, }, /* LAN */ |
78 | { 2 , 0, 8, 0x0f- 2, BCR_ILCRE}, /* PCIRQ2 */ | 39 | { 2 , 4, 8, 0x0f- 2, }, /* PCIRQ2 */ |
79 | { 6 , 0, 4, 0x0f- 6, BCR_ILCRE}, /* PCIRQ1 */ | 40 | { 6 , 4, 4, 0x0f- 6, }, /* PCIRQ1 */ |
80 | { 14, 0, 0, 0x0f-14, BCR_ILCRE}, /* PCIRQ0 */ | 41 | { 14, 4, 0, 0x0f-14, }, /* PCIRQ0 */ |
81 | { 0 , 0, 12, 0x0f , BCR_ILCRF}, | 42 | { 0 , 5, 12, 0x0f , }, |
82 | { 4 , 0, 4, 0x0f- 4, BCR_ILCRF}, | 43 | { 4 , 5, 4, 0x0f- 4, }, |
83 | { 8 , 0, 12, 0x0f- 8, BCR_ILCRG}, | 44 | { 8 , 6, 12, 0x0f- 8, }, |
84 | { 9 , 0, 8, 0x0f- 9, BCR_ILCRG}, | 45 | { 9 , 6, 8, 0x0f- 9, }, |
85 | { 11, 0, 4, 0x0f-11, BCR_ILCRG}, | 46 | { 11, 6, 4, 0x0f-11, }, |
86 | #else | 47 | #else |
87 | { 14, 0, 8, 0x0f-14 ,BCR_ILCRA}, | 48 | { 14, 0, 8, 0x0f-14, }, |
88 | { 12, 0, 4, 0x0f-12 ,BCR_ILCRA}, | 49 | { 12, 0, 4, 0x0f-12, }, |
89 | { 8, 0, 4, 0x0f- 8 ,BCR_ILCRB}, | 50 | { 8, 1, 4, 0x0f- 8, }, |
90 | { 6, 0, 12, 0x0f- 6 ,BCR_ILCRC}, | 51 | { 6, 2, 12, 0x0f- 6, }, |
91 | { 5, 0, 8, 0x0f- 5 ,BCR_ILCRC}, | 52 | { 5, 2, 8, 0x0f- 5, }, |
92 | { 4, 0, 4, 0x0f- 4 ,BCR_ILCRC}, | 53 | { 4, 2, 4, 0x0f- 4, }, |
93 | { 3, 0, 0, 0x0f- 3 ,BCR_ILCRC}, | 54 | { 3, 2, 0, 0x0f- 3, }, |
94 | { 1, 0, 12, 0x0f- 1 ,BCR_ILCRD}, | 55 | { 1, 3, 12, 0x0f- 1, }, |
95 | #if defined(CONFIG_STNIC) | 56 | #if defined(CONFIG_STNIC) |
96 | /* ST NIC */ | 57 | /* ST NIC */ |
97 | { 10, 0, 4, 0x0f-10 ,BCR_ILCRD}, /* LAN */ | 58 | { 10, 3, 4, 0x0f-10, }, /* LAN */ |
98 | #endif | 59 | #endif |
99 | /* MRSHPC IRQs setting */ | 60 | /* MRSHPC IRQs setting */ |
100 | { 0, 0, 12, 0x0f- 0 ,BCR_ILCRE}, /* PCIRQ3 */ | 61 | { 0, 4, 12, 0x0f- 0, }, /* PCIRQ3 */ |
101 | { 11, 0, 8, 0x0f-11 ,BCR_ILCRE}, /* PCIRQ2 */ | 62 | { 11, 4, 8, 0x0f-11, }, /* PCIRQ2 */ |
102 | { 9, 0, 4, 0x0f- 9 ,BCR_ILCRE}, /* PCIRQ1 */ | 63 | { 9, 4, 4, 0x0f- 9, }, /* PCIRQ1 */ |
103 | { 7, 0, 0, 0x0f- 7 ,BCR_ILCRE}, /* PCIRQ0 */ | 64 | { 7, 4, 0, 0x0f- 7, }, /* PCIRQ0 */ |
104 | /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ | 65 | /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ |
105 | /* NOTE: #2 and #13 are not used on PC */ | 66 | /* NOTE: #2 and #13 are not used on PC */ |
106 | { 13, 0, 4, 0x0f-13 ,BCR_ILCRG}, /* SLOTIRQ2 */ | 67 | { 13, 6, 4, 0x0f-13, }, /* SLOTIRQ2 */ |
107 | { 2, 0, 0, 0x0f- 2 ,BCR_ILCRG}, /* SLOTIRQ1 */ | 68 | { 2, 6, 0, 0x0f- 2, }, /* SLOTIRQ1 */ |
108 | #endif | 69 | #endif |
109 | }; | 70 | }; |
110 | 71 | ||
72 | static unsigned long ipr_offsets[] = { | ||
73 | BCR_ILCRA, | ||
74 | BCR_ILCRB, | ||
75 | BCR_ILCRC, | ||
76 | BCR_ILCRD, | ||
77 | BCR_ILCRE, | ||
78 | BCR_ILCRF, | ||
79 | BCR_ILCRG, | ||
80 | }; | ||
81 | |||
82 | static struct ipr_desc ipr_irq_desc = { | ||
83 | .ipr_offsets = ipr_offsets, | ||
84 | .nr_offsets = ARRAY_SIZE(ipr_offsets), | ||
85 | |||
86 | .ipr_data = ipr_irq_table, | ||
87 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), | ||
88 | .chip = { | ||
89 | .name = "IPR-se770x", | ||
90 | }, | ||
91 | }; | ||
92 | |||
111 | /* | 93 | /* |
112 | * Initialize IRQ setting | 94 | * Initialize IRQ setting |
113 | */ | 95 | */ |
@@ -122,5 +104,5 @@ void __init init_se_IRQ(void) | |||
122 | ctrl_outw(0, BCR_ILCRF); | 104 | ctrl_outw(0, BCR_ILCRF); |
123 | ctrl_outw(0, BCR_ILCRG); | 105 | ctrl_outw(0, BCR_ILCRG); |
124 | 106 | ||
125 | make_se770x_irq(se770x_ipr_map, ARRAY_SIZE(se770x_ipr_map)); | 107 | register_ipr_controller(&ipr_irq_desc); |
126 | } | 108 | } |
diff --git a/arch/sh/boards/se/7722/irq.c b/arch/sh/boards/se/7722/irq.c index 099e5deb77f8..26cff0efda40 100644 --- a/arch/sh/boards/se/7722/irq.c +++ b/arch/sh/boards/se/7722/irq.c | |||
@@ -19,15 +19,24 @@ | |||
19 | #define INTC_INTMSK0 0xFFD00044 | 19 | #define INTC_INTMSK0 0xFFD00044 |
20 | #define INTC_INTMSKCLR0 0xFFD00064 | 20 | #define INTC_INTMSKCLR0 0xFFD00064 |
21 | 21 | ||
22 | struct se7722_data { | ||
23 | unsigned char irq; | ||
24 | unsigned char ipr_idx; | ||
25 | unsigned char shift; | ||
26 | unsigned short priority; | ||
27 | unsigned long addr; | ||
28 | }; | ||
29 | |||
30 | |||
22 | static void disable_se7722_irq(unsigned int irq) | 31 | static void disable_se7722_irq(unsigned int irq) |
23 | { | 32 | { |
24 | struct ipr_data *p = get_irq_chip_data(irq); | 33 | struct se7722_data *p = get_irq_chip_data(irq); |
25 | ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr ); | 34 | ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr ); |
26 | } | 35 | } |
27 | 36 | ||
28 | static void enable_se7722_irq(unsigned int irq) | 37 | static void enable_se7722_irq(unsigned int irq) |
29 | { | 38 | { |
30 | struct ipr_data *p = get_irq_chip_data(irq); | 39 | struct se7722_data *p = get_irq_chip_data(irq); |
31 | ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr ); | 40 | ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr ); |
32 | } | 41 | } |
33 | 42 | ||
@@ -38,7 +47,7 @@ static struct irq_chip se7722_irq_chip __read_mostly = { | |||
38 | .mask_ack = disable_se7722_irq, | 47 | .mask_ack = disable_se7722_irq, |
39 | }; | 48 | }; |
40 | 49 | ||
41 | static struct ipr_data ipr_irq_table[] = { | 50 | static struct se7722_data ipr_irq_table[] = { |
42 | /* irq ,idx,sft, priority , addr */ | 51 | /* irq ,idx,sft, priority , addr */ |
43 | { MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } , | 52 | { MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } , |
44 | { MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } , | 53 | { MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } , |
diff --git a/arch/sh/boards/se/7751/irq.c b/arch/sh/boards/se/7751/irq.c index e4c63a48296c..c3d12590e5db 100644 --- a/arch/sh/boards/se/7751/irq.c +++ b/arch/sh/boards/se/7751/irq.c | |||
@@ -14,44 +14,31 @@ | |||
14 | #include <asm/irq.h> | 14 | #include <asm/irq.h> |
15 | #include <asm/se7751.h> | 15 | #include <asm/se7751.h> |
16 | 16 | ||
17 | static struct ipr_data se7751_ipr_map[] = { | 17 | static struct ipr_data ipr_irq_table[] = { |
18 | /* Leave old Solution Engine code in for reference. */ | 18 | { 13, 3, 3, 2 }, |
19 | #if defined(CONFIG_SH_SOLUTION_ENGINE) | 19 | /* Add additional entries here as drivers are added and tested. */ |
20 | /* | 20 | }; |
21 | * Super I/O (Just mimic PC): | ||
22 | * 1: keyboard | ||
23 | * 3: serial 0 | ||
24 | * 4: serial 1 | ||
25 | * 5: printer | ||
26 | * 6: floppy | ||
27 | * 8: rtc | ||
28 | * 12: mouse | ||
29 | * 14: ide0 | ||
30 | */ | ||
31 | { 14, BCR_ILCRA, 2, 0x0f-14 }, | ||
32 | { 12, BCR_ILCRA, 1, 0x0f-12 }, | ||
33 | { 8, BCR_ILCRB, 1, 0x0f- 8 }, | ||
34 | { 6, BCR_ILCRC, 3, 0x0f- 6 }, | ||
35 | { 5, BCR_ILCRC, 2, 0x0f- 5 }, | ||
36 | { 4, BCR_ILCRC, 1, 0x0f- 4 }, | ||
37 | { 3, BCR_ILCRC, 0, 0x0f- 3 }, | ||
38 | { 1, BCR_ILCRD, 3, 0x0f- 1 }, | ||
39 | 21 | ||
40 | { 10, BCR_ILCRD, 1, 0x0f-10 }, /* LAN */ | 22 | static unsigned long ipr_offsets[] = { |
23 | BCR_ILCRA, | ||
24 | BCR_ILCRB, | ||
25 | BCR_ILCRC, | ||
26 | BCR_ILCRD, | ||
27 | BCR_ILCRE, | ||
28 | BCR_ILCRF, | ||
29 | BCR_ILCRG, | ||
30 | }; | ||
41 | 31 | ||
42 | { 0, BCR_ILCRE, 3, 0x0f- 0 }, /* PCIRQ3 */ | 32 | static struct ipr_desc ipr_irq_desc = { |
43 | { 11, BCR_ILCRE, 2, 0x0f-11 }, /* PCIRQ2 */ | 33 | .ipr_offsets = ipr_offsets, |
44 | { 9, BCR_ILCRE, 1, 0x0f- 9 }, /* PCIRQ1 */ | 34 | .nr_offsets = ARRAY_SIZE(ipr_offsets), |
45 | { 7, BCR_ILCRE, 0, 0x0f- 7 }, /* PCIRQ0 */ | ||
46 | 35 | ||
47 | /* #2, #13 are allocated for SLOT IRQ #1 and #2 (for now) */ | 36 | .ipr_data = ipr_irq_table, |
48 | /* NOTE: #2 and #13 are not used on PC */ | 37 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), |
49 | { 13, BCR_ILCRG, 1, 0x0f-13 }, /* SLOTIRQ2 */ | 38 | |
50 | { 2, BCR_ILCRG, 0, 0x0f- 2 }, /* SLOTIRQ1 */ | 39 | .chip = { |
51 | #elif defined(CONFIG_SH_7751_SOLUTION_ENGINE) | 40 | .name = "IPR-se7751", |
52 | { 13, BCR_ILCRD, 3, 2 }, | 41 | }, |
53 | /* Add additional entries here as drivers are added and tested. */ | ||
54 | #endif | ||
55 | }; | 42 | }; |
56 | 43 | ||
57 | /* | 44 | /* |
@@ -59,5 +46,5 @@ static struct ipr_data se7751_ipr_map[] = { | |||
59 | */ | 46 | */ |
60 | void __init init_7751se_IRQ(void) | 47 | void __init init_7751se_IRQ(void) |
61 | { | 48 | { |
62 | make_ipr_irq(se7751_ipr_map, ARRAY_SIZE(se7751_ipr_map)); | 49 | register_ipr_controller(&ipr_irq_desc); |
63 | } | 50 | } |
diff --git a/arch/sh/boards/sh03/setup.c b/arch/sh/boards/sh03/setup.c index d7867c190a96..9c031a8c0a1c 100644 --- a/arch/sh/boards/sh03/setup.c +++ b/arch/sh/boards/sh03/setup.c | |||
@@ -15,17 +15,33 @@ | |||
15 | #include <asm/sh03/sh03.h> | 15 | #include <asm/sh03/sh03.h> |
16 | #include <asm/addrspace.h> | 16 | #include <asm/addrspace.h> |
17 | 17 | ||
18 | static struct ipr_data sh03_ipr_map[] = { | 18 | static struct ipr_data ipr_irq_table[] = { |
19 | { IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY }, | 19 | { IRL0_IRQ, 0, IRL0_IPR_POS, IRL0_PRIORITY }, |
20 | { IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY }, | 20 | { IRL1_IRQ, 0, IRL1_IPR_POS, IRL1_PRIORITY }, |
21 | { IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY }, | 21 | { IRL2_IRQ, 0, IRL2_IPR_POS, IRL2_PRIORITY }, |
22 | { IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY }, | 22 | { IRL3_IRQ, 0, IRL3_IPR_POS, IRL3_PRIORITY }, |
23 | }; | ||
24 | |||
25 | static unsigned long ipr_offsets[] = { | ||
26 | INTC_IPRD, | ||
27 | }; | ||
28 | |||
29 | static struct ipr_desc ipr_irq_desc = { | ||
30 | .ipr_offsets = ipr_offsets, | ||
31 | .nr_offsets = ARRAY_SIZE(ipr_offsets), | ||
32 | |||
33 | .ipr_data = ipr_irq_table, | ||
34 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), | ||
35 | |||
36 | .chip = { | ||
37 | .name = "IPR-sh03", | ||
38 | }, | ||
23 | }; | 39 | }; |
24 | 40 | ||
25 | static void __init init_sh03_IRQ(void) | 41 | static void __init init_sh03_IRQ(void) |
26 | { | 42 | { |
27 | ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); | 43 | ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); |
28 | make_ipr_irq(sh03_ipr_map, ARRAY_SIZE(sh03_ipr_map)); | 44 | register_ipr_controller(&ipr_irq_desc); |
29 | } | 45 | } |
30 | 46 | ||
31 | extern void *cf_io_base; | 47 | extern void *cf_io_base; |
diff --git a/arch/sh/boards/shmin/setup.c b/arch/sh/boards/shmin/setup.c index 9c8bb51eb4bb..dfd124509f42 100644 --- a/arch/sh/boards/shmin/setup.c +++ b/arch/sh/boards/shmin/setup.c | |||
@@ -6,28 +6,44 @@ | |||
6 | * SHMIN Support. | 6 | * SHMIN Support. |
7 | */ | 7 | */ |
8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
9 | #include <linux/irq.h> | ||
9 | #include <asm/machvec.h> | 10 | #include <asm/machvec.h> |
10 | #include <asm/shmin.h> | 11 | #include <asm/shmin.h> |
11 | #include <asm/clock.h> | 12 | #include <asm/clock.h> |
12 | #include <asm/irq.h> | ||
13 | #include <asm/io.h> | 13 | #include <asm/io.h> |
14 | 14 | ||
15 | #define PFC_PHCR 0xa400010eUL | 15 | #define PFC_PHCR 0xa400010eUL |
16 | #define INTC_ICR1 0xa4000010UL | 16 | #define INTC_ICR1 0xa4000010UL |
17 | #define INTC_IPRC 0xa4000016UL | 17 | #define INTC_IPRC 0xa4000016UL |
18 | 18 | ||
19 | static struct ipr_data shmin_ipr_map[] = { | 19 | static struct ipr_data ipr_irq_table[] = { |
20 | { .irq=32, .addr=INTC_IPRC, .shift= 0, .priority=0 }, | 20 | { 32, 0, 0, 0 }, |
21 | { .irq=33, .addr=INTC_IPRC, .shift= 4, .priority=0 }, | 21 | { 33, 0, 4, 0 }, |
22 | { .irq=34, .addr=INTC_IPRC, .shift= 8, .priority=8 }, | 22 | { 34, 0, 8, 8 }, |
23 | { .irq=35, .addr=INTC_IPRC, .shift=12, .priority=0 }, | 23 | { 35, 0, 12, 0 }, |
24 | }; | ||
25 | |||
26 | static unsigned long ipr_offsets[] = { | ||
27 | INTC_IPRC, | ||
28 | }; | ||
29 | |||
30 | static struct ipr_desc ipr_irq_desc = { | ||
31 | .ipr_offsets = ipr_offsets, | ||
32 | .nr_offsets = ARRAY_SIZE(ipr_offsets), | ||
33 | |||
34 | .ipr_data = ipr_irq_table, | ||
35 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), | ||
36 | |||
37 | .chip = { | ||
38 | .name = "IPR-shmin", | ||
39 | }, | ||
24 | }; | 40 | }; |
25 | 41 | ||
26 | static void __init init_shmin_irq(void) | 42 | static void __init init_shmin_irq(void) |
27 | { | 43 | { |
28 | ctrl_outw(0x2a00, PFC_PHCR); // IRQ0-3=IRQ | 44 | ctrl_outw(0x2a00, PFC_PHCR); // IRQ0-3=IRQ |
29 | ctrl_outw(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active. | 45 | ctrl_outw(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active. |
30 | make_ipr_irq(shmin_ipr_map, ARRAY_SIZE(shmin_ipr_map)); | 46 | register_ipr_controller(&ipr_irq_desc); |
31 | } | 47 | } |
32 | 48 | ||
33 | static void __iomem *shmin_ioport_map(unsigned long port, unsigned int size) | 49 | static void __iomem *shmin_ioport_map(unsigned long port, unsigned int size) |
diff --git a/arch/sh/boards/snapgear/setup.c b/arch/sh/boards/snapgear/setup.c index b40124c092f5..84271d85a8dd 100644 --- a/arch/sh/boards/snapgear/setup.c +++ b/arch/sh/boards/snapgear/setup.c | |||
@@ -68,11 +68,27 @@ module_init(eraseconfig_init); | |||
68 | * IRL3 = crypto | 68 | * IRL3 = crypto |
69 | */ | 69 | */ |
70 | 70 | ||
71 | static struct ipr_data snapgear_ipr_map[] = { | 71 | static struct ipr_data ipr_irq_table[] = { |
72 | make_ipr_irq(IRL0_IRQ, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); | 72 | { IRL0_IRQ, 0, IRL0_IPR_POS, IRL0_PRIORITY }, |
73 | make_ipr_irq(IRL1_IRQ, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); | 73 | { IRL1_IRQ, 0, IRL1_IPR_POS, IRL1_PRIORITY }, |
74 | make_ipr_irq(IRL2_IRQ, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); | 74 | { IRL2_IRQ, 0, IRL2_IPR_POS, IRL2_PRIORITY }, |
75 | make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); | 75 | { IRL3_IRQ, 0, IRL3_IPR_POS, IRL3_PRIORITY }, |
76 | }; | ||
77 | |||
78 | static unsigned long ipr_offsets[] = { | ||
79 | INTC_IPRD, | ||
80 | }; | ||
81 | |||
82 | static struct ipr_desc ipr_irq_desc = { | ||
83 | .ipr_offsets = ipr_offsets, | ||
84 | .nr_offsets = ARRAY_SIZE(ipr_offsets), | ||
85 | |||
86 | .ipr_data = ipr_irq_table, | ||
87 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), | ||
88 | |||
89 | .chip = { | ||
90 | .name = "IPR-snapgear", | ||
91 | }, | ||
76 | }; | 92 | }; |
77 | 93 | ||
78 | static void __init init_snapgear_IRQ(void) | 94 | static void __init init_snapgear_IRQ(void) |
@@ -82,7 +98,7 @@ static void __init init_snapgear_IRQ(void) | |||
82 | 98 | ||
83 | printk("Setup SnapGear IRQ/IPR ...\n"); | 99 | printk("Setup SnapGear IRQ/IPR ...\n"); |
84 | 100 | ||
85 | make_ipr_irq(snapgear_ipr_map, ARRAY_SIZE(snapgear_ipr_map)); | 101 | register_ipr_controller(&ipr_irq_desc); |
86 | } | 102 | } |
87 | 103 | ||
88 | /* | 104 | /* |
diff --git a/arch/sh/boards/titan/setup.c b/arch/sh/boards/titan/setup.c index 630f62f69a36..606d25a4b870 100644 --- a/arch/sh/boards/titan/setup.c +++ b/arch/sh/boards/titan/setup.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <asm/titan.h> | 12 | #include <asm/titan.h> |
13 | #include <asm/io.h> | 13 | #include <asm/io.h> |
14 | 14 | ||
15 | static struct ipr_data titan_ipr_map[] = { | 15 | static struct ipr_data ipr_irq_table[] = { |
16 | /* IRQ, IPR idx, shift, prio */ | 16 | /* IRQ, IPR idx, shift, prio */ |
17 | { TITAN_IRQ_WAN, 3, 12, 8 }, /* eth0 (WAN) */ | 17 | { TITAN_IRQ_WAN, 3, 12, 8 }, /* eth0 (WAN) */ |
18 | { TITAN_IRQ_LAN, 3, 8, 8 }, /* eth1 (LAN) */ | 18 | { TITAN_IRQ_LAN, 3, 8, 8 }, /* eth1 (LAN) */ |
@@ -20,12 +20,30 @@ static struct ipr_data titan_ipr_map[] = { | |||
20 | { TITAN_IRQ_USB, 3, 0, 8 }, /* mPCI B (bottom), USB */ | 20 | { TITAN_IRQ_USB, 3, 0, 8 }, /* mPCI B (bottom), USB */ |
21 | }; | 21 | }; |
22 | 22 | ||
23 | static unsigned long ipr_offsets[] = { /* stolen from setup-sh7750.c */ | ||
24 | 0xffd00004UL, /* 0: IPRA */ | ||
25 | 0xffd00008UL, /* 1: IPRB */ | ||
26 | 0xffd0000cUL, /* 2: IPRC */ | ||
27 | 0xffd00010UL, /* 3: IPRD */ | ||
28 | }; | ||
29 | |||
30 | static struct ipr_desc ipr_irq_desc = { | ||
31 | .ipr_offsets = ipr_offsets, | ||
32 | .nr_offsets = ARRAY_SIZE(ipr_offsets), | ||
33 | |||
34 | .ipr_data = ipr_irq_table, | ||
35 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), | ||
36 | |||
37 | .chip = { | ||
38 | .name = "IPR-titan", | ||
39 | }, | ||
40 | }; | ||
23 | static void __init init_titan_irq(void) | 41 | static void __init init_titan_irq(void) |
24 | { | 42 | { |
25 | /* enable individual interrupt mode for externals */ | 43 | /* enable individual interrupt mode for externals */ |
26 | ipr_irq_enable_irlm(); | 44 | ipr_irq_enable_irlm(); |
27 | /* register ipr irqs */ | 45 | /* register ipr irqs */ |
28 | make_ipr_irq(titan_ipr_map, ARRAY_SIZE(titan_ipr_map)); | 46 | register_ipr_controller(&ipr_irq_desc); |
29 | } | 47 | } |
30 | 48 | ||
31 | static struct sh_machine_vector mv_titan __initmv = { | 49 | static struct sh_machine_vector mv_titan __initmv = { |
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index 210280b6fddf..98e84f40c713 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c | |||
@@ -22,58 +22,57 @@ | |||
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | 24 | ||
25 | static inline struct ipr_desc *get_ipr_desc(unsigned int irq) | ||
26 | { | ||
27 | struct irq_chip *chip = get_irq_chip(irq); | ||
28 | return (void *)((char *)chip - offsetof(struct ipr_desc, chip)); | ||
29 | } | ||
30 | |||
25 | static void disable_ipr_irq(unsigned int irq) | 31 | static void disable_ipr_irq(unsigned int irq) |
26 | { | 32 | { |
27 | struct ipr_data *p = get_irq_chip_data(irq); | 33 | struct ipr_data *p = get_irq_chip_data(irq); |
34 | unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx]; | ||
28 | /* Set the priority in IPR to 0 */ | 35 | /* Set the priority in IPR to 0 */ |
29 | ctrl_outw(ctrl_inw(p->addr) & (0xffff ^ (0xf << p->shift)), p->addr); | 36 | ctrl_outw(ctrl_inw(addr) & (0xffff ^ (0xf << p->shift)), addr); |
30 | } | 37 | } |
31 | 38 | ||
32 | static void enable_ipr_irq(unsigned int irq) | 39 | static void enable_ipr_irq(unsigned int irq) |
33 | { | 40 | { |
34 | struct ipr_data *p = get_irq_chip_data(irq); | 41 | struct ipr_data *p = get_irq_chip_data(irq); |
42 | unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx]; | ||
35 | /* Set priority in IPR back to original value */ | 43 | /* Set priority in IPR back to original value */ |
36 | ctrl_outw(ctrl_inw(p->addr) | (p->priority << p->shift), p->addr); | 44 | ctrl_outw(ctrl_inw(addr) | (p->priority << p->shift), addr); |
37 | } | 45 | } |
38 | 46 | ||
39 | static struct irq_chip ipr_irq_chip = { | 47 | /* |
40 | .name = "IPR", | 48 | * The shift value is now the number of bits to shift, not the number of |
41 | .mask = disable_ipr_irq, | 49 | * bits/4. This is to make it easier to read the value directly from the |
42 | .unmask = enable_ipr_irq, | 50 | * datasheets. The IPR address is calculated using the ipr_offset table. |
43 | .mask_ack = disable_ipr_irq, | 51 | */ |
44 | }; | ||
45 | |||
46 | unsigned int map_ipridx_to_addr(int idx) __attribute__ ((weak)); | ||
47 | unsigned int map_ipridx_to_addr(int idx) | ||
48 | { | ||
49 | return 0; | ||
50 | } | ||
51 | 52 | ||
52 | void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs) | 53 | void register_ipr_controller(struct ipr_desc *desc) |
53 | { | 54 | { |
54 | int i; | 55 | int i; |
55 | 56 | ||
56 | for (i = 0; i < nr_irqs; i++) { | 57 | desc->chip.mask = disable_ipr_irq; |
57 | unsigned int irq = table[i].irq; | 58 | desc->chip.unmask = enable_ipr_irq; |
59 | desc->chip.mask_ack = disable_ipr_irq; | ||
58 | 60 | ||
59 | if (!irq) | 61 | for (i = 0; i < desc->nr_irqs; i++) { |
60 | irq = table[i].irq = i; | 62 | struct ipr_data *p = desc->ipr_data + i; |
61 | 63 | ||
62 | /* could the IPR index be mapped, if not we ignore this */ | 64 | BUG_ON(p->ipr_idx >= desc->nr_offsets); |
63 | if (!table[i].addr) { | 65 | BUG_ON(!desc->ipr_offsets[p->ipr_idx]); |
64 | table[i].addr = map_ipridx_to_addr(table[i].ipr_idx); | ||
65 | if (!table[i].addr) | ||
66 | continue; | ||
67 | } | ||
68 | 66 | ||
69 | disable_irq_nosync(irq); | 67 | disable_irq_nosync(p->irq); |
70 | set_irq_chip_and_handler_name(irq, &ipr_irq_chip, | 68 | set_irq_chip_and_handler_name(p->irq, &desc->chip, |
71 | handle_level_irq, "level"); | 69 | handle_level_irq, "level"); |
72 | set_irq_chip_data(irq, &table[i]); | 70 | set_irq_chip_data(p->irq, p); |
73 | enable_ipr_irq(irq); | 71 | disable_ipr_irq(p->irq); |
74 | } | 72 | } |
75 | } | 73 | } |
76 | EXPORT_SYMBOL(make_ipr_irq); | 74 | |
75 | EXPORT_SYMBOL(register_ipr_controller); | ||
77 | 76 | ||
78 | #if !defined(CONFIG_CPU_HAS_PINT_IRQ) | 77 | #if !defined(CONFIG_CPU_HAS_PINT_IRQ) |
79 | int ipr_irq_demux(int irq) | 78 | int ipr_irq_demux(int irq) |
diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index f83ff8a68f35..1a107fe22dde 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c | |||
@@ -52,7 +52,7 @@ static int __init sh7619_devices_setup(void) | |||
52 | } | 52 | } |
53 | __initcall(sh7619_devices_setup); | 53 | __initcall(sh7619_devices_setup); |
54 | 54 | ||
55 | static struct ipr_data sh7619_ipr_map[] = { | 55 | static struct ipr_data ipr_irq_table[] = { |
56 | { 86, 0, 4, 2 }, /* CMI0 */ | 56 | { 86, 0, 4, 2 }, /* CMI0 */ |
57 | { 88, 1, 12, 3 }, /* SCIF0_ERI */ | 57 | { 88, 1, 12, 3 }, /* SCIF0_ERI */ |
58 | { 89, 1, 12, 3 }, /* SCIF0_RXI */ | 58 | { 89, 1, 12, 3 }, /* SCIF0_RXI */ |
@@ -68,7 +68,7 @@ static struct ipr_data sh7619_ipr_map[] = { | |||
68 | { 99, 1, 4, 3 }, /* SCIF2_TXI */ | 68 | { 99, 1, 4, 3 }, /* SCIF2_TXI */ |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static unsigned int ipr_offsets[] = { | 71 | static unsigned long ipr_offsets[] = { |
72 | 0xf8080000, /* IPRC */ | 72 | 0xf8080000, /* IPRC */ |
73 | 0xf8080002, /* IPRD */ | 73 | 0xf8080002, /* IPRD */ |
74 | 0xf8080004, /* IPRE */ | 74 | 0xf8080004, /* IPRE */ |
@@ -76,15 +76,19 @@ static unsigned int ipr_offsets[] = { | |||
76 | 0xf8080008, /* IPRG */ | 76 | 0xf8080008, /* IPRG */ |
77 | }; | 77 | }; |
78 | 78 | ||
79 | /* given the IPR index return the address of the IPR register */ | 79 | static struct ipr_desc ipr_irq_desc = { |
80 | unsigned int map_ipridx_to_addr(int idx) | 80 | .ipr_offsets = ipr_offsets, |
81 | { | 81 | .nr_offsets = ARRAY_SIZE(ipr_offsets), |
82 | if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) | 82 | |
83 | return 0; | 83 | .ipr_data = ipr_irq_table, |
84 | return ipr_offsets[idx]; | 84 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), |
85 | } | 85 | |
86 | .chip = { | ||
87 | .name = "IPR-sh7619", | ||
88 | }, | ||
89 | }; | ||
86 | 90 | ||
87 | void __init init_IRQ_ipr(void) | 91 | void __init init_IRQ_ipr(void) |
88 | { | 92 | { |
89 | make_ipr_irq(sh7619_ipr_map, ARRAY_SIZE(sh7619_ipr_map)); | 93 | register_ipr_controller(&ipr_irq_desc); |
90 | } | 94 | } |
diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index 4ed9110632bc..b6e3a6351fa6 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c | |||
@@ -57,7 +57,7 @@ static int __init sh7206_devices_setup(void) | |||
57 | } | 57 | } |
58 | __initcall(sh7206_devices_setup); | 58 | __initcall(sh7206_devices_setup); |
59 | 59 | ||
60 | static struct ipr_data sh7206_ipr_map[] = { | 60 | static struct ipr_data ipr_irq_table[] = { |
61 | { 140, 7, 12, 2 }, /* CMI0 */ | 61 | { 140, 7, 12, 2 }, /* CMI0 */ |
62 | { 164, 8, 4, 2 }, /* MTU2_TGI1A */ | 62 | { 164, 8, 4, 2 }, /* MTU2_TGI1A */ |
63 | { 240, 13, 12, 3 }, /* SCIF0_BRI */ | 63 | { 240, 13, 12, 3 }, /* SCIF0_BRI */ |
@@ -78,7 +78,7 @@ static struct ipr_data sh7206_ipr_map[] = { | |||
78 | { 255, 13, 0, 3 }, /* SCIF3_TXI */ | 78 | { 255, 13, 0, 3 }, /* SCIF3_TXI */ |
79 | }; | 79 | }; |
80 | 80 | ||
81 | static unsigned int ipr_offsets[] = { | 81 | static unsigned long ipr_offsets[] = { |
82 | 0xfffe0818, /* IPR01 */ | 82 | 0xfffe0818, /* IPR01 */ |
83 | 0xfffe081a, /* IPR02 */ | 83 | 0xfffe081a, /* IPR02 */ |
84 | 0, /* unused */ | 84 | 0, /* unused */ |
@@ -95,15 +95,19 @@ static unsigned int ipr_offsets[] = { | |||
95 | 0xfffe0c10, /* IPR14 */ | 95 | 0xfffe0c10, /* IPR14 */ |
96 | }; | 96 | }; |
97 | 97 | ||
98 | /* given the IPR index return the address of the IPR register */ | 98 | static struct ipr_desc ipr_irq_desc = { |
99 | unsigned int map_ipridx_to_addr(int idx) | 99 | .ipr_offsets = ipr_offsets, |
100 | { | 100 | .nr_offsets = ARRAY_SIZE(ipr_offsets), |
101 | if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) | 101 | |
102 | return 0; | 102 | .ipr_data = ipr_irq_table, |
103 | return ipr_offsets[idx]; | 103 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), |
104 | } | 104 | |
105 | .chip = { | ||
106 | .name = "IPR-sh7206", | ||
107 | }, | ||
108 | }; | ||
105 | 109 | ||
106 | void __init init_IRQ_ipr(void) | 110 | void __init init_IRQ_ipr(void) |
107 | { | 111 | { |
108 | make_ipr_irq(sh7206_ipr_map, ARRAY_SIZE(sh7206_ipr_map)); | 112 | register_ipr_controller(&ipr_irq_desc); |
109 | } | 113 | } |
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 1983fb7ad6ea..a55b8ce2c54c 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c | |||
@@ -48,7 +48,7 @@ static int __init sh7705_devices_setup(void) | |||
48 | } | 48 | } |
49 | __initcall(sh7705_devices_setup); | 49 | __initcall(sh7705_devices_setup); |
50 | 50 | ||
51 | static struct ipr_data sh7705_ipr_map[] = { | 51 | static struct ipr_data ipr_irq_table[] = { |
52 | /* IRQ, IPR-idx, shift, priority */ | 52 | /* IRQ, IPR-idx, shift, priority */ |
53 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ | 53 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ |
54 | { 17, 0, 8, 2 }, /* TMU1 TUNI */ | 54 | { 17, 0, 8, 2 }, /* TMU1 TUNI */ |
@@ -70,25 +70,29 @@ static struct ipr_data sh7705_ipr_map[] = { | |||
70 | }; | 70 | }; |
71 | 71 | ||
72 | static unsigned long ipr_offsets[] = { | 72 | static unsigned long ipr_offsets[] = { |
73 | 0xFFFFFEE2 /* 0: IPRA */ | 73 | 0xFFFFFEE2, /* 0: IPRA */ |
74 | , 0xFFFFFEE4 /* 1: IPRB */ | 74 | 0xFFFFFEE4, /* 1: IPRB */ |
75 | , 0xA4000016 /* 2: IPRC */ | 75 | 0xA4000016, /* 2: IPRC */ |
76 | , 0xA4000018 /* 3: IPRD */ | 76 | 0xA4000018, /* 3: IPRD */ |
77 | , 0xA400001A /* 4: IPRE */ | 77 | 0xA400001A, /* 4: IPRE */ |
78 | , 0xA4080000 /* 5: IPRF */ | 78 | 0xA4080000, /* 5: IPRF */ |
79 | , 0xA4080002 /* 6: IPRG */ | 79 | 0xA4080002, /* 6: IPRG */ |
80 | , 0xA4080004 /* 7: IPRH */ | 80 | 0xA4080004, /* 7: IPRH */ |
81 | }; | 81 | }; |
82 | 82 | ||
83 | /* given the IPR index return the address of the IPR register */ | 83 | static struct ipr_desc ipr_irq_desc = { |
84 | unsigned int map_ipridx_to_addr(int idx) | 84 | .ipr_offsets = ipr_offsets, |
85 | { | 85 | .nr_offsets = ARRAY_SIZE(ipr_offsets), |
86 | if (idx >= ARRAY_SIZE(ipr_offsets)) | 86 | |
87 | return 0; | 87 | .ipr_data = ipr_irq_table, |
88 | return ipr_offsets[idx]; | 88 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), |
89 | } | 89 | |
90 | .chip = { | ||
91 | .name = "IPR-sh7705", | ||
92 | }, | ||
93 | }; | ||
90 | 94 | ||
91 | void __init init_IRQ_ipr() | 95 | void __init init_IRQ_ipr(void) |
92 | { | 96 | { |
93 | make_ipr_irq(sh7705_ipr_map, ARRAY_SIZE(sh7705_ipr_map)); | 97 | register_ipr_controller(&ipr_irq_desc); |
94 | } | 98 | } |
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/arch/sh/kernel/cpu/sh3/setup-sh7709.c index c7d7c35fc834..c0265a96e7d3 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7709.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7709.c | |||
@@ -52,32 +52,66 @@ static int __init sh7709_devices_setup(void) | |||
52 | } | 52 | } |
53 | __initcall(sh7709_devices_setup); | 53 | __initcall(sh7709_devices_setup); |
54 | 54 | ||
55 | #define IPRx(A,N) .addr=A, .shift=N | 55 | static struct ipr_data ipr_irq_table[] = { |
56 | #define IPRA(N) IPRx(0xfffffee2UL,N) | 56 | { 16, 0, 12, 2 }, /* TMU TUNI0 */ |
57 | #define IPRB(N) IPRx(0xfffffee4UL,N) | 57 | { 17, 0, 8, 4 }, /* TMU TUNI1 */ |
58 | #define IPRC(N) IPRx(0xa4000016UL,N) | 58 | { 18, 0, 4, 1 }, /* TMU TUNI1 */ |
59 | #define IPRD(N) IPRx(0xa4000018UL,N) | 59 | { 19, 0, 4, 1 }, /* TMU TUNI1 */ |
60 | #define IPRE(N) IPRx(0xa400001aUL,N) | 60 | { 20, 0, 0, 2 }, /* RTC CUI */ |
61 | 61 | { 21, 0, 0, 2 }, /* RTC CUI */ | |
62 | static struct ipr_data sh7709_ipr_map[] = { | 62 | { 22, 0, 0, 2 }, /* RTC CUI */ |
63 | [16] = { IPRA(12), 2 }, /* TMU TUNI0 */ | 63 | |
64 | [17] = { IPRA(8), 4 }, /* TMU TUNI1 */ | 64 | { 23, 1, 4, 3 }, /* SCI */ |
65 | [18 ... 19] = { IPRA(4), 1 }, /* TMU TUNI1 */ | 65 | { 24, 1, 4, 3 }, /* SCI */ |
66 | [20 ... 22] = { IPRA(0), 2 }, /* RTC CUI */ | 66 | { 25, 1, 4, 3 }, /* SCI */ |
67 | [23 ... 26] = { IPRB(4), 3 }, /* SCI */ | 67 | { 26, 1, 4, 3 }, /* SCI */ |
68 | [27] = { IPRB(12), 2 }, /* WDT ITI */ | 68 | { 27, 1, 12, 3 }, /* WDT ITI */ |
69 | [32] = { IPRC(0), 1 }, /* IRQ 0 */ | 69 | |
70 | [33] = { IPRC(4), 1 }, /* IRQ 1 */ | 70 | { 32, 2, 0, 1 }, /* IRQ 0 */ |
71 | [34] = { IPRC(8), 1 }, /* IRQ 2 APM */ | 71 | { 33, 2, 4, 1 }, /* IRQ 1 */ |
72 | [35] = { IPRC(12), 1 }, /* IRQ 3 TOUCHSCREEN */ | 72 | { 34, 2, 8, 1 }, /* IRQ 2 APM */ |
73 | [36] = { IPRD(0), 1 }, /* IRQ 4 */ | 73 | { 35, 2, 12, 1 }, /* IRQ 3 TOUCHSCREEN */ |
74 | [37] = { IPRD(4), 1 }, /* IRQ 5 */ | 74 | |
75 | [48 ... 51] = { IPRE(12), 7 }, /* DMA */ | 75 | { 36, 3, 0, 1 }, /* IRQ 4 */ |
76 | [52 ... 55] = { IPRE(8), 3 }, /* IRDA */ | 76 | { 37, 3, 4, 1 }, /* IRQ 5 */ |
77 | [56 ... 59] = { IPRE(4), 3 }, /* SCIF */ | 77 | |
78 | { 48, 4, 12, 7 }, /* DMA */ | ||
79 | { 49, 4, 12, 7 }, /* DMA */ | ||
80 | { 50, 4, 12, 7 }, /* DMA */ | ||
81 | { 51, 4, 12, 7 }, /* DMA */ | ||
82 | |||
83 | { 52, 4, 8, 3 }, /* IRDA */ | ||
84 | { 53, 4, 8, 3 }, /* IRDA */ | ||
85 | { 54, 4, 8, 3 }, /* IRDA */ | ||
86 | { 55, 4, 8, 3 }, /* IRDA */ | ||
87 | |||
88 | { 56, 4, 4, 3 }, /* SCIF */ | ||
89 | { 57, 4, 4, 3 }, /* SCIF */ | ||
90 | { 58, 4, 4, 3 }, /* SCIF */ | ||
91 | { 59, 4, 4, 3 }, /* SCIF */ | ||
92 | }; | ||
93 | |||
94 | static unsigned long ipr_offsets[] = { | ||
95 | 0xfffffee2, /* 0: IPRA */ | ||
96 | 0xfffffee4, /* 1: IPRB */ | ||
97 | 0xa4000016, /* 2: IPRC */ | ||
98 | 0xa4000018, /* 3: IPRD */ | ||
99 | 0xa400001a, /* 4: IPRE */ | ||
100 | }; | ||
101 | |||
102 | static struct ipr_desc ipr_irq_desc = { | ||
103 | .ipr_offsets = ipr_offsets, | ||
104 | .nr_offsets = ARRAY_SIZE(ipr_offsets), | ||
105 | |||
106 | .ipr_data = ipr_irq_table, | ||
107 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), | ||
108 | |||
109 | .chip = { | ||
110 | .name = "IPR-sh7709", | ||
111 | }, | ||
78 | }; | 112 | }; |
79 | 113 | ||
80 | void __init init_IRQ_ipr() | 114 | void __init init_IRQ_ipr(void) |
81 | { | 115 | { |
82 | make_ipr_irq(sh7709_ipr_map, ARRAY_SIZE(sh7709_ipr_map)); | 116 | register_ipr_controller(&ipr_irq_desc); |
83 | } | 117 | } |
diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 51760a7e7f1c..f40e6dac337d 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c | |||
@@ -49,7 +49,7 @@ static int __init sh7710_devices_setup(void) | |||
49 | } | 49 | } |
50 | __initcall(sh7710_devices_setup); | 50 | __initcall(sh7710_devices_setup); |
51 | 51 | ||
52 | static struct ipr_data sh7710_ipr_map[] = { | 52 | static struct ipr_data ipr_irq_table[] = { |
53 | /* IRQ, IPR-idx, shift, priority */ | 53 | /* IRQ, IPR-idx, shift, priority */ |
54 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ | 54 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ |
55 | { 17, 0, 8, 2 }, /* TMU1 TUNI */ | 55 | { 17, 0, 8, 2 }, /* TMU1 TUNI */ |
@@ -78,26 +78,30 @@ static struct ipr_data sh7710_ipr_map[] = { | |||
78 | }; | 78 | }; |
79 | 79 | ||
80 | static unsigned long ipr_offsets[] = { | 80 | static unsigned long ipr_offsets[] = { |
81 | 0xA414FEE2 /* 0: IPRA */ | 81 | 0xA414FEE2, /* 0: IPRA */ |
82 | , 0xA414FEE4 /* 1: IPRB */ | 82 | 0xA414FEE4, /* 1: IPRB */ |
83 | , 0xA4140016 /* 2: IPRC */ | 83 | 0xA4140016, /* 2: IPRC */ |
84 | , 0xA4140018 /* 3: IPRD */ | 84 | 0xA4140018, /* 3: IPRD */ |
85 | , 0xA414001A /* 4: IPRE */ | 85 | 0xA414001A, /* 4: IPRE */ |
86 | , 0xA4080000 /* 5: IPRF */ | 86 | 0xA4080000, /* 5: IPRF */ |
87 | , 0xA4080002 /* 6: IPRG */ | 87 | 0xA4080002, /* 6: IPRG */ |
88 | , 0xA4080004 /* 7: IPRH */ | 88 | 0xA4080004, /* 7: IPRH */ |
89 | , 0xA4080006 /* 8: IPRI */ | 89 | 0xA4080006, /* 8: IPRI */ |
90 | }; | 90 | }; |
91 | 91 | ||
92 | /* given the IPR index return the address of the IPR register */ | 92 | static struct ipr_desc ipr_irq_desc = { |
93 | unsigned int map_ipridx_to_addr(int idx) | 93 | .ipr_offsets = ipr_offsets, |
94 | { | 94 | .nr_offsets = ARRAY_SIZE(ipr_offsets), |
95 | if (idx >= ARRAY_SIZE(ipr_offsets)) | 95 | |
96 | return 0; | 96 | .ipr_data = ipr_irq_table, |
97 | return ipr_offsets[idx]; | 97 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), |
98 | } | 98 | |
99 | .chip = { | ||
100 | .name = "IPR-sh7710", | ||
101 | }, | ||
102 | }; | ||
99 | 103 | ||
100 | void __init init_IRQ_ipr() | 104 | void __init init_IRQ_ipr(void) |
101 | { | 105 | { |
102 | make_ipr_irq(sh7710_ipr_map, ARRAY_SIZE(sh7710_ipr_map)); | 106 | register_ipr_controller(&ipr_irq_desc); |
103 | } | 107 | } |
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 03b14cf78ddf..da153bcdfeb2 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c | |||
@@ -82,7 +82,7 @@ static int __init sh7750_devices_setup(void) | |||
82 | } | 82 | } |
83 | __initcall(sh7750_devices_setup); | 83 | __initcall(sh7750_devices_setup); |
84 | 84 | ||
85 | static struct ipr_data sh7750_ipr_map[] = { | 85 | static struct ipr_data ipr_irq_table[] = { |
86 | /* IRQ, IPR-idx, shift, priority */ | 86 | /* IRQ, IPR-idx, shift, priority */ |
87 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ | 87 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ |
88 | { 17, 0, 12, 2 }, /* TMU1 TUNI */ | 88 | { 17, 0, 12, 2 }, /* TMU1 TUNI */ |
@@ -106,8 +106,27 @@ static struct ipr_data sh7750_ipr_map[] = { | |||
106 | { 38, 2, 8, 7 }, /* DMAC DMAE */ | 106 | { 38, 2, 8, 7 }, /* DMAC DMAE */ |
107 | }; | 107 | }; |
108 | 108 | ||
109 | static unsigned long ipr_offsets[] = { | ||
110 | 0xffd00004UL, /* 0: IPRA */ | ||
111 | 0xffd00008UL, /* 1: IPRB */ | ||
112 | 0xffd0000cUL, /* 2: IPRC */ | ||
113 | 0xffd00010UL, /* 3: IPRD */ | ||
114 | }; | ||
115 | |||
116 | static struct ipr_desc ipr_irq_desc = { | ||
117 | .ipr_offsets = ipr_offsets, | ||
118 | .nr_offsets = ARRAY_SIZE(ipr_offsets), | ||
119 | |||
120 | .ipr_data = ipr_irq_table, | ||
121 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), | ||
122 | |||
123 | .chip = { | ||
124 | .name = "IPR-sh7750", | ||
125 | }, | ||
126 | }; | ||
127 | |||
109 | #ifdef CONFIG_CPU_SUBTYPE_SH7751 | 128 | #ifdef CONFIG_CPU_SUBTYPE_SH7751 |
110 | static struct ipr_data sh7751_ipr_map[] = { | 129 | static struct ipr_data ipr_irq_table_sh7751[] = { |
111 | { 44, 2, 8, 7 }, /* DMAC DMTE4 */ | 130 | { 44, 2, 8, 7 }, /* DMAC DMTE4 */ |
112 | { 45, 2, 8, 7 }, /* DMAC DMTE5 */ | 131 | { 45, 2, 8, 7 }, /* DMAC DMTE5 */ |
113 | { 46, 2, 8, 7 }, /* DMAC DMTE6 */ | 132 | { 46, 2, 8, 7 }, /* DMAC DMTE6 */ |
@@ -118,21 +137,26 @@ static struct ipr_data sh7751_ipr_map[] = { | |||
118 | /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */ | 137 | /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */ |
119 | /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */ | 138 | /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */ |
120 | }; | 139 | }; |
121 | #endif | ||
122 | 140 | ||
123 | static unsigned long ipr_offsets[] = { | 141 | static struct ipr_desc ipr_irq_desc_sh7751 = { |
124 | 0xffd00004UL, /* 0: IPRA */ | 142 | .ipr_offsets = ipr_offsets, |
125 | 0xffd00008UL, /* 1: IPRB */ | 143 | .nr_offsets = ARRAY_SIZE(ipr_offsets), |
126 | 0xffd0000cUL, /* 2: IPRC */ | 144 | |
127 | 0xffd00010UL, /* 3: IPRD */ | 145 | .ipr_data = ipr_irq_table_sh7751, |
146 | .nr_irqs = ARRAY_SIZE(ipr_irq_table_sh7751), | ||
147 | |||
148 | .chip = { | ||
149 | .name = "IPR-sh7751", | ||
150 | }, | ||
128 | }; | 151 | }; |
152 | #endif | ||
129 | 153 | ||
130 | /* given the IPR index return the address of the IPR register */ | 154 | void __init init_IRQ_ipr(void) |
131 | unsigned int map_ipridx_to_addr(int idx) | ||
132 | { | 155 | { |
133 | if (idx >= ARRAY_SIZE(ipr_offsets)) | 156 | register_ipr_controller(&ipr_irq_desc); |
134 | return 0; | 157 | #ifdef CONFIG_CPU_SUBTYPE_SH7751 |
135 | return ipr_offsets[idx]; | 158 | register_ipr_controller(&ipr_irq_desc_sh7751); |
159 | #endif | ||
136 | } | 160 | } |
137 | 161 | ||
138 | #define INTC_ICR 0xffd00000UL | 162 | #define INTC_ICR 0xffd00000UL |
@@ -143,11 +167,3 @@ void ipr_irq_enable_irlm(void) | |||
143 | { | 167 | { |
144 | ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); | 168 | ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); |
145 | } | 169 | } |
146 | |||
147 | void __init init_IRQ_ipr() | ||
148 | { | ||
149 | make_ipr_irq(sh7750_ipr_map, ARRAY_SIZE(sh7750_ipr_map)); | ||
150 | #ifdef CONFIG_CPU_SUBTYPE_SH7751 | ||
151 | make_ipr_irq(sh7751_ipr_map, ARRAY_SIZE(sh7751_ipr_map)); | ||
152 | #endif | ||
153 | } | ||
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 6d3c91897774..3df169755673 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c | |||
@@ -109,7 +109,12 @@ static struct intc2_desc intc2_irq_desc __read_mostly = { | |||
109 | }, | 109 | }, |
110 | }; | 110 | }; |
111 | 111 | ||
112 | static struct ipr_data sh7760_ipr_map[] = { | 112 | void __init init_IRQ_intc2(void) |
113 | { | ||
114 | register_intc2_controller(&intc2_irq_desc); | ||
115 | } | ||
116 | |||
117 | static struct ipr_data ipr_irq_table[] = { | ||
113 | /* IRQ, IPR-idx, shift, priority */ | 118 | /* IRQ, IPR-idx, shift, priority */ |
114 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ | 119 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ |
115 | { 17, 0, 8, 2 }, /* TMU1 TUNI */ | 120 | { 17, 0, 8, 2 }, /* TMU1 TUNI */ |
@@ -146,20 +151,19 @@ static unsigned long ipr_offsets[] = { | |||
146 | 0xffd00010UL, /* 3: IPRD */ | 151 | 0xffd00010UL, /* 3: IPRD */ |
147 | }; | 152 | }; |
148 | 153 | ||
149 | /* given the IPR index return the address of the IPR register */ | 154 | static struct ipr_desc ipr_irq_desc = { |
150 | unsigned int map_ipridx_to_addr(int idx) | 155 | .ipr_offsets = ipr_offsets, |
151 | { | 156 | .nr_offsets = ARRAY_SIZE(ipr_offsets), |
152 | if (idx >= ARRAY_SIZE(ipr_offsets)) | ||
153 | return 0; | ||
154 | return ipr_offsets[idx]; | ||
155 | } | ||
156 | 157 | ||
157 | void __init init_IRQ_intc2(void) | 158 | .ipr_data = ipr_irq_table, |
158 | { | 159 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), |
159 | register_intc2_controller(&intc2_irq_desc); | 160 | |
160 | } | 161 | .chip = { |
162 | .name = "IPR-sh7760", | ||
163 | }, | ||
164 | }; | ||
161 | 165 | ||
162 | void __init init_IRQ_ipr(void) | 166 | void __init init_IRQ_ipr(void) |
163 | { | 167 | { |
164 | make_ipr_irq(sh7760_ipr_map, ARRAY_SIZE(sh7760_ipr_map)); | 168 | register_ipr_controller(&ipr_irq_desc); |
165 | } | 169 | } |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index fa07fab4797f..a3e159ef6dfe 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c | |||
@@ -44,7 +44,7 @@ static int __init sh7722_devices_setup(void) | |||
44 | } | 44 | } |
45 | __initcall(sh7722_devices_setup); | 45 | __initcall(sh7722_devices_setup); |
46 | 46 | ||
47 | static struct ipr_data sh7722_ipr_map[] = { | 47 | static struct ipr_data ipr_irq_table[] = { |
48 | /* IRQ, IPR-idx, shift, prio */ | 48 | /* IRQ, IPR-idx, shift, prio */ |
49 | { 16, 0, 12, 2 }, /* TMU0 */ | 49 | { 16, 0, 12, 2 }, /* TMU0 */ |
50 | { 17, 0, 8, 2 }, /* TMU1 */ | 50 | { 17, 0, 8, 2 }, /* TMU1 */ |
@@ -69,16 +69,21 @@ static unsigned long ipr_offsets[] = { | |||
69 | 0xa408002c, /* 11: IPRL */ | 69 | 0xa408002c, /* 11: IPRL */ |
70 | }; | 70 | }; |
71 | 71 | ||
72 | unsigned int map_ipridx_to_addr(int idx) | 72 | static struct ipr_desc ipr_irq_desc = { |
73 | { | 73 | .ipr_offsets = ipr_offsets, |
74 | if (unlikely(idx >= ARRAY_SIZE(ipr_offsets))) | 74 | .nr_offsets = ARRAY_SIZE(ipr_offsets), |
75 | return 0; | 75 | |
76 | return ipr_offsets[idx]; | 76 | .ipr_data = ipr_irq_table, |
77 | } | 77 | .nr_irqs = ARRAY_SIZE(ipr_irq_table), |
78 | |||
79 | .chip = { | ||
80 | .name = "IPR-sh7722", | ||
81 | }, | ||
82 | }; | ||
78 | 83 | ||
79 | void __init init_IRQ_ipr(void) | 84 | void __init init_IRQ_ipr(void) |
80 | { | 85 | { |
81 | make_ipr_irq(sh7722_ipr_map, ARRAY_SIZE(sh7722_ipr_map)); | 86 | register_ipr_controller(&ipr_irq_desc); |
82 | } | 87 | } |
83 | 88 | ||
84 | void __init plat_mem_setup(void) | 89 | void __init plat_mem_setup(void) |