aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/cpm2_pic.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /arch/powerpc/sysdev/cpm2_pic.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (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.c42
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
116static void cpm2_end_irq(unsigned int virq) 116static 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)
138static int cpm2_set_irq_type(unsigned int virq, unsigned int flow_type) 140static 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
195err_sense:
196 pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type);
197 return -EINVAL;
182} 198}
183 199
184static struct irq_chip cpm2_pic = { 200static 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
218static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct, 234static 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];