linux/arch/powerpc/sysdev/ipic.c
<<
>>
Prefs
   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                .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
 509static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg)
 510{
 511        return in_be32(base + (reg >> 2));
 512}
 513
 514static inline void ipic_write(volatile u32 __iomem *base, unsigned int reg, u32 value)
 515{
 516        out_be32(base + (reg >> 2), value);
 517}
 518
 519static inline struct ipic * ipic_from_irq(unsigned int virq)
 520{
 521        return primary_ipic;
 522}
 523
 524static 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
 540static 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
 560static 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
 579static 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
 602static 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 */
 658static 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
 666static 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
 675static 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
 683static 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
 697static 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
 703struct 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
 774int 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
 802void 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
 817void 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
 827void 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
 837void 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
 847u32 ipic_get_mcp_status(void)
 848{
 849        return ipic_read(primary_ipic->regs, IPIC_SERSR);
 850}
 851
 852void 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. */
 858unsigned 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
 874static 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
 886static 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
 917static 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
 939static struct syscore_ops ipic_syscore_ops = {
 940        .suspend = ipic_suspend,
 941        .resume = ipic_resume,
 942};
 943
 944static 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
 955subsys_initcall(init_ipic_syscore);
 956