1 /* 2 * include/asm-ppc/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/sysdev.h> 22 #include <linux/device.h> 23 #include <linux/bootmem.h> 24 #include <linux/spinlock.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 DEFINE_SPINLOCK(ipic_lock); 34 35 static struct ipic_info ipic_info[] = { 36 [9] = { 37 .pend = IPIC_SIPNR_H, 38 .mask = IPIC_SIMSR_H, 39 .prio = IPIC_SIPRR_D, 40 .force = IPIC_SIFCR_H, 41 .bit = 24, 42 .prio_mask = 0, 43 }, 44 [10] = { 45 .pend = IPIC_SIPNR_H, 46 .mask = IPIC_SIMSR_H, 47 .prio = IPIC_SIPRR_D, 48 .force = IPIC_SIFCR_H, 49 .bit = 25, 50 .prio_mask = 1, 51 }, 52 [11] = { 53 .pend = IPIC_SIPNR_H, 54 .mask = IPIC_SIMSR_H, 55 .prio = IPIC_SIPRR_D, 56 .force = IPIC_SIFCR_H, 57 .bit = 26, 58 .prio_mask = 2, 59 }, 60 [14] = { 61 .pend = IPIC_SIPNR_H, 62 .mask = IPIC_SIMSR_H, 63 .prio = IPIC_SIPRR_D, 64 .force = IPIC_SIFCR_H, 65 .bit = 29, 66 .prio_mask = 5, 67 }, 68 [15] = { 69 .pend = IPIC_SIPNR_H, 70 .mask = IPIC_SIMSR_H, 71 .prio = IPIC_SIPRR_D, 72 .force = IPIC_SIFCR_H, 73 .bit = 30, 74 .prio_mask = 6, 75 }, 76 [16] = { 77 .pend = IPIC_SIPNR_H, 78 .mask = IPIC_SIMSR_H, 79 .prio = IPIC_SIPRR_D, 80 .force = IPIC_SIFCR_H, 81 .bit = 31, 82 .prio_mask = 7, 83 }, 84 [17] = { 85 .pend = IPIC_SEPNR, 86 .mask = IPIC_SEMSR, 87 .prio = IPIC_SMPRR_A, 88 .force = IPIC_SEFCR, 89 .bit = 1, 90 .prio_mask = 5, 91 }, 92 [18] = { 93 .pend = IPIC_SEPNR, 94 .mask = IPIC_SEMSR, 95 .prio = IPIC_SMPRR_A, 96 .force = IPIC_SEFCR, 97 .bit = 2, 98 .prio_mask = 6, 99 }, 100 [19] = { 101 .pend = IPIC_SEPNR, 102 .mask = IPIC_SEMSR, 103 .prio = IPIC_SMPRR_A, 104 .force = IPIC_SEFCR, 105 .bit = 3, 106 .prio_mask = 7, 107 }, 108 [20] = { 109 .pend = IPIC_SEPNR, 110 .mask = IPIC_SEMSR, 111 .prio = IPIC_SMPRR_B, 112 .force = IPIC_SEFCR, 113 .bit = 4, 114 .prio_mask = 4, 115 }, 116 [21] = { 117 .pend = IPIC_SEPNR, 118 .mask = IPIC_SEMSR, 119 .prio = IPIC_SMPRR_B, 120 .force = IPIC_SEFCR, 121 .bit = 5, 122 .prio_mask = 5, 123 }, 124 [22] = { 125 .pend = IPIC_SEPNR, 126 .mask = IPIC_SEMSR, 127 .prio = IPIC_SMPRR_B, 128 .force = IPIC_SEFCR, 129 .bit = 6, 130 .prio_mask = 6, 131 }, 132 [23] = { 133 .pend = IPIC_SEPNR, 134 .mask = IPIC_SEMSR, 135 .prio = IPIC_SMPRR_B, 136 .force = IPIC_SEFCR, 137 .bit = 7, 138 .prio_mask = 7, 139 }, 140 [32] = { 141 .pend = IPIC_SIPNR_H, 142 .mask = IPIC_SIMSR_H, 143 .prio = IPIC_SIPRR_A, 144 .force = IPIC_SIFCR_H, 145 .bit = 0, 146 .prio_mask = 0, 147 }, 148 [33] = { 149 .pend = IPIC_SIPNR_H, 150 .mask = IPIC_SIMSR_H, 151 .prio = IPIC_SIPRR_A, 152 .force = IPIC_SIFCR_H, 153 .bit = 1, 154 .prio_mask = 1, 155 }, 156 [34] = { 157 .pend = IPIC_SIPNR_H, 158 .mask = IPIC_SIMSR_H, 159 .prio = IPIC_SIPRR_A, 160 .force = IPIC_SIFCR_H, 161 .bit = 2, 162 .prio_mask = 2, 163 }, 164 [35] = { 165 .pend = IPIC_SIPNR_H, 166 .mask = IPIC_SIMSR_H, 167 .prio = IPIC_SIPRR_A, 168 .force = IPIC_SIFCR_H, 169 .bit = 3, 170 .prio_mask = 3, 171 }, 172 [36] = { 173 .pend = IPIC_SIPNR_H, 174 .mask = IPIC_SIMSR_H, 175 .prio = IPIC_SIPRR_A, 176 .force = IPIC_SIFCR_H, 177 .bit = 4, 178 .prio_mask = 4, 179 }, 180 [37] = { 181 .pend = IPIC_SIPNR_H, 182 .mask = IPIC_SIMSR_H, 183 .prio = IPIC_SIPRR_A, 184 .force = IPIC_SIFCR_H, 185 .bit = 5, 186 .prio_mask = 5, 187 }, 188 [38] = { 189 .pend = IPIC_SIPNR_H, 190 .mask = IPIC_SIMSR_H, 191 .prio = IPIC_SIPRR_A, 192 .force = IPIC_SIFCR_H, 193 .bit = 6, 194 .prio_mask = 6, 195 }, 196 [39] = { 197 .pend = IPIC_SIPNR_H, 198 .mask = IPIC_SIMSR_H, 199 .prio = IPIC_SIPRR_A, 200 .force = IPIC_SIFCR_H, 201 .bit = 7, 202 .prio_mask = 7, 203 }, 204 [48] = { 205 .pend = IPIC_SEPNR, 206 .mask = IPIC_SEMSR, 207 .prio = IPIC_SMPRR_A, 208 .force = IPIC_SEFCR, 209 .bit = 0, 210 .prio_mask = 4, 211 }, 212 [64] = { 213 .pend = IPIC_SIPNR_L, 214 .mask = IPIC_SIMSR_L, 215 .prio = IPIC_SMPRR_A, 216 .force = IPIC_SIFCR_L, 217 .bit = 0, 218 .prio_mask = 0, 219 }, 220 [65] = { 221 .pend = IPIC_SIPNR_L, 222 .mask = IPIC_SIMSR_L, 223 .prio = IPIC_SMPRR_A, 224 .force = IPIC_SIFCR_L, 225 .bit = 1, 226 .prio_mask = 1, 227 }, 228 [66] = { 229 .pend = IPIC_SIPNR_L, 230 .mask = IPIC_SIMSR_L, 231 .prio = IPIC_SMPRR_A, 232 .force = IPIC_SIFCR_L, 233 .bit = 2, 234 .prio_mask = 2, 235 }, 236 [67] = { 237 .pend = IPIC_SIPNR_L, 238 .mask = IPIC_SIMSR_L, 239 .prio = IPIC_SMPRR_A, 240 .force = IPIC_SIFCR_L, 241 .bit = 3, 242 .prio_mask = 3, 243 }, 244 [68] = { 245 .pend = IPIC_SIPNR_L, 246 .mask = IPIC_SIMSR_L, 247 .prio = IPIC_SMPRR_B, 248 .force = IPIC_SIFCR_L, 249 .bit = 4, 250 .prio_mask = 0, 251 }, 252 [69] = { 253 .pend = IPIC_SIPNR_L, 254 .mask = IPIC_SIMSR_L, 255 .prio = IPIC_SMPRR_B, 256 .force = IPIC_SIFCR_L, 257 .bit = 5, 258 .prio_mask = 1, 259 }, 260 [70] = { 261 .pend = IPIC_SIPNR_L, 262 .mask = IPIC_SIMSR_L, 263 .prio = IPIC_SMPRR_B, 264 .force = IPIC_SIFCR_L, 265 .bit = 6, 266 .prio_mask = 2, 267 }, 268 [71] = { 269 .pend = IPIC_SIPNR_L, 270 .mask = IPIC_SIMSR_L, 271 .prio = IPIC_SMPRR_B, 272 .force = IPIC_SIFCR_L, 273 .bit = 7, 274 .prio_mask = 3, 275 }, 276 [72] = { 277 .pend = IPIC_SIPNR_L, 278 .mask = IPIC_SIMSR_L, 279 .prio = 0, 280 .force = IPIC_SIFCR_L, 281 .bit = 8, 282 }, 283 [73] = { 284 .pend = IPIC_SIPNR_L, 285 .mask = IPIC_SIMSR_L, 286 .prio = 0, 287 .force = IPIC_SIFCR_L, 288 .bit = 9, 289 }, 290 [74] = { 291 .pend = IPIC_SIPNR_L, 292 .mask = IPIC_SIMSR_L, 293 .prio = 0, 294 .force = IPIC_SIFCR_L, 295 .bit = 10, 296 }, 297 [75] = { 298 .pend = IPIC_SIPNR_L, 299 .mask = IPIC_SIMSR_L, 300 .prio = 0, 301 .force = IPIC_SIFCR_L, 302 .bit = 11, 303 }, 304 [76] = { 305 .pend = IPIC_SIPNR_L, 306 .mask = IPIC_SIMSR_L, 307 .prio = 0, 308 .force = IPIC_SIFCR_L, 309 .bit = 12, 310 }, 311 [77] = { 312 .pend = IPIC_SIPNR_L, 313 .mask = IPIC_SIMSR_L, 314 .prio = 0, 315 .force = IPIC_SIFCR_L, 316 .bit = 13, 317 }, 318 [78] = { 319 .pend = IPIC_SIPNR_L, 320 .mask = IPIC_SIMSR_L, 321 .prio = 0, 322 .force = IPIC_SIFCR_L, 323 .bit = 14, 324 }, 325 [79] = { 326 .pend = IPIC_SIPNR_L, 327 .mask = IPIC_SIMSR_L, 328 .prio = 0, 329 .force = IPIC_SIFCR_L, 330 .bit = 15, 331 }, 332 [80] = { 333 .pend = IPIC_SIPNR_L, 334 .mask = IPIC_SIMSR_L, 335 .prio = 0, 336 .force = IPIC_SIFCR_L, 337 .bit = 16, 338 }, 339 [84] = { 340 .pend = IPIC_SIPNR_L, 341 .mask = IPIC_SIMSR_L, 342 .prio = 0, 343 .force = IPIC_SIFCR_L, 344 .bit = 20, 345 }, 346 [85] = { 347 .pend = IPIC_SIPNR_L, 348 .mask = IPIC_SIMSR_L, 349 .prio = 0, 350 .force = IPIC_SIFCR_L, 351 .bit = 21, 352 }, 353 [90] = { 354 .pend = IPIC_SIPNR_L, 355 .mask = IPIC_SIMSR_L, 356 .prio = 0, 357 .force = IPIC_SIFCR_L, 358 .bit = 26, 359 }, 360 [91] = { 361 .pend = IPIC_SIPNR_L, 362 .mask = IPIC_SIMSR_L, 363 .prio = 0, 364 .force = IPIC_SIFCR_L, 365 .bit = 27, 366 }, 367 }; 368 369 static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg) 370 { 371 return in_be32(base + (reg >> 2)); 372 } 373 374 static inline void ipic_write(volatile u32 __iomem *base, unsigned int reg, u32 value) 375 { 376 out_be32(base + (reg >> 2), value); 377 } 378 379 static inline struct ipic * ipic_from_irq(unsigned int virq) 380 { 381 return primary_ipic; 382 } 383 384 #define ipic_irq_to_hw(virq) ((unsigned int)irq_map[virq].hwirq) 385 386 static void ipic_unmask_irq(unsigned int virq) 387 { 388 struct ipic *ipic = ipic_from_irq(virq); 389 unsigned int src = ipic_irq_to_hw(virq); 390 unsigned long flags; 391 u32 temp; 392 393 spin_lock_irqsave(&ipic_lock, flags); 394 395 temp = ipic_read(ipic->regs, ipic_info[src].mask); 396 temp |= (1 << (31 - ipic_info[src].bit)); 397 ipic_write(ipic->regs, ipic_info[src].mask, temp); 398 399 spin_unlock_irqrestore(&ipic_lock, flags); 400 } 401 402 static void ipic_mask_irq(unsigned int virq) 403 { 404 struct ipic *ipic = ipic_from_irq(virq); 405 unsigned int src = ipic_irq_to_hw(virq); 406 unsigned long flags; 407 u32 temp; 408 409 spin_lock_irqsave(&ipic_lock, flags); 410 411 temp = ipic_read(ipic->regs, ipic_info[src].mask); 412 temp &= ~(1 << (31 - ipic_info[src].bit)); 413 ipic_write(ipic->regs, ipic_info[src].mask, temp); 414 415 spin_unlock_irqrestore(&ipic_lock, flags); 416 } 417 418 static void ipic_ack_irq(unsigned int virq) 419 { 420 struct ipic *ipic = ipic_from_irq(virq); 421 unsigned int src = ipic_irq_to_hw(virq); 422 unsigned long flags; 423 u32 temp; 424 425 spin_lock_irqsave(&ipic_lock, flags); 426 427 temp = ipic_read(ipic->regs, ipic_info[src].pend); 428 temp |= (1 << (31 - ipic_info[src].bit)); 429 ipic_write(ipic->regs, ipic_info[src].pend, temp); 430 431 spin_unlock_irqrestore(&ipic_lock, flags); 432 } 433 434 static void ipic_mask_irq_and_ack(unsigned int virq) 435 { 436 struct ipic *ipic = ipic_from_irq(virq); 437 unsigned int src = ipic_irq_to_hw(virq); 438 unsigned long flags; 439 u32 temp; 440 441 spin_lock_irqsave(&ipic_lock, flags); 442 443 temp = ipic_read(ipic->regs, ipic_info[src].mask); 444 temp &= ~(1 << (31 - ipic_info[src].bit)); 445 ipic_write(ipic->regs, ipic_info[src].mask, temp); 446 447 temp = ipic_read(ipic->regs, ipic_info[src].pend); 448 temp |= (1 << (31 - ipic_info[src].bit)); 449 ipic_write(ipic->regs, ipic_info[src].pend, temp); 450 451 spin_unlock_irqrestore(&ipic_lock, flags); 452 } 453 454 static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type) 455 { 456 struct ipic *ipic = ipic_from_irq(virq); 457 unsigned int src = ipic_irq_to_hw(virq); 458 struct irq_desc *desc = get_irq_desc(virq); 459 unsigned int vold, vnew, edibit; 460 461 if (flow_type == IRQ_TYPE_NONE) 462 flow_type = IRQ_TYPE_LEVEL_LOW; 463 464 /* ipic supports only low assertion and high-to-low change senses 465 */ 466 if (!(flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))) { 467 printk(KERN_ERR "ipic: sense type 0x%x not supported\n", 468 flow_type); 469 return -EINVAL; 470 } 471 472 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); 473 desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; 474 if (flow_type & IRQ_TYPE_LEVEL_LOW) { 475 desc->status |= IRQ_LEVEL; 476 set_irq_handler(virq, handle_level_irq); 477 } else { 478 set_irq_handler(virq, handle_edge_irq); 479 } 480 481 /* only EXT IRQ senses are programmable on ipic 482 * internal IRQ senses are LEVEL_LOW 483 */ 484 if (src == IPIC_IRQ_EXT0) 485 edibit = 15; 486 else 487 if (src >= IPIC_IRQ_EXT1 && src <= IPIC_IRQ_EXT7) 488 edibit = (14 - (src - IPIC_IRQ_EXT1)); 489 else 490 return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL; 491 492 vold = ipic_read(ipic->regs, IPIC_SECNR); 493 if ((flow_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_FALLING) { 494 vnew = vold | (1 << edibit); 495 } else { 496 vnew = vold & ~(1 << edibit); 497 } 498 if (vold != vnew) 499 ipic_write(ipic->regs, IPIC_SECNR, vnew); 500 return 0; 501 } 502 503 static struct irq_chip ipic_irq_chip = { 504 .typename = " IPIC ", 505 .unmask = ipic_unmask_irq, 506 .mask = ipic_mask_irq, 507 .mask_ack = ipic_mask_irq_and_ack, 508 .ack = ipic_ack_irq, 509 .set_type = ipic_set_irq_type, 510 }; 511 512 static int ipic_host_match(struct irq_host *h, struct device_node *node) 513 { 514 struct ipic *ipic = h->host_data; 515 516 /* Exact match, unless ipic node is NULL */ 517 return ipic->of_node == NULL || ipic->of_node == node; 518 } 519 520 static int ipic_host_map(struct irq_host *h, unsigned int virq, 521 irq_hw_number_t hw) 522 { 523 struct ipic *ipic = h->host_data; 524 struct irq_chip *chip; 525 526 /* Default chip */ 527 chip = &ipic->hc_irq; 528 529 set_irq_chip_data(virq, ipic); 530 set_irq_chip_and_handler(virq, chip, handle_level_irq); 531 532 /* Set default irq type */ 533 set_irq_type(virq, IRQ_TYPE_NONE); 534 535 return 0; 536 } 537 538 static int ipic_host_xlate(struct irq_host *h, struct device_node *ct, 539 u32 *intspec, unsigned int intsize, 540 irq_hw_number_t *out_hwirq, unsigned int *out_flags) 541 542 { 543 /* interrupt sense values coming from the device tree equal either 544 * LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change) 545 */ 546 *out_hwirq = intspec[0]; 547 if (intsize > 1) 548 *out_flags = intspec[1]; 549 else 550 *out_flags = IRQ_TYPE_NONE; 551 return 0; 552 } 553 554 static struct irq_host_ops ipic_host_ops = { 555 .match = ipic_host_match, 556 .map = ipic_host_map, 557 .xlate = ipic_host_xlate, 558 }; 559 560 void __init ipic_init(struct device_node *node, 561 unsigned int flags) 562 { 563 struct ipic *ipic; 564 struct resource res; 565 u32 temp = 0, ret; 566 567 ipic = alloc_bootmem(sizeof(struct ipic)); 568 if (ipic == NULL) 569 return; 570 571 memset(ipic, 0, sizeof(struct ipic)); 572 ipic->of_node = node ? of_node_get(node) : NULL; 573 574 ipic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 575 NR_IPIC_INTS, 576 &ipic_host_ops, 0); 577 if (ipic->irqhost == NULL) { 578 of_node_put(node); 579 return; 580 } 581 582 ret = of_address_to_resource(node, 0, &res); 583 if (ret) 584 return; 585 586 ipic->regs = ioremap(res.start, res.end - res.start + 1); 587 588 ipic->irqhost->host_data = ipic; 589 ipic->hc_irq = ipic_irq_chip; 590 591 /* init hw */ 592 ipic_write(ipic->regs, IPIC_SICNR, 0x0); 593 594 /* default priority scheme is grouped. If spread mode is required 595 * configure SICFR accordingly */ 596 if (flags & IPIC_SPREADMODE_GRP_A) 597 temp |= SICFR_IPSA; 598 if (flags & IPIC_SPREADMODE_GRP_D) 599 temp |= SICFR_IPSD; 600 if (flags & IPIC_SPREADMODE_MIX_A) 601 temp |= SICFR_MPSA; 602 if (flags & IPIC_SPREADMODE_MIX_B) 603 temp |= SICFR_MPSB; 604 605 ipic_write(ipic->regs, IPIC_SICNR, temp); 606 607 /* handle MCP route */ 608 temp = 0; 609 if (flags & IPIC_DISABLE_MCP_OUT) 610 temp = SERCR_MCPR; 611 ipic_write(ipic->regs, IPIC_SERCR, temp); 612 613 /* handle routing of IRQ0 to MCP */ 614 temp = ipic_read(ipic->regs, IPIC_SEMSR); 615 616 if (flags & IPIC_IRQ0_MCP) 617 temp |= SEMSR_SIRQ0; 618 else 619 temp &= ~SEMSR_SIRQ0; 620 621 ipic_write(ipic->regs, IPIC_SEMSR, temp); 622 623 primary_ipic = ipic; 624 irq_set_default_host(primary_ipic->irqhost); 625 626 printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS, 627 primary_ipic->regs); 628 } 629 630 int ipic_set_priority(unsigned int virq, unsigned int priority) 631 { 632 struct ipic *ipic = ipic_from_irq(virq); 633 unsigned int src = ipic_irq_to_hw(virq); 634 u32 temp; 635 636 if (priority > 7) 637 return -EINVAL; 638 if (src > 127) 639 return -EINVAL; 640 if (ipic_info[src].prio == 0) 641 return -EINVAL; 642 643 temp = ipic_read(ipic->regs, ipic_info[src].prio); 644 645 if (priority < 4) { 646 temp &= ~(0x7 << (20 + (3 - priority) * 3)); 647 temp |= ipic_info[src].prio_mask << (20 + (3 - priority) * 3); 648 } else { 649 temp &= ~(0x7 << (4 + (7 - priority) * 3)); 650 temp |= ipic_info[src].prio_mask << (4 + (7 - priority) * 3); 651 } 652 653 ipic_write(ipic->regs, ipic_info[src].prio, temp); 654 655 return 0; 656 } 657 658 void ipic_set_highest_priority(unsigned int virq) 659 { 660 struct ipic *ipic = ipic_from_irq(virq); 661 unsigned int src = ipic_irq_to_hw(virq); 662 u32 temp; 663 664 temp = ipic_read(ipic->regs, IPIC_SICFR); 665 666 /* clear and set HPI */ 667 temp &= 0x7f000000; 668 temp |= (src & 0x7f) << 24; 669 670 ipic_write(ipic->regs, IPIC_SICFR, temp); 671 } 672 673 void ipic_set_default_priority(void) 674 { 675 ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_SIPRR_A_DEFAULT); 676 ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_SIPRR_D_DEFAULT); 677 ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_SMPRR_A_DEFAULT); 678 ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_SMPRR_B_DEFAULT); 679 } 680 681 void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) 682 { 683 struct ipic *ipic = primary_ipic; 684 u32 temp; 685 686 temp = ipic_read(ipic->regs, IPIC_SERMR); 687 temp |= (1 << (31 - mcp_irq)); 688 ipic_write(ipic->regs, IPIC_SERMR, temp); 689 } 690 691 void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq) 692 { 693 struct ipic *ipic = primary_ipic; 694 u32 temp; 695 696 temp = ipic_read(ipic->regs, IPIC_SERMR); 697 temp &= (1 << (31 - mcp_irq)); 698 ipic_write(ipic->regs, IPIC_SERMR, temp); 699 } 700 701 u32 ipic_get_mcp_status(void) 702 { 703 return ipic_read(primary_ipic->regs, IPIC_SERMR); 704 } 705 706 void ipic_clear_mcp_status(u32 mask) 707 { 708 ipic_write(primary_ipic->regs, IPIC_SERMR, mask); 709 } 710 711 /* Return an interrupt vector or NO_IRQ if no interrupt is pending. */ 712 unsigned int ipic_get_irq(struct pt_regs *regs) 713 { 714 int irq; 715 716 BUG_ON(primary_ipic == NULL); 717 718 #define IPIC_SIVCR_VECTOR_MASK 0x7f 719 irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & IPIC_SIVCR_VECTOR_MASK; 720 721 if (irq == 0) /* 0 --> no irq is pending */ 722 return NO_IRQ; 723 724 return irq_linear_revmap(primary_ipic->irqhost, irq); 725 } 726 727 static struct sysdev_class ipic_sysclass = { 728 set_kset_name("ipic"), 729 }; 730 731 static struct sys_device device_ipic = { 732 .id = 0, 733 .cls = &ipic_sysclass, 734 }; 735 736 static int __init init_ipic_sysfs(void) 737 { 738 int rc; 739 740 if (!primary_ipic->regs) 741 return -ENODEV; 742 printk(KERN_DEBUG "Registering ipic with sysfs...\n"); 743 744 rc = sysdev_class_register(&ipic_sysclass); 745 if (rc) { 746 printk(KERN_ERR "Failed registering ipic sys class\n"); 747 return -ENODEV; 748 } 749 rc = sysdev_register(&device_ipic); 750 if (rc) { 751 printk(KERN_ERR "Failed registering ipic sys device\n"); 752 return -ENODEV; 753 } 754 return 0; 755 } 756 757 subsys_initcall(init_ipic_sysfs); 758