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/sh/boards/se | |
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/sh/boards/se')
-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 |
3 files changed, 88 insertions, 110 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 | } |