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                .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