aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/xics.c
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2011-03-07 08:59:45 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-03-09 19:04:01 -0500
commit79f26c268ebad29bd75d078cfc09d3d82b30ccbd (patch)
treea797234dbbe8385f297de472dda8c0981b1e3150 /arch/powerpc/platforms/pseries/xics.c
parent8126708ae8f2bb7cf98a38ca89b5cfd96d897a05 (diff)
powerpc: platforms/pseries irq_data conversion.
Signed-off-by: Lennert Buytenhek <buytenh@secretlab.ca> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms/pseries/xics.c')
-rw-r--r--arch/powerpc/platforms/pseries/xics.c89
1 files changed, 47 insertions, 42 deletions
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 7b96e5a270c..01fea46c033 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -202,20 +202,20 @@ static int get_irq_server(unsigned int virq, const struct cpumask *cpumask,
202#define get_irq_server(virq, cpumask, strict_check) (default_server) 202#define get_irq_server(virq, cpumask, strict_check) (default_server)
203#endif 203#endif
204 204
205static void xics_unmask_irq(unsigned int virq) 205static void xics_unmask_irq(struct irq_data *d)
206{ 206{
207 unsigned int irq; 207 unsigned int irq;
208 int call_status; 208 int call_status;
209 int server; 209 int server;
210 210
211 pr_devel("xics: unmask virq %d\n", virq); 211 pr_devel("xics: unmask virq %d\n", d->irq);
212 212
213 irq = (unsigned int)irq_map[virq].hwirq; 213 irq = (unsigned int)irq_map[d->irq].hwirq;
214 pr_devel(" -> map to hwirq 0x%x\n", irq); 214 pr_devel(" -> map to hwirq 0x%x\n", irq);
215 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) 215 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
216 return; 216 return;
217 217
218 server = get_irq_server(virq, irq_to_desc(virq)->affinity, 0); 218 server = get_irq_server(d->irq, d->affinity, 0);
219 219
220 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, 220 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
221 DEFAULT_PRIORITY); 221 DEFAULT_PRIORITY);
@@ -235,61 +235,61 @@ static void xics_unmask_irq(unsigned int virq)
235 } 235 }
236} 236}
237 237
238static unsigned int xics_startup(unsigned int virq) 238static unsigned int xics_startup(struct irq_data *d)
239{ 239{
240 /* 240 /*
241 * The generic MSI code returns with the interrupt disabled on the 241 * The generic MSI code returns with the interrupt disabled on the
242 * card, using the MSI mask bits. Firmware doesn't appear to unmask 242 * card, using the MSI mask bits. Firmware doesn't appear to unmask
243 * at that level, so we do it here by hand. 243 * at that level, so we do it here by hand.
244 */ 244 */
245 if (irq_to_desc(virq)->msi_desc) 245 if (d->msi_desc)
246 unmask_msi_irq(irq_get_irq_data(virq)); 246 unmask_msi_irq(d);
247 247
248 /* unmask it */ 248 /* unmask it */
249 xics_unmask_irq(virq); 249 xics_unmask_irq(d);
250 return 0; 250 return 0;
251} 251}
252 252
253static void xics_mask_real_irq(unsigned int irq) 253static void xics_mask_real_irq(struct irq_data *d)
254{ 254{
255 int call_status; 255 int call_status;
256 256
257 if (irq == XICS_IPI) 257 if (d->irq == XICS_IPI)
258 return; 258 return;
259 259
260 call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq); 260 call_status = rtas_call(ibm_int_off, 1, 1, NULL, d->irq);
261 if (call_status != 0) { 261 if (call_status != 0) {
262 printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n", 262 printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
263 __func__, irq, call_status); 263 __func__, d->irq, call_status);
264 return; 264 return;
265 } 265 }
266 266
267 /* Have to set XIVE to 0xff to be able to remove a slot */ 267 /* Have to set XIVE to 0xff to be able to remove a slot */
268 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, 268 call_status = rtas_call(ibm_set_xive, 3, 1, NULL, d->irq,
269 default_server, 0xff); 269 default_server, 0xff);
270 if (call_status != 0) { 270 if (call_status != 0) {
271 printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n", 271 printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
272 __func__, irq, call_status); 272 __func__, d->irq, call_status);
273 return; 273 return;
274 } 274 }
275} 275}
276 276
277static void xics_mask_irq(unsigned int virq) 277static void xics_mask_irq(struct irq_data *d)
278{ 278{
279 unsigned int irq; 279 unsigned int irq;
280 280
281 pr_devel("xics: mask virq %d\n", virq); 281 pr_devel("xics: mask virq %d\n", d->irq);
282 282
283 irq = (unsigned int)irq_map[virq].hwirq; 283 irq = (unsigned int)irq_map[d->irq].hwirq;
284 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) 284 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
285 return; 285 return;
286 xics_mask_real_irq(irq); 286 xics_mask_real_irq(d);
287} 287}
288 288
289static void xics_mask_unknown_vec(unsigned int vec) 289static void xics_mask_unknown_vec(unsigned int vec)
290{ 290{
291 printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec); 291 printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec);
292 xics_mask_real_irq(vec); 292 xics_mask_real_irq(irq_get_irq_data(vec));
293} 293}
294 294
295static inline unsigned int xics_xirr_vector(unsigned int xirr) 295static inline unsigned int xics_xirr_vector(unsigned int xirr)
@@ -371,30 +371,31 @@ static unsigned char pop_cppr(void)
371 return os_cppr->stack[--os_cppr->index]; 371 return os_cppr->stack[--os_cppr->index];
372} 372}
373 373
374static void xics_eoi_direct(unsigned int virq) 374static void xics_eoi_direct(struct irq_data *d)
375{ 375{
376 unsigned int irq = (unsigned int)irq_map[virq].hwirq; 376 unsigned int irq = (unsigned int)irq_map[d->irq].hwirq;
377 377
378 iosync(); 378 iosync();
379 direct_xirr_info_set((pop_cppr() << 24) | irq); 379 direct_xirr_info_set((pop_cppr() << 24) | irq);
380} 380}
381 381
382static void xics_eoi_lpar(unsigned int virq) 382static void xics_eoi_lpar(struct irq_data *d)
383{ 383{
384 unsigned int irq = (unsigned int)irq_map[virq].hwirq; 384 unsigned int irq = (unsigned int)irq_map[d->irq].hwirq;
385 385
386 iosync(); 386 iosync();
387 lpar_xirr_info_set((pop_cppr() << 24) | irq); 387 lpar_xirr_info_set((pop_cppr() << 24) | irq);
388} 388}
389 389
390static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask) 390static int
391xics_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force)
391{ 392{
392 unsigned int irq; 393 unsigned int irq;
393 int status; 394 int status;
394 int xics_status[2]; 395 int xics_status[2];
395 int irq_server; 396 int irq_server;
396 397
397 irq = (unsigned int)irq_map[virq].hwirq; 398 irq = (unsigned int)irq_map[d->irq].hwirq;
398 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) 399 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
399 return -1; 400 return -1;
400 401
@@ -406,13 +407,13 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
406 return -1; 407 return -1;
407 } 408 }
408 409
409 irq_server = get_irq_server(virq, cpumask, 1); 410 irq_server = get_irq_server(d->irq, cpumask, 1);
410 if (irq_server == -1) { 411 if (irq_server == -1) {
411 char cpulist[128]; 412 char cpulist[128];
412 cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask); 413 cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
413 printk(KERN_WARNING 414 printk(KERN_WARNING
414 "%s: No online cpus in the mask %s for irq %d\n", 415 "%s: No online cpus in the mask %s for irq %d\n",
415 __func__, cpulist, virq); 416 __func__, cpulist, d->irq);
416 return -1; 417 return -1;
417 } 418 }
418 419
@@ -430,20 +431,20 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
430 431
431static struct irq_chip xics_pic_direct = { 432static struct irq_chip xics_pic_direct = {
432 .name = "XICS", 433 .name = "XICS",
433 .startup = xics_startup, 434 .irq_startup = xics_startup,
434 .mask = xics_mask_irq, 435 .irq_mask = xics_mask_irq,
435 .unmask = xics_unmask_irq, 436 .irq_unmask = xics_unmask_irq,
436 .eoi = xics_eoi_direct, 437 .irq_eoi = xics_eoi_direct,
437 .set_affinity = xics_set_affinity 438 .irq_set_affinity = xics_set_affinity
438}; 439};
439 440
440static struct irq_chip xics_pic_lpar = { 441static struct irq_chip xics_pic_lpar = {
441 .name = "XICS", 442 .name = "XICS",
442 .startup = xics_startup, 443 .irq_startup = xics_startup,
443 .mask = xics_mask_irq, 444 .irq_mask = xics_mask_irq,
444 .unmask = xics_unmask_irq, 445 .irq_unmask = xics_unmask_irq,
445 .eoi = xics_eoi_lpar, 446 .irq_eoi = xics_eoi_lpar,
446 .set_affinity = xics_set_affinity 447 .irq_set_affinity = xics_set_affinity
447}; 448};
448 449
449 450
@@ -890,6 +891,7 @@ void xics_migrate_irqs_away(void)
890 891
891 for_each_irq(virq) { 892 for_each_irq(virq) {
892 struct irq_desc *desc; 893 struct irq_desc *desc;
894 struct irq_chip *chip;
893 int xics_status[2]; 895 int xics_status[2];
894 int status; 896 int status;
895 unsigned long flags; 897 unsigned long flags;
@@ -903,12 +905,15 @@ void xics_migrate_irqs_away(void)
903 /* We need to get IPIs still. */ 905 /* We need to get IPIs still. */
904 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS) 906 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
905 continue; 907 continue;
908
906 desc = irq_to_desc(virq); 909 desc = irq_to_desc(virq);
907 910
908 /* We only need to migrate enabled IRQS */ 911 /* We only need to migrate enabled IRQS */
909 if (desc == NULL || desc->chip == NULL 912 if (desc == NULL || desc->action == NULL)
910 || desc->action == NULL 913 continue;
911 || desc->chip->set_affinity == NULL) 914
915 chip = get_irq_desc_chip(desc);
916 if (chip == NULL || chip->irq_set_affinity == NULL)
912 continue; 917 continue;
913 918
914 raw_spin_lock_irqsave(&desc->lock, flags); 919 raw_spin_lock_irqsave(&desc->lock, flags);
@@ -934,8 +939,8 @@ void xics_migrate_irqs_away(void)
934 virq, cpu); 939 virq, cpu);
935 940
936 /* Reset affinity to all cpus */ 941 /* Reset affinity to all cpus */
937 cpumask_setall(irq_to_desc(virq)->affinity); 942 cpumask_setall(desc->irq_data.affinity);
938 desc->chip->set_affinity(virq, cpu_all_mask); 943 chip->irq_set_affinity(&desc->irq_data, cpu_all_mask, true);
939unlock: 944unlock:
940 raw_spin_unlock_irqrestore(&desc->lock, flags); 945 raw_spin_unlock_irqrestore(&desc->lock, flags);
941 } 946 }