1 /* 2 * arch/powerpc/sysdev/ipic.c 3 * 4 * IPIC routines implementations. 5 * 6 * Copyright 2005 Freescale Semiconductor, Inc. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 */ 13 #include <linux/kernel.h> 14 #include <linux/init.h> 15 #include <linux/errno.h> 16 #include <linux/reboot.h> 17 #include <linux/slab.h> 18 #include <linux/stddef.h> 19 #include <linux/sched.h> 20 #include <linux/signal.h> 21 #include <linux/syscore_ops.h> 22 #include <linux/device.h> 23 #include <linux/spinlock.h> 24 #include <linux/fsl_devices.h> 25 #include <asm/irq.h> 26 #include <asm/io.h> 27 #include <asm/prom.h> 28 #include <asm/ipic.h> 29 30 #include "ipic.h" 31 32 static struct ipic * primary_ipic; 33 static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip; 34 static DEFINE_RAW_SPINLOCK(ipic_lock); 35 36 static struct ipic_info ipic_info[] = { 37 [1] = { 38 .mask = IPIC_SIMSR_H, 39 .prio = IPIC_SIPRR_C, 40 .force = IPIC_SIFCR_H, 41 .bit = 16, 42 .prio_mask = 0, 43 }, 44 [2] = { 45 .mask = IPIC_SIMSR_H, 46 .prio = IPIC_SIPRR_C, 47 .force = IPIC_SIFCR_H, 48 .bit = 17, 49 .prio_mask = 1, 50 }, 51 [3] = { 52 .mask = IPIC_SIMSR_H, 53 .prio = IPIC_SIPRR_C, 54 .force = IPIC_SIFCR_H, 55 .bit = 18, 56 .prio_mask = 2, 57 }, 58 [4] = { 59 .mask = IPIC_SIMSR_H, 60 .prio = IPIC_SIPRR_C, 61 .force = IPIC_SIFCR_H, 62 .bit = 19, 63 .prio_mask = 3, 64 }, 65 [5] = { 66 .mask = IPIC_SIMSR_H, 67 .prio = IPIC_SIPRR_C, 68 .force = IPIC_SIFCR_H, 69 .bit = 20, 70 .prio_mask = 4, 71 }, 72 [6] = { 73 .mask = IPIC_SIMSR_H, 74 .prio = IPIC_SIPRR_C, 75 .force = IPIC_SIFCR_H, 76 .bit = 21, 77 .prio_mask = 5, 78 }, 79 [7] = { 80 .mask = IPIC_SIMSR_H, 81 .prio = IPIC_SIPRR_C, 82 .force = IPIC_SIFCR_H, 83 .bit = 22, 84 .prio_mask = 6, 85 }, 86 [8] = { 87 .mask = IPIC_SIMSR_H, 88 .prio = IPIC_SIPRR_C, 89 .force = IPIC_SIFCR_H, 90 .bit = 23, 91 .prio_mask = 7, 92 }, 93 [9] = { 94 .mask = IPIC_SIMSR_H, 95 .prio = IPIC_SIPRR_D, 96 .force = IPIC_SIFCR_H, 97 .bit = 24, 98 .prio_mask = 0, 99 }, 100 [10] = { 101 .mask = IPIC_SIMSR_H, 102 .prio = IPIC_SIPRR_D, 103 .force = IPIC_SIFCR_H, 104 .bit = 25, 105 .prio_mask = 1, 106 }, 107 [11] = { 108 .mask = IPIC_SIMSR_H, 109 .prio = IPIC_SIPRR_D, 110 .force = IPIC_SIFCR_H, 111 .bit = 26, 112 .prio_mask = 2, 113 }, 114 [12] = { 115 .mask = IPIC_SIMSR_H, 116 .prio = IPIC_SIPRR_D, 117 .force = IPIC_SIFCR_H, 118 .bit = 27, 119 .prio_mask = 3, 120 }, 121 [13] = { 122 .mask = IPIC_SIMSR_H, 123 .prio = IPIC_SIPRR_D, 124 .force = IPIC_SIFCR_H, 125 .bit = 28, 126 .prio_mask = 4, 127 }, 128 [14] = { 129 .mask = IPIC_SIMSR_H, 130 .prio = IPIC_SIPRR_D, 131 .force = IPIC_SIFCR_H, 132 .bit = 29, 133 .prio_mask = 5, 134 }, 135 [15] = { 136 .mask = IPIC_SIMSR_H, 137 .prio = IPIC_SIPRR_D, 138 .force = IPIC_SIFCR_H, 139 .bit = 30, 140 .prio_mask = 6, 141 }, 142 [16] = { 143 .mask = IPIC_SIMSR_H, 144 .prio = IPIC_SIPRR_D, 145 .force = IPIC_SIFCR_H, 146 .bit = 31, 147 .prio_mask = 7, 148 }, 149 [17] = { 150 .ack = IPIC_SEPNR, 151 .mask = IPIC_SEMSR, 152 .prio = IPIC_SMPRR_A, 153 .force = IPIC_SEFCR, 154 .bit = 1, 155 .prio_mask = 5, 156 }, 157 [18] = { 158 .ack = IPIC_SEPNR, 159 .mask = IPIC_SEMSR, 160 .prio = IPIC_SMPRR_A, 161 .force = IPIC_SEFCR, 162 .bit = 2, 163 .prio_mask = 6, 164 }, 165 [19] = { 166 .ack = IPIC_SEPNR, 167 .mask = IPIC_SEMSR, 168 .prio = IPIC_SMPRR_A, 169 .force = IPIC_SEFCR, 170 .bit = 3, 171 .prio_mask = 7, 172 }, 173 [20] = { 174 .ack = IPIC_SEPNR, 175 .mask = IPIC_SEMSR, 176 .prio = IPIC_SMPRR_B, 177 .force = IPIC_SEFCR, 178 .bit = 4, 179 .prio_mask = 4, 180 }, 181 [21] = { 182 .ack = IPIC_SEPNR, 183 .mask = IPIC_SEMSR, 184 .prio = IPIC_SMPRR_B, 185 .force = IPIC_SEFCR, 186 .bit = 5, 187 .prio_mask = 5, 188 }, 189 [22] = { 190 .ack = IPIC_SEPNR, 191 .mask = IPIC_SEMSR, 192 .prio = IPIC_SMPRR_B, 193 .force = IPIC_SEFCR, 194 .bit = 6, 195 .prio_mask = 6, 196 }, 197 [23] = { 198 .ack = IPIC_SEPNR, 199 .mask = IPIC_SEMSR, 200 .prio = IPIC_SMPRR_B, 201 .force = IPIC_SEFCR, 202 .bit = 7, 203 .prio_mask = 7, 204 }, 205 [32] = { 206 .mask = IPIC_SIMSR_H, 207 .prio = IPIC_SIPRR_A, 208 .force = IPIC_SIFCR_H, 209 .bit = 0, 210 .prio_mask = 0, 211 }, 212 [33] = { 213 .mask = IPIC_SIMSR_H, 214 .prio = IPIC_SIPRR_A, 215 .force = IPIC_SIFCR_H, 216 .bit = 1, 217 .prio_mask = 1, 218 }, 219 [34] = { 220 .mask = IPIC_SIMSR_H, 221 .prio = IPIC_SIPRR_A, 222 .force = IPIC_SIFCR_H, 223 .bit = 2, 224 .prio_mask = 2, 225 }, 226 [35] = { 227 .mask = IPIC_SIMSR_H, 228 .prio = IPIC_SIPRR_A, 229 .force = IPIC_SIFCR_H, 230 .bit = 3, 231 .prio_mask = 3, 232 }, 233 [36] = { 234 .mask = IPIC_SIMSR_H, 235 .prio = IPIC_SIPRR_A, 236 .force = IPIC_SIFCR_H, 237 .bit = 4, 238 .prio_mask = 4, 239 }, 240 [37] = { 241 .mask = IPIC_SIMSR_H, 242 .prio = IPIC_SIPRR_A, 243 .force = IPIC_SIFCR_H, 244 .bit = 5, 245 .prio_mask = 5, 246 }, 247 [38] = { 248 .mask = IPIC_SIMSR_H, 249 .prio = IPIC_SIPRR_A, 250 .force = IPIC_SIFCR_H, 251 .bit = 6, 252 .prio_mask = 6, 253 }, 254 [39] = { 255 .mask = IPIC_SIMSR_H, 256 .prio = IPIC_SIPRR_A, 257 .force = IPIC_SIFCR_H, 258 .bit = 7, 259 .prio_mask = 7, 260 }, 261 [40] = { 262 .mask = IPIC_SIMSR_H, 263 .prio = IPIC_SIPRR_B, 264 .force = IPIC_SIFCR_H, 265 .bit = 8, 266 .prio_mask = 0, 267 }, 268 [41] = { 269 .mask = IPIC_SIMSR_H, 270 .prio = IPIC_SIPRR_B, 271 .force = IPIC_SIFCR_H, 272 .bit = 9, 273 .prio_mask = 1, 274 }, 275 [42] = { 276 .mask = IPIC_SIMSR_H, 277 .prio = IPIC_SIPRR_B, 278 .force = IPIC_SIFCR_H, 279 .bit = 10, 280 .prio_mask = 2, 281 }, 282 [43] = { 283 .mask = IPIC_SIMSR_H, 284 .prio = IPIC_SIPRR_B, 285 .force = IPIC_SIFCR_H, 286 .bit = 11, 287 .prio_mask = 3, 288 }, 289 [44] = { 290 .mask = IPIC_SIMSR_H, 291 .prio = IPIC_SIPRR_B, 292 .force = IPIC_SIFCR_H, 293 .bit = 12, 294 .prio_mask = 4, 295 }, 296 [45] = { 297 .mask = IPIC_SIMSR_H, 298 .prio = IPIC_SIPRR_B, 299 .force = IPIC_SIFCR_H, 300 .bit = 13, 301 .prio_mask = 5, 302 }, 303 [46] = { 304 .mask = IPIC_SIMSR_H, 305 .prio = IPIC_SIPRR_B, 306 .force = IPIC_SIFCR_H, 307 .bit = 14, 308 .prio_mask = 6, 309 }, 310 [47] = { 311 .mask = IPIC_SIMSR_H, 312 .prio = IPIC_SIPRR_B, 313 .force = IPIC_SIFCR_H, 314 .bit = 15, 315 .prio_mask = 7, 316 }, 317 [48] = { 318 .ack = IPIC_SEPNR, 319 .mask = IPIC_SEMSR, 320 .prio = IPIC_SMPRR_A, 321 .force = IPIC_SEFCR, 322 .bit = 0, 323 .prio_mask = 4, 324 }, 325 [64] = { 326 .mask = IPIC_SIMSR_L, 327 .prio = IPIC_SMPRR_A, 328 .force = IPIC_SIFCR_L, 329 .bit = 0, 330 .prio_mask = 0, 331 }, 332 [65] = { 333 .mask = IPIC_SIMSR_L, 334 .prio = IPIC_SMPRR_A, 335 .force = IPIC_SIFCR_L, 336 .bit = 1, 337 .prio_mask = 1, 338 }, 339 [66] = { 340 .mask = IPIC_SIMSR_L, 341 .prio = IPIC_SMPRR_A, 342 .force = IPIC_SIFCR_L, 343 .bit = 2, 344 .prio_mask = 2, 345 }, 346 [67] = { 347 .mask = IPIC_SIMSR_L, 348 .prio = IPIC_SMPRR_A, 349 .force = IPIC_SIFCR_L, 350 .bit = 3, 351 .prio_mask = 3, 352 }, 353 [68] = { 354 .mask = IPIC_SIMSR_L, 355 .prio = IPIC_SMPRR_B, 356 .force = IPIC_SIFCR_L, 357 .bit = 4, 358 .prio_mask = 0, 359 }, 360 [69] = { 361 .mask = IPIC_SIMSR_L, 362 .prio = IPIC_SMPRR_B, 363 .force = IPIC_SIFCR_L, 364 .bit = 5, 365 .prio_mask = 1, 366 }, 367 [70] = { 368 .mask = IPIC_SIMSR_L, 369 .prio = IPIC_SMPRR_B, 370 .force = IPIC_SIFCR_L, 371 .bit = 6, 372 .prio_mask = 2, 373 }, 374 [71] = { 375 .mask = IPIC_SIMSR_L, 376 .prio = IPIC_SMPRR_B, 377 .force = IPIC_SIFCR_L, 378 .bit = 7, 379 .prio_mask = 3, 380 }, 381 [72] = { 382 .mask = IPIC_SIMSR_L, 383 .prio = 0, 384 .force = IPIC_SIFCR_L, 385 .bit = 8, 386 }, 387 [73] = { 388 .mask = IPIC_SIMSR_L, 389 .prio = 0, 390 .force = IPIC_SIFCR_L, 391 .bit = 9, 392 }, 393 [74] = { 394 .mask = IPIC_SIMSR_L, 395 .prio = 0, 396 .force = IPIC_SIFCR_L, 397 .bit = 10, 398 }, 399 [75] = { 400 .mask = IPIC_SIMSR_L, 401 .prio = 0, 402 .force = IPIC_SIFCR_L, 403 .bit = 11, 404 }, 405 [76] = { 406 .mask = IPIC_SIMSR_L, 407 .prio = 0, 408 .force = IPIC_SIFCR_L, 409 .bit = 12, 410 }, 411 [77] = { 412 .mask = IPIC_SIMSR_L, 413 .prio = 0, 414 .force = IPIC_SIFCR_L, 415 .bit = 13, 416 }, 417 [78] = { 418 .mask = IPIC_SIMSR_L, 419 .prio = 0, 420 .force = IPIC_SIFCR_L, 421 .bit = 14, 422 }, 423 [79] = { 424 .mask = IPIC_SIMSR_L, 425 .prio = 0, 426 .force = IPIC_SIFCR_L, 427 .bit = 15, 428 }, 429 [80] = { 430 .mask = IPIC_SIMSR_L, 431 .prio = 0, 432 .force = IPIC_SIFCR_L, 433 .bit = 16, 434 }, 435 [81] = { 436 .mask = IPIC_SIMSR_L, 437 .prio = 0, 438 .force = IPIC_SIFCR_L, 439 .bit = 17, 440 }, 441 [82] = { 442 .mask = IPIC_SIMSR_L, 443 .prio = 0, 444 .force = IPIC_SIFCR_L, 445 .bit = 18, 446 }, 447 [83] = { 448 .mask = IPIC_SIMSR_L, 449 .prio = 0, 450 .force = IPIC_SIFCR_L, 451 .bit = 19, 452 }, 453 [84] = { 454 .mask = IPIC_SIMSR_L, 455 .prio = 0, 456 .force = IPIC_SIFCR_L, 457 .bit = 20, 458 }, 459 [85] = { 460 .mask = IPIC_SIMSR_L, 461 .prio = 0, 462 .force = IPIC_SIFCR_L, 463 .bit = 21, 464 }, 465 [86] = { 466 .mask = IPIC_SIMSR_L, 467 .prio = 0, 468 .force = IPIC_SIFCR_L, 469 .bit = 22, 470 }, 471 [87] = { 472 .mask = IPIC_SIMSR_L, 473 .prio = 0, 474 .force = IPIC_SIFCR_L, 475 .bit = 23, 476 }, 477 [88] = { 478 .mask = IPIC_SIMSR_L, 479 .prio = 0, 480 .force = IPIC_SIFCR_L, 481 .bit = 24, 482 }, 483 [89] = { 484 .mask = IPIC_SIMSR_L, 485 .prio = 0, 486 .force = IPIC_SIFCR_L, 487 .bit = 25, 488 }, 489 [90] = { 490 .mask = IPIC_SIMSR_L, 491 .prio = 0, 492 .force = IPIC_SIFCR_L, 493 .bit = 26, 494 }, 495 [91] = { 496 .mask = IPIC_SIMSR_L, 497 .prio = 0, 498 .force = IPIC_SIFCR_L, 499 .bit = 27, 500 }, 501 [94] = { 502 .mask = IPIC_SIMSR_L, 503 .prio = 0, 504 .force = IPIC_SIFCR_L, 505 .bit = 30, 506 }, 507 }; 508 509 static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg) 510 { 511 return in_be32(base + (reg >> 2)); 512 } 513 514 static inline void ipic_write(volatile u32 __iomem *base, unsigned int reg, u32 value) 515 { 516 out_be32(base + (reg >> 2), value); 517 } 518 519 static inline struct ipic * ipic_from_irq(unsigned int virq) 520 { 521 return primary_ipic; 522 } 523 524 static void ipic_unmask_irq(struct irq_data *d) 525 { 526 struct ipic *ipic = ipic_from_irq(d->irq); 527 unsigned int src = irqd_to_hwirq(d); 528 unsigned long flags; 529 u32 temp; 530 531 raw_spin_lock_irqsave(&ipic_lock, flags); 532 533 temp = ipic_read(ipic->regs, ipic_info[src].mask); 534 temp |= (1 << (31 - ipic_info[src].bit)); 535 ipic_write(ipic->regs, ipic_info[src].mask, temp); 536 537 raw_spin_unlock_irqrestore(&ipic_lock, flags); 538 } 539 540 static void ipic_mask_irq(struct irq_data *d) 541 { 542 struct ipic *ipic = ipic_from_irq(d->irq); 543 unsigned int src = irqd_to_hwirq(d); 544 unsigned long flags; 545 u32 temp; 546 547 raw_spin_lock_irqsave(&ipic_lock, flags); 548 549 temp = ipic_read(ipic->regs, ipic_info[src].mask); 550 temp &= ~(1 << (31 - ipic_info[src].bit)); 551 ipic_write(ipic->regs, ipic_info[src].mask, temp); 552 553 /* mb() can't guarantee that masking is finished. But it does finish 554 * for nearly all cases. */ 555 mb(); 556 557 raw_spin_unlock_irqrestore(&ipic_lock, flags); 558 } 559 560 static void ipic_ack_irq(struct irq_data *d) 561 { 562 struct ipic *ipic = ipic_from_irq(d->irq); 563 unsigned int src = irqd_to_hwirq(d); 564 unsigned long flags; 565 u32 temp; 566 567 raw_spin_lock_irqsave(&ipic_lock, flags); 568 569 temp = 1 << (31 - ipic_info[src].bit); 570 ipic_write(ipic->regs, ipic_info[src].ack, temp); 571 572 /* mb() can't guarantee that ack is finished. But it does finish 573 * for nearly all cases. */ 574 mb(); 575 576 raw_spin_unlock_irqrestore(&ipic_lock, flags); 577 } 578 579 static void ipic_mask_irq_and_ack(struct irq_data *d) 580 { 581 struct ipic *ipic = ipic_from_irq(d->irq); 582 unsigned int src = irqd_to_hwirq(d); 583 unsigned long flags; 584 u32 temp; 585 586 raw_spin_lock_irqsave(&ipic_lock, flags); 587 588 temp = ipic_read(ipic->regs, ipic_info[src].mask); 589 temp &= ~(1 << (31 - ipic_info[src].bit)); 590 ipic_write(ipic->regs, ipic_info[src].mask, temp); 591 592 temp = 1 << (31 - ipic_info[src].bit); 593 ipic_write(ipic->regs, ipic_info[src].ack, temp); 594 595 /* mb() can't guarantee that ack is finished. But it does finish 596 * for nearly all cases. */ 597 mb(); 598 599 raw_spin_unlock_irqrestore(&ipic_lock, flags); 600 } 601 602 static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type) 603 { 604 struct ipic *ipic = ipic_from_irq(d->irq); 605 unsigned int src = irqd_to_hwirq(d); 606 unsigned int vold, vnew, edibit; 607 608 if (flow_type == IRQ_TYPE_NONE) 609 flow_type = IRQ_TYPE_LEVEL_LOW; 610 611 /* ipic supports only low assertion and high-to-low change senses 612 */ 613 if (!(flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))) { 614 printk(KERN_ERR "ipic: sense type 0x%x not supported\n", 615 flow_type); 616 return -EINVAL; 617 } 618 /* ipic supports only edge mode on external interrupts */ 619 if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !ipic_info[src].ack) { 620 printk(KERN_ERR "ipic: edge sense not supported on internal " 621 "interrupts\n"); 622 return -EINVAL; 623 624 } 625 626 irqd_set_trigger_type(d, flow_type); 627 if (flow_type & IRQ_TYPE_LEVEL_LOW) { 628 irq_set_handler_locked(d, handle_level_irq); 629 d->chip = &ipic_level_irq_chip; 630 } else { 631 irq_set_handler_locked(d, handle_edge_irq); 632 d->chip = &ipic_edge_irq_chip; 633 } 634 635 /* only EXT IRQ senses are programmable on ipic 636 * internal IRQ senses are LEVEL_LOW 637 */ 638 if (src == IPIC_IRQ_EXT0) 639 edibit = 15; 640 else 641 if (src >= IPIC_IRQ_EXT1 && src <= IPIC_IRQ_EXT7) 642 edibit = (14 - (src - IPIC_IRQ_EXT1)); 643 else 644 return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL; 645 646 vold = ipic_read(ipic->regs, IPIC_SECNR); 647 if ((flow_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_FALLING) { 648 vnew = vold | (1 << edibit); 649 } else { 650 vnew = vold & ~(1 << edibit); 651 } 652 if (vold != vnew) 653 ipic_write(ipic->regs, IPIC_SECNR, vnew); 654 return IRQ_SET_MASK_OK_NOCOPY; 655 } 656 657 /* level interrupts and edge interrupts have different ack operations */ 658 static struct irq_chip ipic_level_irq_chip = { 659 .name = "IPIC", 660 .irq_unmask = ipic_unmask_irq, 661 .irq_mask = ipic_mask_irq, 662 .irq_mask_ack = ipic_mask_irq, 663 .irq_set_type = ipic_set_irq_type, 664 }; 665 666 static struct irq_chip ipic_edge_irq_chip = { 667 .name = "IPIC", 668 .irq_unmask = ipic_unmask_irq, 669 .irq_mask = ipic_mask_irq, 670 .irq_mask_ack = ipic_mask_irq_and_ack, 671 .irq_ack = ipic_ack_irq, 672 .irq_set_type = ipic_set_irq_type, 673 }; 674 675 static int ipic_host_match(struct irq_domain *h, struct device_node *node, 676 enum irq_domain_bus_token bus_token) 677 { 678 /* Exact match, unless ipic node is NULL */ 679 struct device_node *of_node = irq_domain_get_of_node(h); 680 return of_node == NULL || of_node == node; 681 } 682 683 static int ipic_host_map(struct irq_domain *h, unsigned int virq, 684 irq_hw_number_t hw) 685 { 686 struct ipic *ipic = h->host_data; 687 688 irq_set_chip_data(virq, ipic); 689 irq_set_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq); 690 691 /* Set default irq type */ 692 irq_set_irq_type(virq, IRQ_TYPE_NONE); 693 694 return 0; 695 } 696 697 static const struct irq_domain_ops ipic_host_ops = { 698 .match = ipic_host_match, 699 .map = ipic_host_map, 700 .xlate = irq_domain_xlate_onetwocell, 701 }; 702 703 struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) 704 { 705 struct ipic *ipic; 706 struct resource res; 707 u32 temp = 0, ret; 708 709 ret = of_address_to_resource(node, 0, &res); 710 if (ret) 711 return NULL; 712 713 ipic = kzalloc(sizeof(*ipic), GFP_KERNEL); 714 if (ipic == NULL) 715 return NULL; 716 717 ipic->irqhost = irq_domain_add_linear(node, NR_IPIC_INTS, 718 &ipic_host_ops, ipic); 719 if (ipic->irqhost == NULL) { 720 kfree(ipic); 721 return NULL; 722 } 723 724 ipic->regs = ioremap(res.start, resource_size(&res)); 725 726 /* init hw */ 727 ipic_write(ipic->regs, IPIC_SICNR, 0x0); 728 729 /* default priority scheme is grouped. If spread mode is required 730 * configure SICFR accordingly */ 731 if (flags & IPIC_SPREADMODE_GRP_A) 732 temp |= SICFR_IPSA; 733 if (flags & IPIC_SPREADMODE_GRP_B) 734 temp |= SICFR_IPSB; 735 if (flags & IPIC_SPREADMODE_GRP_C) 736 temp |= SICFR_IPSC; 737 if (flags & IPIC_SPREADMODE_GRP_D) 738 temp |= SICFR_IPSD; 739 if (flags & IPIC_SPREADMODE_MIX_A) 740 temp |= SICFR_MPSA; 741 if (flags & IPIC_SPREADMODE_MIX_B) 742 temp |= SICFR_MPSB; 743 744 ipic_write(ipic->regs, IPIC_SICFR, temp); 745 746 /* handle MCP route */ 747 temp = 0; 748 if (flags & IPIC_DISABLE_MCP_OUT) 749 temp = SERCR_MCPR; 750 ipic_write(ipic->regs, IPIC_SERCR, temp); 751 752 /* handle routing of IRQ0 to MCP */ 753 temp = ipic_read(ipic->regs, IPIC_SEMSR); 754 755 if (flags & IPIC_IRQ0_MCP) 756 temp |= SEMSR_SIRQ0; 757 else 758 temp &= ~SEMSR_SIRQ0; 759 760 ipic_write(ipic->regs, IPIC_SEMSR, temp); 761 762 primary_ipic = ipic; 763 irq_set_default_host(primary_ipic->irqhost); 764 765 ipic_write(ipic->regs, IPIC_SIMSR_H, 0); 766 ipic_write(ipic->regs, IPIC_SIMSR_L, 0); 767 768 printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS, 769 primary_ipic->regs); 770 771 return ipic; 772 } 773 774 int ipic_set_priority(unsigned int virq, unsigned int priority) 775 { 776 struct ipic *ipic = ipic_from_irq(virq); 777 unsigned int src = virq_to_hw(virq); 778 u32 temp; 779 780 if (priority > 7) 781 return -EINVAL; 782 if (src > 127) 783 return -EINVAL; 784 if (ipic_info[src].prio == 0) 785 return -EINVAL; 786 787 temp = ipic_read(ipic->regs, ipic_info[src].prio); 788 789 if (priority < 4) { 790 temp &= ~(0x7 << (20 + (3 - priority) * 3)); 791 temp |= ipic_info[src].prio_mask << (20 + (3 - priority) * 3); 792 } else { 793 temp &= ~(0x7 << (4 + (7 - priority) * 3)); 794 temp |= ipic_info[src].prio_mask << (4 + (7 - priority) * 3); 795 } 796 797 ipic_write(ipic->regs, ipic_info[src].prio, temp); 798 799 return 0; 800 } 801 802 void ipic_set_highest_priority(unsigned int virq) 803 { 804 struct ipic *ipic = ipic_from_irq(virq); 805 unsigned int src = virq_to_hw(virq); 806 u32 temp; 807 808 temp = ipic_read(ipic->regs, IPIC_SICFR); 809 810 /* clear and set HPI */ 811 temp &= 0x7f000000; 812 temp |= (src & 0x7f) << 24; 813 814 ipic_write(ipic->regs, IPIC_SICFR, temp); 815 } 816 817 void ipic_set_default_priority(void) 818 { 819 ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_PRIORITY_DEFAULT); 820 ipic_write(primary_ipic->regs, IPIC_SIPRR_B, IPIC_PRIORITY_DEFAULT); 821 ipic_write(primary_ipic->regs, IPIC_SIPRR_C, IPIC_PRIORITY_DEFAULT); 822 ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_PRIORITY_DEFAULT); 823 ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_PRIORITY_DEFAULT); 824 ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_PRIORITY_DEFAULT); 825 } 826 827 void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) 828 { 829 struct ipic *ipic = primary_ipic; 830 u32 temp; 831 832 temp = ipic_read(ipic->regs, IPIC_SERMR); 833 temp |= (1 << (31 - mcp_irq)); 834 ipic_write(ipic->regs, IPIC_SERMR, temp); 835 } 836 837 void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq) 838 { 839 struct ipic *ipic = primary_ipic; 840 u32 temp; 841 842 temp = ipic_read(ipic->regs, IPIC_SERMR); 843 temp &= (1 << (31 - mcp_irq)); 844 ipic_write(ipic->regs, IPIC_SERMR, temp); 845 } 846 847 u32 ipic_get_mcp_status(void) 848 { 849 return primary_ipic ? ipic_read(primary_ipic->regs, IPIC_SERSR) : 0; 850 } 851 852 void ipic_clear_mcp_status(u32 mask) 853 { 854 ipic_write(primary_ipic->regs, IPIC_SERSR, mask); 855 } 856 857 /* Return an interrupt vector or 0 if no interrupt is pending. */ 858 unsigned int ipic_get_irq(void) 859 { 860 int irq; 861 862 BUG_ON(primary_ipic == NULL); 863 864 #define IPIC_SIVCR_VECTOR_MASK 0x7f 865 irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & IPIC_SIVCR_VECTOR_MASK; 866 867 if (irq == 0) /* 0 --> no irq is pending */ 868 return 0; 869 870 return irq_linear_revmap(primary_ipic->irqhost, irq); 871 } 872 873 #ifdef CONFIG_SUSPEND 874 static struct { 875 u32 sicfr; 876 u32 siprr[2]; 877 u32 simsr[2]; 878 u32 sicnr; 879 u32 smprr[2]; 880 u32 semsr; 881 u32 secnr; 882 u32 sermr; 883 u32 sercr; 884 } ipic_saved_state; 885 886 static int ipic_suspend(void) 887 { 888 struct ipic *ipic = primary_ipic; 889 890 ipic_saved_state.sicfr = ipic_read(ipic->regs, IPIC_SICFR); 891 ipic_saved_state.siprr[0] = ipic_read(ipic->regs, IPIC_SIPRR_A); 892 ipic_saved_state.siprr[1] = ipic_read(ipic->regs, IPIC_SIPRR_D); 893 ipic_saved_state.simsr[0] = ipic_read(ipic->regs, IPIC_SIMSR_H); 894 ipic_saved_state.simsr[1] = ipic_read(ipic->regs, IPIC_SIMSR_L); 895 ipic_saved_state.sicnr = ipic_read(ipic->regs, IPIC_SICNR); 896 ipic_saved_state.smprr[0] = ipic_read(ipic->regs, IPIC_SMPRR_A); 897 ipic_saved_state.smprr[1] = ipic_read(ipic->regs, IPIC_SMPRR_B); 898 ipic_saved_state.semsr = ipic_read(ipic->regs, IPIC_SEMSR); 899 ipic_saved_state.secnr = ipic_read(ipic->regs, IPIC_SECNR); 900 ipic_saved_state.sermr = ipic_read(ipic->regs, IPIC_SERMR); 901 ipic_saved_state.sercr = ipic_read(ipic->regs, IPIC_SERCR); 902 903 if (fsl_deep_sleep()) { 904 /* In deep sleep, make sure there can be no 905 * pending interrupts, as this can cause 906 * problems on 831x. 907 */ 908 ipic_write(ipic->regs, IPIC_SIMSR_H, 0); 909 ipic_write(ipic->regs, IPIC_SIMSR_L, 0); 910 ipic_write(ipic->regs, IPIC_SEMSR, 0); 911 ipic_write(ipic->regs, IPIC_SERMR, 0); 912 } 913 914 return 0; 915 } 916 917 static void ipic_resume(void) 918 { 919 struct ipic *ipic = primary_ipic; 920 921 ipic_write(ipic->regs, IPIC_SICFR, ipic_saved_state.sicfr); 922 ipic_write(ipic->regs, IPIC_SIPRR_A, ipic_saved_state.siprr[0]); 923 ipic_write(ipic->regs, IPIC_SIPRR_D, ipic_saved_state.siprr[1]); 924 ipic_write(ipic->regs, IPIC_SIMSR_H, ipic_saved_state.simsr[0]); 925 ipic_write(ipic->regs, IPIC_SIMSR_L, ipic_saved_state.simsr[1]); 926 ipic_write(ipic->regs, IPIC_SICNR, ipic_saved_state.sicnr); 927 ipic_write(ipic->regs, IPIC_SMPRR_A, ipic_saved_state.smprr[0]); 928 ipic_write(ipic->regs, IPIC_SMPRR_B, ipic_saved_state.smprr[1]); 929 ipic_write(ipic->regs, IPIC_SEMSR, ipic_saved_state.semsr); 930 ipic_write(ipic->regs, IPIC_SECNR, ipic_saved_state.secnr); 931 ipic_write(ipic->regs, IPIC_SERMR, ipic_saved_state.sermr); 932 ipic_write(ipic->regs, IPIC_SERCR, ipic_saved_state.sercr); 933 } 934 #else 935 #define ipic_suspend NULL 936 #define ipic_resume NULL 937 #endif 938 939 static struct syscore_ops ipic_syscore_ops = { 940 .suspend = ipic_suspend, 941 .resume = ipic_resume, 942 }; 943 944 static int __init init_ipic_syscore(void) 945 { 946 if (!primary_ipic || !primary_ipic->regs) 947 return -ENODEV; 948 949 printk(KERN_DEBUG "Registering ipic system core operations\n"); 950 register_syscore_ops(&ipic_syscore_ops); 951 952 return 0; 953 } 954 955 subsys_initcall(init_ipic_syscore); 956