diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /arch/powerpc/sysdev/cpm2_pic.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'arch/powerpc/sysdev/cpm2_pic.c')
-rw-r--r-- | arch/powerpc/sysdev/cpm2_pic.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c index 78f1f7cca0a0..fcea4ff825dd 100644 --- a/arch/powerpc/sysdev/cpm2_pic.c +++ b/arch/powerpc/sysdev/cpm2_pic.c | |||
@@ -115,11 +115,13 @@ static void cpm2_ack(unsigned int virq) | |||
115 | 115 | ||
116 | static void cpm2_end_irq(unsigned int virq) | 116 | static void cpm2_end_irq(unsigned int virq) |
117 | { | 117 | { |
118 | struct irq_desc *desc; | ||
118 | int bit, word; | 119 | int bit, word; |
119 | unsigned int irq_nr = virq_to_hw(virq); | 120 | unsigned int irq_nr = virq_to_hw(virq); |
120 | 121 | ||
121 | if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)) | 122 | desc = irq_to_desc(irq_nr); |
122 | && irq_desc[irq_nr].action) { | 123 | if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)) |
124 | && desc->action) { | ||
123 | 125 | ||
124 | bit = irq_to_siubit[irq_nr]; | 126 | bit = irq_to_siubit[irq_nr]; |
125 | word = irq_to_siureg[irq_nr]; | 127 | word = irq_to_siureg[irq_nr]; |
@@ -138,16 +140,26 @@ static void cpm2_end_irq(unsigned int virq) | |||
138 | static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) | 140 | static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) |
139 | { | 141 | { |
140 | unsigned int src = virq_to_hw(virq); | 142 | unsigned int src = virq_to_hw(virq); |
141 | struct irq_desc *desc = get_irq_desc(virq); | 143 | struct irq_desc *desc = irq_to_desc(virq); |
142 | unsigned int vold, vnew, edibit; | 144 | unsigned int vold, vnew, edibit; |
143 | 145 | ||
144 | if (flow_type == IRQ_TYPE_NONE) | 146 | /* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or |
145 | flow_type = IRQ_TYPE_LEVEL_LOW; | 147 | * IRQ_TYPE_EDGE_BOTH (default). All others are IRQ_TYPE_EDGE_FALLING |
146 | 148 | * or IRQ_TYPE_LEVEL_LOW (default) | |
147 | if (flow_type & IRQ_TYPE_EDGE_RISING) { | 149 | */ |
148 | printk(KERN_ERR "CPM2 PIC: sense type 0x%x not supported\n", | 150 | if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0) { |
149 | flow_type); | 151 | if (flow_type == IRQ_TYPE_NONE) |
150 | return -EINVAL; | 152 | flow_type = IRQ_TYPE_EDGE_BOTH; |
153 | |||
154 | if (flow_type != IRQ_TYPE_EDGE_BOTH && | ||
155 | flow_type != IRQ_TYPE_EDGE_FALLING) | ||
156 | goto err_sense; | ||
157 | } else { | ||
158 | if (flow_type == IRQ_TYPE_NONE) | ||
159 | flow_type = IRQ_TYPE_LEVEL_LOW; | ||
160 | |||
161 | if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH)) | ||
162 | goto err_sense; | ||
151 | } | 163 | } |
152 | 164 | ||
153 | desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); | 165 | desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); |
@@ -179,10 +191,14 @@ static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) | |||
179 | if (vold != vnew) | 191 | if (vold != vnew) |
180 | out_be32(&cpm2_intctl->ic_siexr, vnew); | 192 | out_be32(&cpm2_intctl->ic_siexr, vnew); |
181 | return 0; | 193 | return 0; |
194 | |||
195 | err_sense: | ||
196 | pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type); | ||
197 | return -EINVAL; | ||
182 | } | 198 | } |
183 | 199 | ||
184 | static struct irq_chip cpm2_pic = { | 200 | static struct irq_chip cpm2_pic = { |
185 | .typename = " CPM2 SIU ", | 201 | .name = "CPM2 SIU", |
186 | .mask = cpm2_mask_irq, | 202 | .mask = cpm2_mask_irq, |
187 | .unmask = cpm2_unmask_irq, | 203 | .unmask = cpm2_unmask_irq, |
188 | .ack = cpm2_ack, | 204 | .ack = cpm2_ack, |
@@ -210,13 +226,13 @@ static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq, | |||
210 | { | 226 | { |
211 | pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw); | 227 | pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw); |
212 | 228 | ||
213 | get_irq_desc(virq)->status |= IRQ_LEVEL; | 229 | irq_to_desc(virq)->status |= IRQ_LEVEL; |
214 | set_irq_chip_and_handler(virq, &cpm2_pic, handle_level_irq); | 230 | set_irq_chip_and_handler(virq, &cpm2_pic, handle_level_irq); |
215 | return 0; | 231 | return 0; |
216 | } | 232 | } |
217 | 233 | ||
218 | static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct, | 234 | static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct, |
219 | u32 *intspec, unsigned int intsize, | 235 | const u32 *intspec, unsigned int intsize, |
220 | irq_hw_number_t *out_hwirq, unsigned int *out_flags) | 236 | irq_hw_number_t *out_hwirq, unsigned int *out_flags) |
221 | { | 237 | { |
222 | *out_hwirq = intspec[0]; | 238 | *out_hwirq = intspec[0]; |