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/sysdev.h>
  22#include <linux/device.h>
  23#include <linux/bootmem.h>
  24#include <linux/spinlock.h>
  25#include <linux/fsl_devices.h>
  26#include <asm/irq.h>
  27#include <asm/io.h>
  28#include <asm/prom.h>
  29#include <asm/ipic.h>
  30
  31#include "ipic.h"
  32
  33static struct ipic * primary_ipic;
  34static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip;
  35static DEFINE_RAW_SPINLOCK(ipic_lock);
  36
  37static struct ipic_info ipic_info[] = {
  38        [1] = {
  39                .mask   = IPIC_SIMSR_H,
  40                .prio   = IPIC_SIPRR_C,
  41                .force  = IPIC_SIFCR_H,
  42                .bit    = 16,
  43                .prio_mask = 0,
  44        },
  45        [2] = {
  46                .mask   = IPIC_SIMSR_H,
  47                .prio   = IPIC_SIPRR_C,
  48                .force  = IPIC_SIFCR_H,
  49                .bit    = 17,
  50                .prio_mask = 1,
  51        },
  52        [3] = {
  53                .mask   = IPIC_SIMSR_H,
  54                .prio   = IPIC_SIPRR_C,
  55                .force  = IPIC_SIFCR_H,
  56                .bit    = 18,
  57                .prio_mask = 2,
  58        },
  59        [4] = {
  60                .mask   = IPIC_SIMSR_H,
  61                .prio   = IPIC_SIPRR_C,
  62                .force  = IPIC_SIFCR_H,
  63                .bit    = 19,
  64                .prio_mask = 3,
  65        },
  66        [5] = {
  67                .mask   = IPIC_SIMSR_H,
  68                .prio   = IPIC_SIPRR_C,
  69                .force  = IPIC_SIFCR_H,
  70                .bit    = 20,
  71                .prio_mask = 4,
  72        },
  73        [6] = {
  74                .mask   = IPIC_SIMSR_H,
  75                .prio   = IPIC_SIPRR_C,
  76                .force  = IPIC_SIFCR_H,
  77                .bit    = 21,
  78                .prio_mask = 5,
  79        },
  80        [7] = {
  81                .mask   = IPIC_SIMSR_H,
  82                .prio   = IPIC_SIPRR_C,
  83                .force  = IPIC_SIFCR_H,
  84                .bit    = 22,
  85                .prio_mask = 6,
  86        },
  87        [8] = {
  88                .mask   = IPIC_SIMSR_H,
  89                .prio   = IPIC_SIPRR_C,
  90                .force  = IPIC_SIFCR_H,
  91                .bit    = 23,
  92                .prio_mask = 7,
  93        },
  94        [9] = {
  95                .mask   = IPIC_SIMSR_H,
  96                .prio   = IPIC_SIPRR_D,
  97                .force  = IPIC_SIFCR_H,
  98                .bit    = 24,
  99                .prio_mask = 0,
 100        },
 101        [10] = {
 102                .mask   = IPIC_SIMSR_H,
 103                .prio   = IPIC_SIPRR_D,
 104                .force  = IPIC_SIFCR_H,
 105                .bit    = 25,
 106                .prio_mask = 1,
 107        },
 108        [11] = {
 109                .mask   = IPIC_SIMSR_H,
 110                .prio   = IPIC_SIPRR_D,
 111                .force  = IPIC_SIFCR_H,
 112                .bit    = 26,
 113                .prio_mask = 2,
 114        },
 115        [12] = {
 116                .mask   = IPIC_SIMSR_H,
 117                .prio   = IPIC_SIPRR_D,
 118                .force  = IPIC_SIFCR_H,
 119                .bit    = 27,
 120                .prio_mask = 3,
 121        },
 122        [13] = {
 123                .mask   = IPIC_SIMSR_H,
 124                .prio   = IPIC_SIPRR_D,
 125                .force  = IPIC_SIFCR_H,
 126                .bit    = 28,
 127                .prio_mask = 4,
 128        },
 129        [14] = {
 130                .mask   = IPIC_SIMSR_H,
 131                .prio   = IPIC_SIPRR_D,
 132                .force  = IPIC_SIFCR_H,
 133                .bit    = 29,
 134                .prio_mask = 5,
 135        },
 136        [15] = {
 137                .mask   = IPIC_SIMSR_H,
 138                .prio   = IPIC_SIPRR_D,
 139                .force  = IPIC_SIFCR_H,
 140                .bit    = 30,
 141                .prio_mask = 6,
 142        },
 143        [16] = {
 144                .mask   = IPIC_SIMSR_H,
 145                .prio   = IPIC_SIPRR_D,
 146                .force  = IPIC_SIFCR_H,
 147                .bit    = 31,
 148                .prio_mask = 7,
 149        },
 150        [17] = {
 151                .ack    = IPIC_SEPNR,
 152                .mask   = IPIC_SEMSR,
 153                .prio   = IPIC_SMPRR_A,
 154                .force  = IPIC_SEFCR,
 155                .bit    = 1,
 156                .prio_mask = 5,
 157        },
 158        [18] = {
 159                .ack    = IPIC_SEPNR,
 160                .mask   = IPIC_SEMSR,
 161                .prio   = IPIC_SMPRR_A,
 162                .force  = IPIC_SEFCR,
 163                .bit    = 2,
 164                .prio_mask = 6,
 165        },
 166        [19] = {
 167                .ack    = IPIC_SEPNR,
 168                .mask   = IPIC_SEMSR,
 169                .prio   = IPIC_SMPRR_A,
 170                .force  = IPIC_SEFCR,
 171                .bit    = 3,
 172                .prio_mask = 7,
 173        },
 174        [20] = {
 175                .ack    = IPIC_SEPNR,
 176                .mask   = IPIC_SEMSR,
 177                .prio   = IPIC_SMPRR_B,
 178                .force  = IPIC_SEFCR,
 179                .bit    = 4,
 180                .prio_mask = 4,
 181        },
 182        [21] = {
 183                .ack    = IPIC_SEPNR,
 184                .mask   = IPIC_SEMSR,
 185                .prio   = IPIC_SMPRR_B,
 186                .force  = IPIC_SEFCR,
 187                .bit    = 5,
 188                .prio_mask = 5,
 189        },
 190        [22] = {
 191                .ack    = IPIC_SEPNR,
 192                .mask   = IPIC_SEMSR,
 193                .prio   = IPIC_SMPRR_B,
 194                .force  = IPIC_SEFCR,
 195                .bit    = 6,
 196                .prio_mask = 6,
 197        },
 198        [23] = {
 199                .ack    = IPIC_SEPNR,
 200                .mask   = IPIC_SEMSR,
 201                .prio   = IPIC_SMPRR_B,
 202                .force  = IPIC_SEFCR,
 203                .bit    = 7,
 204                .prio_mask = 7,
 205        },
 206        [32] = {
 207                .mask   = IPIC_SIMSR_H,
 208                .prio   = IPIC_SIPRR_A,
 209                .force  = IPIC_SIFCR_H,
 210                .bit    = 0,
 211                .prio_mask = 0,
 212        },
 213        [33] = {
 214                .mask   = IPIC_SIMSR_H,
 215                .prio   = IPIC_SIPRR_A,
 216                .force  = IPIC_SIFCR_H,
 217                .bit    = 1,
 218                .prio_mask = 1,
 219        },
 220        [34] = {
 221                .mask   = IPIC_SIMSR_H,
 222                .prio   = IPIC_SIPRR_A,
 223                .force  = IPIC_SIFCR_H,
 224                .bit    = 2,
 225                .prio_mask = 2,
 226        },
 227        [35] = {
 228                .mask   = IPIC_SIMSR_H,
 229                .prio   = IPIC_SIPRR_A,
 230                .force  = IPIC_SIFCR_H,
 231                .bit    = 3,
 232                .prio_mask = 3,
 233        },
 234        [36] = {
 235                .mask   = IPIC_SIMSR_H,
 236                .prio   = IPIC_SIPRR_A,
 237                .force  = IPIC_SIFCR_H,
 238                .bit    = 4,
 239                .prio_mask = 4,
 240        },
 241        [37] = {
 242                .mask   = IPIC_SIMSR_H,
 243                .prio   = IPIC_SIPRR_A,
 244                .force  = IPIC_SIFCR_H,
 245                .bit    = 5,
 246                .prio_mask = 5,
 247        },
 248        [38] = {
 249                .mask   = IPIC_SIMSR_H,
 250                .prio   = IPIC_SIPRR_A,
 251                .force  = IPIC_SIFCR_H,
 252                .bit    = 6,
 253                .prio_mask = 6,
 254        },
 255        [39] = {
 256                .mask   = IPIC_SIMSR_H,
 257                .prio   = IPIC_SIPRR_A,
 258                .force  = IPIC_SIFCR_H,
 259                .bit    = 7,
 260                .prio_mask = 7,
 261        },
 262        [40] = {
 263                .mask   = IPIC_SIMSR_H,
 264                .prio   = IPIC_SIPRR_B,
 265                .force  = IPIC_SIFCR_H,
 266                .bit    = 8,
 267                .prio_mask = 0,
 268        },
 269        [41] = {
 270                .mask   = IPIC_SIMSR_H,
 271                .prio   = IPIC_SIPRR_B,
 272                .force  = IPIC_SIFCR_H,
 273                .bit    = 9,
 274                .prio_mask = 1,
 275        },
 276        [42] = {
 277                .mask   = IPIC_SIMSR_H,
 278                .prio   = IPIC_SIPRR_B,
 279                .force  = IPIC_SIFCR_H,
 280                .bit    = 10,
 281                .prio_mask = 2,
 282        },
 283        [43] = {
 284                .mask   = IPIC_SIMSR_H,
 285                .prio   = IPIC_SIPRR_B,
 286                .force  = IPIC_SIFCR_H,
 287                .bit    = 11,
 288                .prio_mask = 3,
 289        },
 290        [44] = {
 291                .mask   = IPIC_SIMSR_H,
 292                .prio   = IPIC_SIPRR_B,
 293                .force  = IPIC_SIFCR_H,
 294                .bit    = 12,
 295                .prio_mask = 4,
 296        },
 297        [45] = {
 298                .mask   = IPIC_SIMSR_H,
 299                .prio   = IPIC_SIPRR_B,
 300                .force  = IPIC_SIFCR_H,
 301                .bit    = 13,
 302                .prio_mask = 5,
 303        },
 304        [46] = {
 305                .mask   = IPIC_SIMSR_H,
 306                .prio   = IPIC_SIPRR_B,
 307                .force  = IPIC_SIFCR_H,
 308                .bit    = 14,
 309                .prio_mask = 6,
 310        },
 311        [47] = {
 312                .mask   = IPIC_SIMSR_H,
 313                .prio   = IPIC_SIPRR_B,
 314                .force  = IPIC_SIFCR_H,
 315                .bit    = 15,
 316                .prio_mask = 7,
 317        },
 318        [48] = {
 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
 524#define ipic_irq_to_hw(virq)    ((unsigned int)irq_map[virq].hwirq)
 525
 526static void ipic_unmask_irq(unsigned int virq)
 527{
 528        struct ipic *ipic = ipic_from_irq(virq);
 529        unsigned int src = ipic_irq_to_hw(virq);
 530        unsigned long flags;
 531        u32 temp;
 532
 533        raw_spin_lock_irqsave(&ipic_lock, flags);
 534
 535        temp = ipic_read(ipic->regs, ipic_info[src].mask);
 536        temp |= (1 << (31 - ipic_info[src].bit));
 537        ipic_write(ipic->regs, ipic_info[src].mask, temp);
 538
 539        raw_spin_unlock_irqrestore(&ipic_lock, flags);
 540}
 541
 542static void ipic_mask_irq(unsigned int virq)
 543{
 544        struct ipic *ipic = ipic_from_irq(virq);
 545        unsigned int src = ipic_irq_to_hw(virq);
 546        unsigned long flags;
 547        u32 temp;
 548
 549        raw_spin_lock_irqsave(&ipic_lock, flags);
 550
 551        temp = ipic_read(ipic->regs, ipic_info[src].mask);
 552        temp &= ~(1 << (31 - ipic_info[src].bit));
 553        ipic_write(ipic->regs, ipic_info[src].mask, temp);
 554
 555        /* mb() can't guarantee that masking is finished.  But it does finish
 556         * for nearly all cases. */
 557        mb();
 558
 559        raw_spin_unlock_irqrestore(&ipic_lock, flags);
 560}
 561
 562static void ipic_ack_irq(unsigned int virq)
 563{
 564        struct ipic *ipic = ipic_from_irq(virq);
 565        unsigned int src = ipic_irq_to_hw(virq);
 566        unsigned long flags;
 567        u32 temp;
 568
 569        raw_spin_lock_irqsave(&ipic_lock, flags);
 570
 571        temp = 1 << (31 - ipic_info[src].bit);
 572        ipic_write(ipic->regs, ipic_info[src].ack, temp);
 573
 574        /* mb() can't guarantee that ack is finished.  But it does finish
 575         * for nearly all cases. */
 576        mb();
 577
 578        raw_spin_unlock_irqrestore(&ipic_lock, flags);
 579}
 580
 581static void ipic_mask_irq_and_ack(unsigned int virq)
 582{
 583        struct ipic *ipic = ipic_from_irq(virq);
 584        unsigned int src = ipic_irq_to_hw(virq);
 585        unsigned long flags;
 586        u32 temp;
 587
 588        raw_spin_lock_irqsave(&ipic_lock, flags);
 589
 590        temp = ipic_read(ipic->regs, ipic_info[src].mask);
 591        temp &= ~(1 << (31 - ipic_info[src].bit));
 592        ipic_write(ipic->regs, ipic_info[src].mask, temp);
 593
 594        temp = 1 << (31 - ipic_info[src].bit);
 595        ipic_write(ipic->regs, ipic_info[src].ack, temp);
 596
 597        /* mb() can't guarantee that ack is finished.  But it does finish
 598         * for nearly all cases. */
 599        mb();
 600
 601        raw_spin_unlock_irqrestore(&ipic_lock, flags);
 602}
 603
 604static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
 605{
 606        struct ipic *ipic = ipic_from_irq(virq);
 607        unsigned int src = ipic_irq_to_hw(virq);
 608        struct irq_desc *desc = irq_to_desc(virq);
 609        unsigned int vold, vnew, edibit;
 610
 611        if (flow_type == IRQ_TYPE_NONE)
 612                flow_type = IRQ_TYPE_LEVEL_LOW;
 613
 614        /* ipic supports only low assertion and high-to-low change senses
 615         */
 616        if (!(flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))) {
 617                printk(KERN_ERR "ipic: sense type 0x%x not supported\n",
 618                        flow_type);
 619                return -EINVAL;
 620        }
 621        /* ipic supports only edge mode on external interrupts */
 622        if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !ipic_info[src].ack) {
 623                printk(KERN_ERR "ipic: edge sense not supported on internal "
 624                                "interrupts\n");
 625                return -EINVAL;
 626        }
 627
 628        desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
 629        desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
 630        if (flow_type & IRQ_TYPE_LEVEL_LOW)  {
 631                desc->status |= IRQ_LEVEL;
 632                desc->handle_irq = handle_level_irq;
 633                desc->chip = &ipic_level_irq_chip;
 634        } else {
 635                desc->handle_irq = handle_edge_irq;
 636                desc->chip = &ipic_edge_irq_chip;
 637        }
 638
 639        /* only EXT IRQ senses are programmable on ipic
 640         * internal IRQ senses are LEVEL_LOW
 641         */
 642        if (src == IPIC_IRQ_EXT0)
 643                edibit = 15;
 644        else
 645                if (src >= IPIC_IRQ_EXT1 && src <= IPIC_IRQ_EXT7)
 646                        edibit = (14 - (src - IPIC_IRQ_EXT1));
 647                else
 648                        return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL;
 649
 650        vold = ipic_read(ipic->regs, IPIC_SECNR);
 651        if ((flow_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_FALLING) {
 652                vnew = vold | (1 << edibit);
 653        } else {
 654                vnew = vold & ~(1 << edibit);
 655        }
 656        if (vold != vnew)
 657                ipic_write(ipic->regs, IPIC_SECNR, vnew);
 658        return 0;
 659}
 660
 661/* level interrupts and edge interrupts have different ack operations */
 662static struct irq_chip ipic_level_irq_chip = {
 663        .name           = "IPIC",
 664        .unmask         = ipic_unmask_irq,
 665        .mask           = ipic_mask_irq,
 666        .mask_ack       = ipic_mask_irq,
 667        .set_type       = ipic_set_irq_type,
 668};
 669
 670static struct irq_chip ipic_edge_irq_chip = {
 671        .name           = "IPIC",
 672        .unmask         = ipic_unmask_irq,
 673        .mask           = ipic_mask_irq,
 674        .mask_ack       = ipic_mask_irq_and_ack,
 675        .ack            = ipic_ack_irq,
 676        .set_type       = ipic_set_irq_type,
 677};
 678
 679static int ipic_host_match(struct irq_host *h, struct device_node *node)
 680{
 681        /* Exact match, unless ipic node is NULL */
 682        return h->of_node == NULL || h->of_node == node;
 683}
 684
 685static int ipic_host_map(struct irq_host *h, unsigned int virq,
 686                         irq_hw_number_t hw)
 687{
 688        struct ipic *ipic = h->host_data;
 689
 690        set_irq_chip_data(virq, ipic);
 691        set_irq_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq);
 692
 693        /* Set default irq type */
 694        set_irq_type(virq, IRQ_TYPE_NONE);
 695
 696        return 0;
 697}
 698
 699static int ipic_host_xlate(struct irq_host *h, struct device_node *ct,
 700                           const u32 *intspec, unsigned int intsize,
 701                           irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 702
 703{
 704        /* interrupt sense values coming from the device tree equal either
 705         * LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change)
 706         */
 707        *out_hwirq = intspec[0];
 708        if (intsize > 1)
 709                *out_flags = intspec[1];
 710        else
 711                *out_flags = IRQ_TYPE_NONE;
 712        return 0;
 713}
 714
 715static struct irq_host_ops ipic_host_ops = {
 716        .match  = ipic_host_match,
 717        .map    = ipic_host_map,
 718        .xlate  = ipic_host_xlate,
 719};
 720
 721struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
 722{
 723        struct ipic     *ipic;
 724        struct resource res;
 725        u32 temp = 0, ret;
 726
 727        ret = of_address_to_resource(node, 0, &res);
 728        if (ret)
 729                return NULL;
 730
 731        ipic = kzalloc(sizeof(*ipic), GFP_KERNEL);
 732        if (ipic == NULL)
 733                return NULL;
 734
 735        ipic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
 736                                       NR_IPIC_INTS,
 737                                       &ipic_host_ops, 0);
 738        if (ipic->irqhost == NULL) {
 739                kfree(ipic);
 740                return NULL;
 741        }
 742
 743        ipic->regs = ioremap(res.start, res.end - res.start + 1);
 744
 745        ipic->irqhost->host_data = ipic;
 746
 747        /* init hw */
 748        ipic_write(ipic->regs, IPIC_SICNR, 0x0);
 749
 750        /* default priority scheme is grouped. If spread mode is required
 751         * configure SICFR accordingly */
 752        if (flags & IPIC_SPREADMODE_GRP_A)
 753                temp |= SICFR_IPSA;
 754        if (flags & IPIC_SPREADMODE_GRP_B)
 755                temp |= SICFR_IPSB;
 756        if (flags & IPIC_SPREADMODE_GRP_C)
 757                temp |= SICFR_IPSC;
 758        if (flags & IPIC_SPREADMODE_GRP_D)
 759                temp |= SICFR_IPSD;
 760        if (flags & IPIC_SPREADMODE_MIX_A)
 761                temp |= SICFR_MPSA;
 762        if (flags & IPIC_SPREADMODE_MIX_B)
 763                temp |= SICFR_MPSB;
 764
 765        ipic_write(ipic->regs, IPIC_SICFR, temp);
 766
 767        /* handle MCP route */
 768        temp = 0;
 769        if (flags & IPIC_DISABLE_MCP_OUT)
 770                temp = SERCR_MCPR;
 771        ipic_write(ipic->regs, IPIC_SERCR, temp);
 772
 773        /* handle routing of IRQ0 to MCP */
 774        temp = ipic_read(ipic->regs, IPIC_SEMSR);
 775
 776        if (flags & IPIC_IRQ0_MCP)
 777                temp |= SEMSR_SIRQ0;
 778        else
 779                temp &= ~SEMSR_SIRQ0;
 780
 781        ipic_write(ipic->regs, IPIC_SEMSR, temp);
 782
 783        primary_ipic = ipic;
 784        irq_set_default_host(primary_ipic->irqhost);
 785
 786        ipic_write(ipic->regs, IPIC_SIMSR_H, 0);
 787        ipic_write(ipic->regs, IPIC_SIMSR_L, 0);
 788
 789        printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS,
 790                        primary_ipic->regs);
 791
 792        return ipic;
 793}
 794
 795int ipic_set_priority(unsigned int virq, unsigned int priority)
 796{
 797        struct ipic *ipic = ipic_from_irq(virq);
 798        unsigned int src = ipic_irq_to_hw(virq);
 799        u32 temp;
 800
 801        if (priority > 7)
 802                return -EINVAL;
 803        if (src > 127)
 804                return -EINVAL;
 805        if (ipic_info[src].prio == 0)
 806                return -EINVAL;
 807
 808        temp = ipic_read(ipic->regs, ipic_info[src].prio);
 809
 810        if (priority < 4) {
 811                temp &= ~(0x7 << (20 + (3 - priority) * 3));
 812                temp |= ipic_info[src].prio_mask << (20 + (3 - priority) * 3);
 813        } else {
 814                temp &= ~(0x7 << (4 + (7 - priority) * 3));
 815                temp |= ipic_info[src].prio_mask << (4 + (7 - priority) * 3);
 816        }
 817
 818        ipic_write(ipic->regs, ipic_info[src].prio, temp);
 819
 820        return 0;
 821}
 822
 823void ipic_set_highest_priority(unsigned int virq)
 824{
 825        struct ipic *ipic = ipic_from_irq(virq);
 826        unsigned int src = ipic_irq_to_hw(virq);
 827        u32 temp;
 828
 829        temp = ipic_read(ipic->regs, IPIC_SICFR);
 830
 831        /* clear and set HPI */
 832        temp &= 0x7f000000;
 833        temp |= (src & 0x7f) << 24;
 834
 835        ipic_write(ipic->regs, IPIC_SICFR, temp);
 836}
 837
 838void ipic_set_default_priority(void)
 839{
 840        ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_PRIORITY_DEFAULT);
 841        ipic_write(primary_ipic->regs, IPIC_SIPRR_B, IPIC_PRIORITY_DEFAULT);
 842        ipic_write(primary_ipic->regs, IPIC_SIPRR_C, IPIC_PRIORITY_DEFAULT);
 843        ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_PRIORITY_DEFAULT);
 844        ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_PRIORITY_DEFAULT);
 845        ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_PRIORITY_DEFAULT);
 846}
 847
 848void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq)
 849{
 850        struct ipic *ipic = primary_ipic;
 851        u32 temp;
 852
 853        temp = ipic_read(ipic->regs, IPIC_SERMR);
 854        temp |= (1 << (31 - mcp_irq));
 855        ipic_write(ipic->regs, IPIC_SERMR, temp);
 856}
 857
 858void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq)
 859{
 860        struct ipic *ipic = primary_ipic;
 861        u32 temp;
 862
 863        temp = ipic_read(ipic->regs, IPIC_SERMR);
 864        temp &= (1 << (31 - mcp_irq));
 865        ipic_write(ipic->regs, IPIC_SERMR, temp);
 866}
 867
 868u32 ipic_get_mcp_status(void)
 869{
 870        return ipic_read(primary_ipic->regs, IPIC_SERMR);
 871}
 872
 873void ipic_clear_mcp_status(u32 mask)
 874{
 875        ipic_write(primary_ipic->regs, IPIC_SERMR, mask);
 876}
 877
 878/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
 879unsigned int ipic_get_irq(void)
 880{
 881        int irq;
 882
 883        BUG_ON(primary_ipic == NULL);
 884
 885#define IPIC_SIVCR_VECTOR_MASK  0x7f
 886        irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & IPIC_SIVCR_VECTOR_MASK;
 887
 888        if (irq == 0)    /* 0 --> no irq is pending */
 889                return NO_IRQ;
 890
 891        return irq_linear_revmap(primary_ipic->irqhost, irq);
 892}
 893
 894#ifdef CONFIG_SUSPEND
 895static struct {
 896        u32 sicfr;
 897        u32 siprr[2];
 898        u32 simsr[2];
 899        u32 sicnr;
 900        u32 smprr[2];
 901        u32 semsr;
 902        u32 secnr;
 903        u32 sermr;
 904        u32 sercr;
 905} ipic_saved_state;
 906
 907static int ipic_suspend(struct sys_device *sdev, pm_message_t state)
 908{
 909        struct ipic *ipic = primary_ipic;
 910
 911        ipic_saved_state.sicfr = ipic_read(ipic->regs, IPIC_SICFR);
 912        ipic_saved_state.siprr[0] = ipic_read(ipic->regs, IPIC_SIPRR_A);
 913        ipic_saved_state.siprr[1] = ipic_read(ipic->regs, IPIC_SIPRR_D);
 914        ipic_saved_state.simsr[0] = ipic_read(ipic->regs, IPIC_SIMSR_H);
 915        ipic_saved_state.simsr[1] = ipic_read(ipic->regs, IPIC_SIMSR_L);
 916        ipic_saved_state.sicnr = ipic_read(ipic->regs, IPIC_SICNR);
 917        ipic_saved_state.smprr[0] = ipic_read(ipic->regs, IPIC_SMPRR_A);
 918        ipic_saved_state.smprr[1] = ipic_read(ipic->regs, IPIC_SMPRR_B);
 919        ipic_saved_state.semsr = ipic_read(ipic->regs, IPIC_SEMSR);
 920        ipic_saved_state.secnr = ipic_read(ipic->regs, IPIC_SECNR);
 921        ipic_saved_state.sermr = ipic_read(ipic->regs, IPIC_SERMR);
 922        ipic_saved_state.sercr = ipic_read(ipic->regs, IPIC_SERCR);
 923
 924        if (fsl_deep_sleep()) {
 925                /* In deep sleep, make sure there can be no
 926                 * pending interrupts, as this can cause
 927                 * problems on 831x.
 928                 */
 929                ipic_write(ipic->regs, IPIC_SIMSR_H, 0);
 930                ipic_write(ipic->regs, IPIC_SIMSR_L, 0);
 931                ipic_write(ipic->regs, IPIC_SEMSR, 0);
 932                ipic_write(ipic->regs, IPIC_SERMR, 0);
 933        }
 934
 935        return 0;
 936}
 937
 938static int ipic_resume(struct sys_device *sdev)
 939{
 940        struct ipic *ipic = primary_ipic;
 941
 942        ipic_write(ipic->regs, IPIC_SICFR, ipic_saved_state.sicfr);
 943        ipic_write(ipic->regs, IPIC_SIPRR_A, ipic_saved_state.siprr[0]);
 944        ipic_write(ipic->regs, IPIC_SIPRR_D, ipic_saved_state.siprr[1]);
 945        ipic_write(ipic->regs, IPIC_SIMSR_H, ipic_saved_state.simsr[0]);
 946        ipic_write(ipic->regs, IPIC_SIMSR_L, ipic_saved_state.simsr[1]);
 947        ipic_write(ipic->regs, IPIC_SICNR, ipic_saved_state.sicnr);
 948        ipic_write(ipic->regs, IPIC_SMPRR_A, ipic_saved_state.smprr[0]);
 949        ipic_write(ipic->regs, IPIC_SMPRR_B, ipic_saved_state.smprr[1]);
 950        ipic_write(ipic->regs, IPIC_SEMSR, ipic_saved_state.semsr);
 951        ipic_write(ipic->regs, IPIC_SECNR, ipic_saved_state.secnr);
 952        ipic_write(ipic->regs, IPIC_SERMR, ipic_saved_state.sermr);
 953        ipic_write(ipic->regs, IPIC_SERCR, ipic_saved_state.sercr);
 954
 955        return 0;
 956}
 957#else
 958#define ipic_suspend NULL
 959#define ipic_resume NULL
 960#endif
 961
 962static struct sysdev_class ipic_sysclass = {
 963        .name = "ipic",
 964        .suspend = ipic_suspend,
 965        .resume = ipic_resume,
 966};
 967
 968static struct sys_device device_ipic = {
 969        .id             = 0,
 970        .cls            = &ipic_sysclass,
 971};
 972
 973static int __init init_ipic_sysfs(void)
 974{
 975        int rc;
 976
 977        if (!primary_ipic || !primary_ipic->regs)
 978                return -ENODEV;
 979        printk(KERN_DEBUG "Registering ipic with sysfs...\n");
 980
 981        rc = sysdev_class_register(&ipic_sysclass);
 982        if (rc) {
 983                printk(KERN_ERR "Failed registering ipic sys class\n");
 984                return -ENODEV;
 985        }
 986        rc = sysdev_register(&device_ipic);
 987        if (rc) {
 988                printk(KERN_ERR "Failed registering ipic sys device\n");
 989                return -ENODEV;
 990        }
 991        return 0;
 992}
 993
 994subsys_initcall(init_ipic_sysfs);
 995