diff options
-rw-r--r-- | arch/sh/boards/se/7780/irq.c | 45 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/irq/intc2.c | 58 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4/setup-sh7760.c | 15 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 15 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 16 | ||||
-rw-r--r-- | include/asm-sh/hw_irq.h | 19 | ||||
-rw-r--r-- | include/asm-sh/irq.h | 10 |
7 files changed, 103 insertions, 75 deletions
diff --git a/arch/sh/boards/se/7780/irq.c b/arch/sh/boards/se/7780/irq.c index 3d0625c2d07b..874914746009 100644 --- a/arch/sh/boards/se/7780/irq.c +++ b/arch/sh/boards/se/7780/irq.c | |||
@@ -16,28 +16,6 @@ | |||
16 | #include <asm/io.h> | 16 | #include <asm/io.h> |
17 | #include <asm/se7780.h> | 17 | #include <asm/se7780.h> |
18 | 18 | ||
19 | #define INTC_INTMSK0 0xFFD00044 | ||
20 | #define INTC_INTMSKCLR0 0xFFD00064 | ||
21 | |||
22 | static void disable_se7780_irq(unsigned int irq) | ||
23 | { | ||
24 | struct intc2_data *p = get_irq_chip_data(irq); | ||
25 | ctrl_outl(1 << p->msk_shift, INTC_INTMSK0 + p->msk_offset); | ||
26 | } | ||
27 | |||
28 | static void enable_se7780_irq(unsigned int irq) | ||
29 | { | ||
30 | struct intc2_data *p = get_irq_chip_data(irq); | ||
31 | ctrl_outl(1 << p->msk_shift, INTC_INTMSKCLR0 + p->msk_offset); | ||
32 | } | ||
33 | |||
34 | static struct irq_chip se7780_irq_chip __read_mostly = { | ||
35 | .name = "SE7780", | ||
36 | .mask = disable_se7780_irq, | ||
37 | .unmask = enable_se7780_irq, | ||
38 | .mask_ack = disable_se7780_irq, | ||
39 | }; | ||
40 | |||
41 | static struct intc2_data intc2_irq_table[] = { | 19 | static struct intc2_data intc2_irq_table[] = { |
42 | { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT1 */ | 20 | { 2, 0, 31, 0, 31, 3 }, /* daughter board EXTINT1 */ |
43 | { 4, 0, 30, 0, 30, 3 }, /* daughter board EXTINT2 */ | 21 | { 4, 0, 30, 0, 30, 3 }, /* daughter board EXTINT2 */ |
@@ -51,13 +29,24 @@ static struct intc2_data intc2_irq_table[] = { | |||
51 | { 0 , 0, 24, 0, 24, 3 }, /* SM501 */ | 29 | { 0 , 0, 24, 0, 24, 3 }, /* SM501 */ |
52 | }; | 30 | }; |
53 | 31 | ||
32 | static struct intc2_desc intc2_irq_desc __read_mostly = { | ||
33 | .prio_base = 0, /* N/A */ | ||
34 | .msk_base = 0xffd00044, | ||
35 | .mskclr_base = 0xffd00064, | ||
36 | |||
37 | .intc2_data = intc2_irq_table, | ||
38 | .nr_irqs = ARRAY_SIZE(intc2_irq_table), | ||
39 | |||
40 | .chip = { | ||
41 | .name = "INTC2-se7780", | ||
42 | }, | ||
43 | }; | ||
44 | |||
54 | /* | 45 | /* |
55 | * Initialize IRQ setting | 46 | * Initialize IRQ setting |
56 | */ | 47 | */ |
57 | void __init init_se7780_IRQ(void) | 48 | void __init init_se7780_IRQ(void) |
58 | { | 49 | { |
59 | int i ; | ||
60 | |||
61 | /* enable all interrupt at FPGA */ | 50 | /* enable all interrupt at FPGA */ |
62 | ctrl_outw(0, FPGA_INTMSK1); | 51 | ctrl_outw(0, FPGA_INTMSK1); |
63 | /* mask SM501 interrupt */ | 52 | /* mask SM501 interrupt */ |
@@ -79,11 +68,5 @@ void __init init_se7780_IRQ(void) | |||
79 | /* FPGA + 0x0A */ | 68 | /* FPGA + 0x0A */ |
80 | ctrl_outw((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3); | 69 | ctrl_outw((IRQPIN_PCCPW << IRQPOS_PCCPW), FPGA_INTSEL3); |
81 | 70 | ||
82 | for (i = 0; i < ARRAY_SIZE(intc2_irq_table); i++) { | 71 | register_intc2_controller(&intc2_irq_desc); |
83 | disable_irq_nosync(intc2_irq_table[i].irq); | ||
84 | set_irq_chip_and_handler_name( intc2_irq_table[i].irq, &se7780_irq_chip, | ||
85 | handle_level_irq, "level"); | ||
86 | set_irq_chip_data( intc2_irq_table[i].irq, &intc2_irq_table[i] ); | ||
87 | disable_se7780_irq(intc2_irq_table[i].irq); | ||
88 | } | ||
89 | } | 72 | } |
diff --git a/arch/sh/kernel/cpu/irq/intc2.c b/arch/sh/kernel/cpu/irq/intc2.c index d8e22f4ff0f0..dae02d3152e7 100644 --- a/arch/sh/kernel/cpu/irq/intc2.c +++ b/arch/sh/kernel/cpu/irq/intc2.c | |||
@@ -14,36 +14,26 @@ | |||
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | 16 | ||
17 | #if defined(CONFIG_CPU_SUBTYPE_SH7760) | 17 | static inline struct intc2_desc *get_intc2_desc(unsigned int irq) |
18 | #define INTC2_BASE 0xfe080000 | 18 | { |
19 | #define INTC2_INTMSK (INTC2_BASE + 0x40) | 19 | struct irq_chip *chip = get_irq_chip(irq); |
20 | #define INTC2_INTMSKCLR (INTC2_BASE + 0x60) | 20 | return (void *)((char *)chip - offsetof(struct intc2_desc, chip)); |
21 | #elif defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | 21 | } |
22 | defined(CONFIG_CPU_SUBTYPE_SH7785) | ||
23 | #define INTC2_BASE 0xffd40000 | ||
24 | #define INTC2_INTMSK (INTC2_BASE + 0x38) | ||
25 | #define INTC2_INTMSKCLR (INTC2_BASE + 0x3c) | ||
26 | #endif | ||
27 | 22 | ||
28 | static void disable_intc2_irq(unsigned int irq) | 23 | static void disable_intc2_irq(unsigned int irq) |
29 | { | 24 | { |
30 | struct intc2_data *p = get_irq_chip_data(irq); | 25 | struct intc2_data *p = get_irq_chip_data(irq); |
31 | ctrl_outl(1 << p->msk_shift, INTC2_INTMSK + p->msk_offset); | 26 | struct intc2_desc *d = get_intc2_desc(irq); |
27 | ctrl_outl(1 << p->msk_shift, d->msk_base + p->msk_offset); | ||
32 | } | 28 | } |
33 | 29 | ||
34 | static void enable_intc2_irq(unsigned int irq) | 30 | static void enable_intc2_irq(unsigned int irq) |
35 | { | 31 | { |
36 | struct intc2_data *p = get_irq_chip_data(irq); | 32 | struct intc2_data *p = get_irq_chip_data(irq); |
37 | ctrl_outl(1 << p->msk_shift, INTC2_INTMSKCLR + p->msk_offset); | 33 | struct intc2_desc *d = get_intc2_desc(irq); |
34 | ctrl_outl(1 << p->msk_shift, d->mskclr_base + p->msk_offset); | ||
38 | } | 35 | } |
39 | 36 | ||
40 | static struct irq_chip intc2_irq_chip = { | ||
41 | .name = "INTC2", | ||
42 | .mask = disable_intc2_irq, | ||
43 | .unmask = enable_intc2_irq, | ||
44 | .mask_ack = disable_intc2_irq, | ||
45 | }; | ||
46 | |||
47 | /* | 37 | /* |
48 | * Setup an INTC2 style interrupt. | 38 | * Setup an INTC2 style interrupt. |
49 | * NOTE: Unlike IPR interrupts, parameters are not shifted by this code, | 39 | * NOTE: Unlike IPR interrupts, parameters are not shifted by this code, |
@@ -56,30 +46,36 @@ static struct irq_chip intc2_irq_chip = { | |||
56 | * | 46 | * |
57 | * in the intc2_data table. | 47 | * in the intc2_data table. |
58 | */ | 48 | */ |
59 | void make_intc2_irq(struct intc2_data *table, unsigned int nr_irqs) | 49 | void register_intc2_controller(struct intc2_desc *desc) |
60 | { | 50 | { |
61 | int i; | 51 | int i; |
62 | 52 | ||
63 | for (i = 0; i < nr_irqs; i++) { | 53 | desc->chip.mask = disable_intc2_irq; |
54 | desc->chip.unmask = enable_intc2_irq; | ||
55 | desc->chip.mask_ack = disable_intc2_irq; | ||
56 | |||
57 | for (i = 0; i < desc->nr_irqs; i++) { | ||
64 | unsigned long ipr, flags; | 58 | unsigned long ipr, flags; |
65 | struct intc2_data *p = table + i; | 59 | struct intc2_data *p = desc->intc2_data + i; |
66 | 60 | ||
67 | disable_irq_nosync(p->irq); | 61 | disable_irq_nosync(p->irq); |
68 | 62 | ||
69 | /* Set the priority level */ | 63 | if (desc->prio_base) { |
70 | local_irq_save(flags); | 64 | /* Set the priority level */ |
65 | local_irq_save(flags); | ||
71 | 66 | ||
72 | ipr = ctrl_inl(INTC2_BASE + p->ipr_offset); | 67 | ipr = ctrl_inl(desc->prio_base + p->ipr_offset); |
73 | ipr &= ~(0xf << p->ipr_shift); | 68 | ipr &= ~(0xf << p->ipr_shift); |
74 | ipr |= p->priority << p->ipr_shift; | 69 | ipr |= p->priority << p->ipr_shift; |
75 | ctrl_outl(ipr, INTC2_BASE + p->ipr_offset); | 70 | ctrl_outl(ipr, desc->prio_base + p->ipr_offset); |
76 | 71 | ||
77 | local_irq_restore(flags); | 72 | local_irq_restore(flags); |
73 | } | ||
78 | 74 | ||
79 | set_irq_chip_and_handler_name(p->irq, &intc2_irq_chip, | 75 | set_irq_chip_and_handler_name(p->irq, &desc->chip, |
80 | handle_level_irq, "level"); | 76 | handle_level_irq, "level"); |
81 | set_irq_chip_data(p->irq, p); | 77 | set_irq_chip_data(p->irq, p); |
82 | 78 | ||
83 | enable_intc2_irq(p->irq); | 79 | disable_intc2_irq(p->irq); |
84 | } | 80 | } |
85 | } | 81 | } |
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index b7c702821e6f..6d3c91897774 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c | |||
@@ -96,6 +96,19 @@ static struct intc2_data intc2_irq_table[] = { | |||
96 | {109,12, 0, 4, 0, 3}, /* CMTI */ | 96 | {109,12, 0, 4, 0, 3}, /* CMTI */ |
97 | }; | 97 | }; |
98 | 98 | ||
99 | static struct intc2_desc intc2_irq_desc __read_mostly = { | ||
100 | .prio_base = 0xfe080000, | ||
101 | .msk_base = 0xfe080040, | ||
102 | .mskclr_base = 0xfe080060, | ||
103 | |||
104 | .intc2_data = intc2_irq_table, | ||
105 | .nr_irqs = ARRAY_SIZE(intc2_irq_table), | ||
106 | |||
107 | .chip = { | ||
108 | .name = "INTC2-sh7760", | ||
109 | }, | ||
110 | }; | ||
111 | |||
99 | static struct ipr_data sh7760_ipr_map[] = { | 112 | static struct ipr_data sh7760_ipr_map[] = { |
100 | /* IRQ, IPR-idx, shift, priority */ | 113 | /* IRQ, IPR-idx, shift, priority */ |
101 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ | 114 | { 16, 0, 12, 2 }, /* TMU0 TUNI*/ |
@@ -143,7 +156,7 @@ unsigned int map_ipridx_to_addr(int idx) | |||
143 | 156 | ||
144 | void __init init_IRQ_intc2(void) | 157 | void __init init_IRQ_intc2(void) |
145 | { | 158 | { |
146 | make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); | 159 | register_intc2_controller(&intc2_irq_desc); |
147 | } | 160 | } |
148 | 161 | ||
149 | void __init init_IRQ_ipr(void) | 162 | void __init init_IRQ_ipr(void) |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 9aeaa2ddaa28..b57c760bffde 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c | |||
@@ -102,7 +102,20 @@ static struct intc2_data intc2_irq_table[] = { | |||
102 | { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */ | 102 | { 68, 0x14, 8, 0, 18, 2 }, /* PCIC4 */ |
103 | }; | 103 | }; |
104 | 104 | ||
105 | static struct intc2_desc intc2_irq_desc __read_mostly = { | ||
106 | .prio_base = 0xffd40000, | ||
107 | .msk_base = 0xffd40038, | ||
108 | .mskclr_base = 0xffd4003c, | ||
109 | |||
110 | .intc2_data = intc2_irq_table, | ||
111 | .nr_irqs = ARRAY_SIZE(intc2_irq_table), | ||
112 | |||
113 | .chip = { | ||
114 | .name = "INTC2-sh7780", | ||
115 | }, | ||
116 | }; | ||
117 | |||
105 | void __init init_IRQ_intc2(void) | 118 | void __init init_IRQ_intc2(void) |
106 | { | 119 | { |
107 | make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); | 120 | register_intc2_controller(&intc2_irq_desc); |
108 | } | 121 | } |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index 07b0de82cfe6..ce10ec5d6914 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c | |||
@@ -97,7 +97,21 @@ static struct intc2_data intc2_irq_table[] = { | |||
97 | { 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */ | 97 | { 60, 12, 16, 0, 7, 3 }, /* SCIF5 ERI, RXI, BRI, TXI */ |
98 | }; | 98 | }; |
99 | 99 | ||
100 | static struct intc2_desc intc2_irq_desc __read_mostly = { | ||
101 | .prio_base = 0xffd40000, | ||
102 | .msk_base = 0xffd40038, | ||
103 | .mskclr_base = 0xffd4003c, | ||
104 | |||
105 | .intc2_data = intc2_irq_table, | ||
106 | .nr_irqs = ARRAY_SIZE(intc2_irq_table), | ||
107 | |||
108 | .chip = { | ||
109 | .name = "INTC2-sh7785", | ||
110 | }, | ||
111 | }; | ||
112 | |||
100 | void __init init_IRQ_intc2(void) | 113 | void __init init_IRQ_intc2(void) |
101 | { | 114 | { |
102 | make_intc2_irq(intc2_irq_table, ARRAY_SIZE(intc2_irq_table)); | 115 | register_intc2_controller(&intc2_irq_desc); |
103 | } | 116 | } |
117 | |||
diff --git a/include/asm-sh/hw_irq.h b/include/asm-sh/hw_irq.h index 80ee1cda7498..f9dfdc04aef5 100644 --- a/include/asm-sh/hw_irq.h +++ b/include/asm-sh/hw_irq.h | |||
@@ -5,4 +5,23 @@ | |||
5 | 5 | ||
6 | extern atomic_t irq_err_count; | 6 | extern atomic_t irq_err_count; |
7 | 7 | ||
8 | struct intc2_data { | ||
9 | unsigned short irq; | ||
10 | unsigned char ipr_offset, ipr_shift; | ||
11 | unsigned char msk_offset, msk_shift; | ||
12 | unsigned char priority; | ||
13 | }; | ||
14 | |||
15 | struct intc2_desc { | ||
16 | unsigned long prio_base; | ||
17 | unsigned long msk_base; | ||
18 | unsigned long mskclr_base; | ||
19 | struct intc2_data *intc2_data; | ||
20 | unsigned int nr_irqs; | ||
21 | struct irq_chip chip; | ||
22 | }; | ||
23 | |||
24 | void register_intc2_controller(struct intc2_desc *); | ||
25 | void init_IRQ_intc2(void); | ||
26 | |||
8 | #endif /* __ASM_SH_HW_IRQ_H */ | 27 | #endif /* __ASM_SH_HW_IRQ_H */ |
diff --git a/include/asm-sh/irq.h b/include/asm-sh/irq.h index e81bf21c801e..c247b733a7d6 100644 --- a/include/asm-sh/irq.h +++ b/include/asm-sh/irq.h | |||
@@ -63,16 +63,6 @@ void make_ipr_irq(struct ipr_data *table, unsigned int nr_irqs); | |||
63 | void make_imask_irq(unsigned int irq); | 63 | void make_imask_irq(unsigned int irq); |
64 | void init_IRQ_ipr(void); | 64 | void init_IRQ_ipr(void); |
65 | 65 | ||
66 | struct intc2_data { | ||
67 | unsigned short irq; | ||
68 | unsigned char ipr_offset, ipr_shift; | ||
69 | unsigned char msk_offset, msk_shift; | ||
70 | unsigned char priority; | ||
71 | }; | ||
72 | |||
73 | void make_intc2_irq(struct intc2_data *, unsigned int nr_irqs); | ||
74 | void init_IRQ_intc2(void); | ||
75 | |||
76 | static inline int generic_irq_demux(int irq) | 66 | static inline int generic_irq_demux(int irq) |
77 | { | 67 | { |
78 | return irq; | 68 | return irq; |