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 32static struct ipic * primary_ipic; 33static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip; 34static DEFINE_RAW_SPINLOCK(ipic_lock); 35 36static 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 .mask = IPIC_SEMSR, 319 .prio = IPIC_SMPRR_A, 320 .force = IPIC_SEFCR, 321 .bit = 0, 322 .prio_mask = 4, 323 }, 324 [64] = { 325 .mask = IPIC_SIMSR_L, 326 .prio = IPIC_SMPRR_A, 327 .force = IPIC_SIFCR_L, 328 .bit = 0, 329 .prio_mask = 0, 330 }, 331 [65] = { 332 .mask = IPIC_SIMSR_L, 333 .prio = IPIC_SMPRR_A, 334 .force = IPIC_SIFCR_L, 335 .bit = 1, 336 .prio_mask = 1, 337 }, 338 [66] = { 339 .mask = IPIC_SIMSR_L, 340 .prio = IPIC_SMPRR_A, 341 .force = IPIC_SIFCR_L, 342 .bit = 2, 343 .prio_mask = 2, 344 }, 345 [67] = { 346 .mask = IPIC_SIMSR_L, 347 .prio = IPIC_SMPRR_A, 348 .force = IPIC_SIFCR_L, 349 .bit = 3, 350 .prio_mask = 3, 351 }, 352 [68] = { 353 .mask = IPIC_SIMSR_L, 354 .prio = IPIC_SMPRR_B, 355 .force = IPIC_SIFCR_L, 356 .bit = 4, 357 .prio_mask = 0, 358 }, 359 [69] = { 360 .mask = IPIC_SIMSR_L, 361 .prio = IPIC_SMPRR_B, 362 .force = IPIC_SIFCR_L, 363 .bit = 5, 364 .prio_mask = 1, 365 }, 366 [70] = { 367 .mask = IPIC_SIMSR_L, 368 .prio = IPIC_SMPRR_B, 369 .force = IPIC_SIFCR_L, 370 .bit = 6, 371 .prio_mask = 2, 372 }, 373 [71] = { 374 .mask = IPIC_SIMSR_L, 375 .prio = IPIC_SMPRR_B, 376 .force = IPIC_SIFCR_L, 377 .bit = 7, 378 .prio_mask = 3, 379 }, 380 [72] = { 381 .mask = IPIC_SIMSR_L, 382 .prio = 0, 383 .force = IPIC_SIFCR_L, 384 .bit = 8, 385 }, 386 [73] = { 387 .mask = IPIC_SIMSR_L, 388 .prio = 0, 389 .force = IPIC_SIFCR_L, 390 .bit = 9, 391 }, 392 [74] = { 393 .mask = IPIC_SIMSR_L, 394 .prio = 0, 395 .force = IPIC_SIFCR_L, 396 .bit = 10, 397 }, 398 [75] = { 399 .mask = IPIC_SIMSR_L, 400 .prio = 0, 401 .force = IPIC_SIFCR_L, 402 .bit = 11, 403 }, 404 [76] = { 405 .mask = IPIC_SIMSR_L, 406 .prio = 0, 407 .force = IPIC_SIFCR_L, 408 .bit = 12, 409 }, 410 [77] = { 411 .mask = IPIC_SIMSR_L, 412 .prio = 0, 413 .force = IPIC_SIFCR_L, 414 .bit = 13, 415 }, 416 [78] = { 417 .mask = IPIC_SIMSR_L, 418 .prio = 0, 419 .force = IPIC_SIFCR_L, 420 .bit = 14, 421 }, 422 [79] = { 423 .mask = IPIC_SIMSR_L, 424 .prio = 0, 425 .force = IPIC_SIFCR_L, 426 .bit = 15, 427 }, 428 [80] = { 429 .mask = IPIC_SIMSR_L, 430 .prio = 0, 431 .force = IPIC_SIFCR_L, 432 .bit = 16, 433 }, 434 [81] = { 435 .mask = IPIC_SIMSR_L, 436 .prio = 0, 437 .force = IPIC_SIFCR_L, 438 .bit = 17, 439 }, 440 [82] = { 441 .mask = IPIC_SIMSR_L, 442 .prio = 0, 443 .force = IPIC_SIFCR_L, 444 .bit = 18, 445 }, 446 [83] = { 447 .mask = IPIC_SIMSR_L, 448 .prio = 0, 449 .force = IPIC_SIFCR_L, 450 .bit = 19, 451 }, 452 [84] = { 453 .mask = IPIC_SIMSR_L, 454 .prio = 0, 455 .force = IPIC_SIFCR_L, 456 .bit = 20, 457 }, 458 [85] = { 459 .mask = IPIC_SIMSR_L, 460 .prio = 0, 461 .force = IPIC_SIFCR_L, 462 .bit = 21, 463 }, 464 [86] = { 465 .mask = IPIC_SIMSR_L, 466 .prio = 0, 467 .force = IPIC_SIFCR_L, 468 .bit = 22, 469 }, 470 [87] = { 471 .mask = IPIC_SIMSR_L, 472 .prio = 0, 473 .force = IPIC_SIFCR_L, 474 .bit = 23, 475 }, 476 [88] = { 477 .mask = IPIC_SIMSR_L, 478 .prio = 0, 479 .force = IPIC_SIFCR_L, 480 .bit = 24, 481 }, 482 [89] = { 483 .mask = IPIC_SIMSR_L, 484 .prio = 0, 485 .force = IPIC_SIFCR_L, 486 .bit = 25, 487 }, 488 [90] = { 489 .mask = IPIC_SIMSR_L, 490 .prio = 0, 491 .force = IPIC_SIFCR_L, 492 .bit = 26, 493 }, 494 [91] = { 495 .mask = IPIC_SIMSR_L, 496 .prio = 0, 497 .force = IPIC_SIFCR_L, 498 .bit = 27, 499 }, 500 [94] = { 501 .mask = IPIC_SIMSR_L, 502 .prio = 0, 503 .force = IPIC_SIFCR_L, 504 .bit = 30, 505 }, 506}; 507 508static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg) 509{ 510 return in_be32(base + (reg >> 2)); 511} 512 513static inline void ipic_write(volatile u32 __iomem *base, unsigned int reg, u32 value) 514{ 515 out_be32(base + (reg >> 2), value); 516} 517 518static inline struct ipic * ipic_from_irq(unsigned int virq) 519{ 520 return primary_ipic; 521} 522 523static void ipic_unmask_irq(struct irq_data *d) 524{ 525 struct ipic *ipic = ipic_from_irq(d->irq); 526 unsigned int src = irqd_to_hwirq(d); 527 unsigned long flags; 528 u32 temp; 529 530 raw_spin_lock_irqsave(&ipic_lock, flags); 531 532 temp = ipic_read(ipic->regs, ipic_info[src].mask); 533 temp |= (1 << (31 - ipic_info[src].bit)); 534 ipic_write(ipic->regs, ipic_info[src].mask, temp); 535 536 raw_spin_unlock_irqrestore(&ipic_lock, flags); 537} 538 539static void ipic_mask_irq(struct irq_data *d) 540{ 541 struct ipic *ipic = ipic_from_irq(d->irq); 542 unsigned int src = irqd_to_hwirq(d); 543 unsigned long flags; 544 u32 temp; 545 546 raw_spin_lock_irqsave(&ipic_lock, flags); 547 548 temp = ipic_read(ipic->regs, ipic_info[src].mask); 549 temp &= ~(1 << (31 - ipic_info[src].bit)); 550 ipic_write(ipic->regs, ipic_info[src].mask, temp); 551 552 /* mb() can't guarantee that masking is finished. But it does finish 553 * for nearly all cases. */ 554 mb(); 555 556 raw_spin_unlock_irqrestore(&ipic_lock, flags); 557} 558 559static void ipic_ack_irq(struct irq_data *d) 560{ 561 struct ipic *ipic = ipic_from_irq(d->irq); 562 unsigned int src = irqd_to_hwirq(d); 563 unsigned long flags; 564 u32 temp; 565 566 raw_spin_lock_irqsave(&ipic_lock, flags); 567 568 temp = 1 << (31 - ipic_info[src].bit); 569 ipic_write(ipic->regs, ipic_info[src].ack, temp); 570 571 /* mb() can't guarantee that ack is finished. But it does finish 572 * for nearly all cases. */ 573 mb(); 574 575 raw_spin_unlock_irqrestore(&ipic_lock, flags); 576} 577 578static void ipic_mask_irq_and_ack(struct irq_data *d) 579{ 580 struct ipic *ipic = ipic_from_irq(d->irq); 581 unsigned int src = irqd_to_hwirq(d); 582 unsigned long flags; 583 u32 temp; 584 585 raw_spin_lock_irqsave(&ipic_lock, flags); 586 587 temp = ipic_read(ipic->regs, ipic_info[src].mask); 588 temp &= ~(1 << (31 - ipic_info[src].bit)); 589 ipic_write(ipic->regs, ipic_info[src].mask, temp); 590 591 temp = 1 << (31 - ipic_info[src].bit); 592 ipic_write(ipic->regs, ipic_info[src].ack, temp); 593 594 /* mb() can't guarantee that ack is finished. But it does finish 595 * for nearly all cases. */ 596 mb(); 597 598 raw_spin_unlock_irqrestore(&ipic_lock, flags); 599} 600 601static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type) 602{ 603 struct ipic *ipic = ipic_from_irq(d->irq); 604 unsigned int src = irqd_to_hwirq(d); 605 unsigned int vold, vnew, edibit; 606 607 if (flow_type == IRQ_TYPE_NONE) 608 flow_type = IRQ_TYPE_LEVEL_LOW; 609 610 /* ipic supports only low assertion and high-to-low change senses 611 */ 612 if (!(flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))) { 613 printk(KERN_ERR "ipic: sense type 0x%x not supported\n", 614 flow_type); 615 return -EINVAL; 616 } 617 /* ipic supports only edge mode on external interrupts */ 618 if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !ipic_info[src].ack) { 619 printk(KERN_ERR "ipic: edge sense not supported on internal " 620 "interrupts\n"); 621 return -EINVAL; 622 623 } 624 625 irqd_set_trigger_type(d, flow_type); 626 if (flow_type & IRQ_TYPE_LEVEL_LOW) { 627 irq_set_handler_locked(d, handle_level_irq); 628 d->chip = &ipic_level_irq_chip; 629 } else { 630 irq_set_handler_locked(d, handle_edge_irq); 631 d->chip = &ipic_edge_irq_chip; 632 } 633 634 /* only EXT IRQ senses are programmable on ipic 635 * internal IRQ senses are LEVEL_LOW 636 */ 637 if (src == IPIC_IRQ_EXT0) 638 edibit = 15; 639 else 640 if (src >= IPIC_IRQ_EXT1 && src <= IPIC_IRQ_EXT7) 641 edibit = (14 - (src - IPIC_IRQ_EXT1)); 642 else 643 return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL; 644 645 vold = ipic_read(ipic->regs, IPIC_SECNR); 646 if ((flow_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_FALLING) { 647 vnew = vold | (1 << edibit); 648 } else { 649 vnew = vold & ~(1 << edibit); 650 } 651 if (vold != vnew) 652 ipic_write(ipic->regs, IPIC_SECNR, vnew); 653 return IRQ_SET_MASK_OK_NOCOPY; 654} 655 656/* level interrupts and edge interrupts have different ack operations */ 657static struct irq_chip ipic_level_irq_chip = { 658 .name = "IPIC", 659 .irq_unmask = ipic_unmask_irq, 660 .irq_mask = ipic_mask_irq, 661 .irq_mask_ack = ipic_mask_irq, 662 .irq_set_type = ipic_set_irq_type, 663}; 664 665static struct irq_chip ipic_edge_irq_chip = { 666 .name = "IPIC", 667 .irq_unmask = ipic_unmask_irq, 668 .irq_mask = ipic_mask_irq, 669 .irq_mask_ack = ipic_mask_irq_and_ack, 670 .irq_ack = ipic_ack_irq, 671 .irq_set_type = ipic_set_irq_type, 672}; 673 674static int ipic_host_match(struct irq_domain *h, struct device_node *node, 675 enum irq_domain_bus_token bus_token) 676{ 677 /* Exact match, unless ipic node is NULL */ 678 struct device_node *of_node = irq_domain_get_of_node(h); 679 return of_node == NULL || of_node == node; 680} 681 682static int ipic_host_map(struct irq_domain *h, unsigned int virq, 683 irq_hw_number_t hw) 684{ 685 struct ipic *ipic = h->host_data; 686 687 irq_set_chip_data(virq, ipic); 688 irq_set_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq); 689 690 /* Set default irq type */ 691 irq_set_irq_type(virq, IRQ_TYPE_NONE); 692 693 return 0; 694} 695 696static const struct irq_domain_ops ipic_host_ops = { 697 .match = ipic_host_match, 698 .map = ipic_host_map, 699 .xlate = irq_domain_xlate_onetwocell, 700}; 701 702struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) 703{ 704 struct ipic *ipic; 705 struct resource res; 706 u32 temp = 0, ret; 707 708 ret = of_address_to_resource(node, 0, &res); 709 if (ret) 710 return NULL; 711 712 ipic = kzalloc(sizeof(*ipic), GFP_KERNEL); 713 if (ipic == NULL) 714 return NULL; 715 716 ipic->irqhost = irq_domain_add_linear(node, NR_IPIC_INTS, 717 &ipic_host_ops, ipic); 718 if (ipic->irqhost == NULL) { 719 kfree(ipic); 720 return NULL; 721 } 722 723 ipic->regs = ioremap(res.start, resource_size(&res)); 724 725 /* init hw */ 726 ipic_write(ipic->regs, IPIC_SICNR, 0x0); 727 728 /* default priority scheme is grouped. If spread mode is required 729 * configure SICFR accordingly */ 730 if (flags & IPIC_SPREADMODE_GRP_A) 731 temp |= SICFR_IPSA; 732 if (flags & IPIC_SPREADMODE_GRP_B) 733 temp |= SICFR_IPSB; 734 if (flags & IPIC_SPREADMODE_GRP_C) 735 temp |= SICFR_IPSC; 736 if (flags & IPIC_SPREADMODE_GRP_D) 737 temp |= SICFR_IPSD; 738 if (flags & IPIC_SPREADMODE_MIX_A) 739 temp |= SICFR_MPSA; 740 if (flags & IPIC_SPREADMODE_MIX_B) 741 temp |= SICFR_MPSB; 742 743 ipic_write(ipic->regs, IPIC_SICFR, temp); 744 745 /* handle MCP route */ 746 temp = 0; 747 if (flags & IPIC_DISABLE_MCP_OUT) 748 temp = SERCR_MCPR; 749 ipic_write(ipic->regs, IPIC_SERCR, temp); 750 751 /* handle routing of IRQ0 to MCP */ 752 temp = ipic_read(ipic->regs, IPIC_SEMSR); 753 754 if (flags & IPIC_IRQ0_MCP) 755 temp |= SEMSR_SIRQ0; 756 else 757 temp &= ~SEMSR_SIRQ0; 758 759 ipic_write(ipic->regs, IPIC_SEMSR, temp); 760 761 primary_ipic = ipic; 762 irq_set_default_host(primary_ipic->irqhost); 763 764 ipic_write(ipic->regs, IPIC_SIMSR_H, 0); 765 ipic_write(ipic->regs, IPIC_SIMSR_L, 0); 766 767 printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS, 768 primary_ipic->regs); 769 770 return ipic; 771} 772 773int ipic_set_priority(unsigned int virq, unsigned int priority) 774{ 775 struct ipic *ipic = ipic_from_irq(virq); 776 unsigned int src = virq_to_hw(virq); 777 u32 temp; 778 779 if (priority > 7) 780 return -EINVAL; 781 if (src > 127) 782 return -EINVAL; 783 if (ipic_info[src].prio == 0) 784 return -EINVAL; 785 786 temp = ipic_read(ipic->regs, ipic_info[src].prio); 787 788 if (priority < 4) { 789 temp &= ~(0x7 << (20 + (3 - priority) * 3)); 790 temp |= ipic_info[src].prio_mask << (20 + (3 - priority) * 3); 791 } else { 792 temp &= ~(0x7 << (4 + (7 - priority) * 3)); 793 temp |= ipic_info[src].prio_mask << (4 + (7 - priority) * 3); 794 } 795 796 ipic_write(ipic->regs, ipic_info[src].prio, temp); 797 798 return 0; 799} 800 801void ipic_set_highest_priority(unsigned int virq) 802{ 803 struct ipic *ipic = ipic_from_irq(virq); 804 unsigned int src = virq_to_hw(virq); 805 u32 temp; 806 807 temp = ipic_read(ipic->regs, IPIC_SICFR); 808 809 /* clear and set HPI */ 810 temp &= 0x7f000000; 811 temp |= (src & 0x7f) << 24; 812 813 ipic_write(ipic->regs, IPIC_SICFR, temp); 814} 815 816void ipic_set_default_priority(void) 817{ 818 ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_PRIORITY_DEFAULT); 819 ipic_write(primary_ipic->regs, IPIC_SIPRR_B, IPIC_PRIORITY_DEFAULT); 820 ipic_write(primary_ipic->regs, IPIC_SIPRR_C, IPIC_PRIORITY_DEFAULT); 821 ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_PRIORITY_DEFAULT); 822 ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_PRIORITY_DEFAULT); 823 ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_PRIORITY_DEFAULT); 824} 825 826void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) 827{ 828 struct ipic *ipic = primary_ipic; 829 u32 temp; 830 831 temp = ipic_read(ipic->regs, IPIC_SERMR); 832 temp |= (1 << (31 - mcp_irq)); 833 ipic_write(ipic->regs, IPIC_SERMR, temp); 834} 835 836void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq) 837{ 838 struct ipic *ipic = primary_ipic; 839 u32 temp; 840 841 temp = ipic_read(ipic->regs, IPIC_SERMR); 842 temp &= (1 << (31 - mcp_irq)); 843 ipic_write(ipic->regs, IPIC_SERMR, temp); 844} 845 846u32 ipic_get_mcp_status(void) 847{ 848 return ipic_read(primary_ipic->regs, IPIC_SERMR); 849} 850 851void ipic_clear_mcp_status(u32 mask) 852{ 853 ipic_write(primary_ipic->regs, IPIC_SERMR, mask); 854} 855 856/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ 857unsigned int ipic_get_irq(void) 858{ 859 int irq; 860 861 BUG_ON(primary_ipic == NULL); 862 863#define IPIC_SIVCR_VECTOR_MASK 0x7f 864 irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & IPIC_SIVCR_VECTOR_MASK; 865 866 if (irq == 0) /* 0 --> no irq is pending */ 867 return NO_IRQ; 868 869 return irq_linear_revmap(primary_ipic->irqhost, irq); 870} 871 872#ifdef CONFIG_SUSPEND 873static struct { 874 u32 sicfr; 875 u32 siprr[2]; 876 u32 simsr[2]; 877 u32 sicnr; 878 u32 smprr[2]; 879 u32 semsr; 880 u32 secnr; 881 u32 sermr; 882 u32 sercr; 883} ipic_saved_state; 884 885static int ipic_suspend(void) 886{ 887 struct ipic *ipic = primary_ipic; 888 889 ipic_saved_state.sicfr = ipic_read(ipic->regs, IPIC_SICFR); 890 ipic_saved_state.siprr[0] = ipic_read(ipic->regs, IPIC_SIPRR_A); 891 ipic_saved_state.siprr[1] = ipic_read(ipic->regs, IPIC_SIPRR_D); 892 ipic_saved_state.simsr[0] = ipic_read(ipic->regs, IPIC_SIMSR_H); 893 ipic_saved_state.simsr[1] = ipic_read(ipic->regs, IPIC_SIMSR_L); 894 ipic_saved_state.sicnr = ipic_read(ipic->regs, IPIC_SICNR); 895 ipic_saved_state.smprr[0] = ipic_read(ipic->regs, IPIC_SMPRR_A); 896 ipic_saved_state.smprr[1] = ipic_read(ipic->regs, IPIC_SMPRR_B); 897 ipic_saved_state.semsr = ipic_read(ipic->regs, IPIC_SEMSR); 898 ipic_saved_state.secnr = ipic_read(ipic->regs, IPIC_SECNR); 899 ipic_saved_state.sermr = ipic_read(ipic->regs, IPIC_SERMR); 900 ipic_saved_state.sercr = ipic_read(ipic->regs, IPIC_SERCR); 901 902 if (fsl_deep_sleep()) { 903 /* In deep sleep, make sure there can be no 904 * pending interrupts, as this can cause 905 * problems on 831x. 906 */ 907 ipic_write(ipic->regs, IPIC_SIMSR_H, 0); 908 ipic_write(ipic->regs, IPIC_SIMSR_L, 0); 909 ipic_write(ipic->regs, IPIC_SEMSR, 0); 910 ipic_write(ipic->regs, IPIC_SERMR, 0); 911 } 912 913 return 0; 914} 915 916static void ipic_resume(void) 917{ 918 struct ipic *ipic = primary_ipic; 919 920 ipic_write(ipic->regs, IPIC_SICFR, ipic_saved_state.sicfr); 921 ipic_write(ipic->regs, IPIC_SIPRR_A, ipic_saved_state.siprr[0]); 922 ipic_write(ipic->regs, IPIC_SIPRR_D, ipic_saved_state.siprr[1]); 923 ipic_write(ipic->regs, IPIC_SIMSR_H, ipic_saved_state.simsr[0]); 924 ipic_write(ipic->regs, IPIC_SIMSR_L, ipic_saved_state.simsr[1]); 925 ipic_write(ipic->regs, IPIC_SICNR, ipic_saved_state.sicnr); 926 ipic_write(ipic->regs, IPIC_SMPRR_A, ipic_saved_state.smprr[0]); 927 ipic_write(ipic->regs, IPIC_SMPRR_B, ipic_saved_state.smprr[1]); 928 ipic_write(ipic->regs, IPIC_SEMSR, ipic_saved_state.semsr); 929 ipic_write(ipic->regs, IPIC_SECNR, ipic_saved_state.secnr); 930 ipic_write(ipic->regs, IPIC_SERMR, ipic_saved_state.sermr); 931 ipic_write(ipic->regs, IPIC_SERCR, ipic_saved_state.sercr); 932} 933#else 934#define ipic_suspend NULL 935#define ipic_resume NULL 936#endif 937 938static struct syscore_ops ipic_syscore_ops = { 939 .suspend = ipic_suspend, 940 .resume = ipic_resume, 941}; 942 943static int __init init_ipic_syscore(void) 944{ 945 if (!primary_ipic || !primary_ipic->regs) 946 return -ENODEV; 947 948 printk(KERN_DEBUG "Registering ipic system core operations\n"); 949 register_syscore_ops(&ipic_syscore_ops); 950 951 return 0; 952} 953 954subsys_initcall(init_ipic_syscore); 955