aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/cpm2_pic.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/cpm2_pic.c')
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.c47
1 files changed, 20 insertions, 27 deletions
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index 473032556715..5495c1be472b 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -115,32 +115,25 @@ static void cpm2_ack(struct irq_data *d)
115 115
116static void cpm2_end_irq(struct irq_data *d) 116static void cpm2_end_irq(struct irq_data *d)
117{ 117{
118 struct irq_desc *desc;
119 int bit, word; 118 int bit, word;
120 unsigned int irq_nr = virq_to_hw(d->irq); 119 unsigned int irq_nr = virq_to_hw(d->irq);
121 120
122 desc = irq_to_desc(irq_nr); 121 bit = irq_to_siubit[irq_nr];
123 if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)) 122 word = irq_to_siureg[irq_nr];
124 && desc->action) {
125
126 bit = irq_to_siubit[irq_nr];
127 word = irq_to_siureg[irq_nr];
128 123
129 ppc_cached_irq_mask[word] |= 1 << bit; 124 ppc_cached_irq_mask[word] |= 1 << bit;
130 out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]); 125 out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
131 126
132 /* 127 /*
133 * Work around large numbers of spurious IRQs on PowerPC 82xx 128 * Work around large numbers of spurious IRQs on PowerPC 82xx
134 * systems. 129 * systems.
135 */ 130 */
136 mb(); 131 mb();
137 }
138} 132}
139 133
140static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type) 134static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
141{ 135{
142 unsigned int src = virq_to_hw(d->irq); 136 unsigned int src = virq_to_hw(d->irq);
143 struct irq_desc *desc = irq_to_desc(d->irq);
144 unsigned int vold, vnew, edibit; 137 unsigned int vold, vnew, edibit;
145 138
146 /* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or 139 /* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
@@ -162,13 +155,11 @@ static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
162 goto err_sense; 155 goto err_sense;
163 } 156 }
164 157
165 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); 158 irqd_set_trigger_type(d, flow_type);
166 desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; 159 if (flow_type & IRQ_TYPE_LEVEL_LOW)
167 if (flow_type & IRQ_TYPE_LEVEL_LOW) { 160 __irq_set_handler_locked(d->irq, handle_level_irq);
168 desc->status |= IRQ_LEVEL; 161 else
169 desc->handle_irq = handle_level_irq; 162 __irq_set_handler_locked(d->irq, handle_edge_irq);
170 } else
171 desc->handle_irq = handle_edge_irq;
172 163
173 /* internal IRQ senses are LEVEL_LOW 164 /* internal IRQ senses are LEVEL_LOW
174 * EXT IRQ and Port C IRQ senses are programmable 165 * EXT IRQ and Port C IRQ senses are programmable
@@ -179,7 +170,8 @@ static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
179 if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) 170 if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0)
180 edibit = (31 - (CPM2_IRQ_PORTC0 - src)); 171 edibit = (31 - (CPM2_IRQ_PORTC0 - src));
181 else 172 else
182 return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL; 173 return (flow_type & IRQ_TYPE_LEVEL_LOW) ?
174 IRQ_SET_MASK_OK_NOCOPY : -EINVAL;
183 175
184 vold = in_be32(&cpm2_intctl->ic_siexr); 176 vold = in_be32(&cpm2_intctl->ic_siexr);
185 177
@@ -190,7 +182,7 @@ static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
190 182
191 if (vold != vnew) 183 if (vold != vnew)
192 out_be32(&cpm2_intctl->ic_siexr, vnew); 184 out_be32(&cpm2_intctl->ic_siexr, vnew);
193 return 0; 185 return IRQ_SET_MASK_OK_NOCOPY;
194 186
195err_sense: 187err_sense:
196 pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type); 188 pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type);
@@ -204,6 +196,7 @@ static struct irq_chip cpm2_pic = {
204 .irq_ack = cpm2_ack, 196 .irq_ack = cpm2_ack,
205 .irq_eoi = cpm2_end_irq, 197 .irq_eoi = cpm2_end_irq,
206 .irq_set_type = cpm2_set_irq_type, 198 .irq_set_type = cpm2_set_irq_type,
199 .flags = IRQCHIP_EOI_IF_HANDLED,
207}; 200};
208 201
209unsigned int cpm2_get_irq(void) 202unsigned int cpm2_get_irq(void)
@@ -226,8 +219,8 @@ static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
226{ 219{
227 pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw); 220 pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw);
228 221
229 irq_to_desc(virq)->status |= IRQ_LEVEL; 222 irq_set_status_flags(virq, IRQ_LEVEL);
230 set_irq_chip_and_handler(virq, &cpm2_pic, handle_level_irq); 223 irq_set_chip_and_handler(virq, &cpm2_pic, handle_level_irq);
231 return 0; 224 return 0;
232} 225}
233 226