0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/init.h>
0011 #include <linux/errno.h>
0012 #include <linux/reboot.h>
0013 #include <linux/slab.h>
0014 #include <linux/stddef.h>
0015 #include <linux/sched.h>
0016 #include <linux/signal.h>
0017 #include <linux/syscore_ops.h>
0018 #include <linux/device.h>
0019 #include <linux/spinlock.h>
0020 #include <linux/fsl_devices.h>
0021 #include <linux/irqdomain.h>
0022 #include <linux/of_address.h>
0023 #include <asm/irq.h>
0024 #include <asm/io.h>
0025 #include <asm/ipic.h>
0026
0027 #include "ipic.h"
0028
0029 static struct ipic * primary_ipic;
0030 static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip;
0031 static DEFINE_RAW_SPINLOCK(ipic_lock);
0032
0033 static struct ipic_info ipic_info[] = {
0034 [1] = {
0035 .mask = IPIC_SIMSR_H,
0036 .prio = IPIC_SIPRR_C,
0037 .force = IPIC_SIFCR_H,
0038 .bit = 16,
0039 .prio_mask = 0,
0040 },
0041 [2] = {
0042 .mask = IPIC_SIMSR_H,
0043 .prio = IPIC_SIPRR_C,
0044 .force = IPIC_SIFCR_H,
0045 .bit = 17,
0046 .prio_mask = 1,
0047 },
0048 [3] = {
0049 .mask = IPIC_SIMSR_H,
0050 .prio = IPIC_SIPRR_C,
0051 .force = IPIC_SIFCR_H,
0052 .bit = 18,
0053 .prio_mask = 2,
0054 },
0055 [4] = {
0056 .mask = IPIC_SIMSR_H,
0057 .prio = IPIC_SIPRR_C,
0058 .force = IPIC_SIFCR_H,
0059 .bit = 19,
0060 .prio_mask = 3,
0061 },
0062 [5] = {
0063 .mask = IPIC_SIMSR_H,
0064 .prio = IPIC_SIPRR_C,
0065 .force = IPIC_SIFCR_H,
0066 .bit = 20,
0067 .prio_mask = 4,
0068 },
0069 [6] = {
0070 .mask = IPIC_SIMSR_H,
0071 .prio = IPIC_SIPRR_C,
0072 .force = IPIC_SIFCR_H,
0073 .bit = 21,
0074 .prio_mask = 5,
0075 },
0076 [7] = {
0077 .mask = IPIC_SIMSR_H,
0078 .prio = IPIC_SIPRR_C,
0079 .force = IPIC_SIFCR_H,
0080 .bit = 22,
0081 .prio_mask = 6,
0082 },
0083 [8] = {
0084 .mask = IPIC_SIMSR_H,
0085 .prio = IPIC_SIPRR_C,
0086 .force = IPIC_SIFCR_H,
0087 .bit = 23,
0088 .prio_mask = 7,
0089 },
0090 [9] = {
0091 .mask = IPIC_SIMSR_H,
0092 .prio = IPIC_SIPRR_D,
0093 .force = IPIC_SIFCR_H,
0094 .bit = 24,
0095 .prio_mask = 0,
0096 },
0097 [10] = {
0098 .mask = IPIC_SIMSR_H,
0099 .prio = IPIC_SIPRR_D,
0100 .force = IPIC_SIFCR_H,
0101 .bit = 25,
0102 .prio_mask = 1,
0103 },
0104 [11] = {
0105 .mask = IPIC_SIMSR_H,
0106 .prio = IPIC_SIPRR_D,
0107 .force = IPIC_SIFCR_H,
0108 .bit = 26,
0109 .prio_mask = 2,
0110 },
0111 [12] = {
0112 .mask = IPIC_SIMSR_H,
0113 .prio = IPIC_SIPRR_D,
0114 .force = IPIC_SIFCR_H,
0115 .bit = 27,
0116 .prio_mask = 3,
0117 },
0118 [13] = {
0119 .mask = IPIC_SIMSR_H,
0120 .prio = IPIC_SIPRR_D,
0121 .force = IPIC_SIFCR_H,
0122 .bit = 28,
0123 .prio_mask = 4,
0124 },
0125 [14] = {
0126 .mask = IPIC_SIMSR_H,
0127 .prio = IPIC_SIPRR_D,
0128 .force = IPIC_SIFCR_H,
0129 .bit = 29,
0130 .prio_mask = 5,
0131 },
0132 [15] = {
0133 .mask = IPIC_SIMSR_H,
0134 .prio = IPIC_SIPRR_D,
0135 .force = IPIC_SIFCR_H,
0136 .bit = 30,
0137 .prio_mask = 6,
0138 },
0139 [16] = {
0140 .mask = IPIC_SIMSR_H,
0141 .prio = IPIC_SIPRR_D,
0142 .force = IPIC_SIFCR_H,
0143 .bit = 31,
0144 .prio_mask = 7,
0145 },
0146 [17] = {
0147 .ack = IPIC_SEPNR,
0148 .mask = IPIC_SEMSR,
0149 .prio = IPIC_SMPRR_A,
0150 .force = IPIC_SEFCR,
0151 .bit = 1,
0152 .prio_mask = 5,
0153 },
0154 [18] = {
0155 .ack = IPIC_SEPNR,
0156 .mask = IPIC_SEMSR,
0157 .prio = IPIC_SMPRR_A,
0158 .force = IPIC_SEFCR,
0159 .bit = 2,
0160 .prio_mask = 6,
0161 },
0162 [19] = {
0163 .ack = IPIC_SEPNR,
0164 .mask = IPIC_SEMSR,
0165 .prio = IPIC_SMPRR_A,
0166 .force = IPIC_SEFCR,
0167 .bit = 3,
0168 .prio_mask = 7,
0169 },
0170 [20] = {
0171 .ack = IPIC_SEPNR,
0172 .mask = IPIC_SEMSR,
0173 .prio = IPIC_SMPRR_B,
0174 .force = IPIC_SEFCR,
0175 .bit = 4,
0176 .prio_mask = 4,
0177 },
0178 [21] = {
0179 .ack = IPIC_SEPNR,
0180 .mask = IPIC_SEMSR,
0181 .prio = IPIC_SMPRR_B,
0182 .force = IPIC_SEFCR,
0183 .bit = 5,
0184 .prio_mask = 5,
0185 },
0186 [22] = {
0187 .ack = IPIC_SEPNR,
0188 .mask = IPIC_SEMSR,
0189 .prio = IPIC_SMPRR_B,
0190 .force = IPIC_SEFCR,
0191 .bit = 6,
0192 .prio_mask = 6,
0193 },
0194 [23] = {
0195 .ack = IPIC_SEPNR,
0196 .mask = IPIC_SEMSR,
0197 .prio = IPIC_SMPRR_B,
0198 .force = IPIC_SEFCR,
0199 .bit = 7,
0200 .prio_mask = 7,
0201 },
0202 [32] = {
0203 .mask = IPIC_SIMSR_H,
0204 .prio = IPIC_SIPRR_A,
0205 .force = IPIC_SIFCR_H,
0206 .bit = 0,
0207 .prio_mask = 0,
0208 },
0209 [33] = {
0210 .mask = IPIC_SIMSR_H,
0211 .prio = IPIC_SIPRR_A,
0212 .force = IPIC_SIFCR_H,
0213 .bit = 1,
0214 .prio_mask = 1,
0215 },
0216 [34] = {
0217 .mask = IPIC_SIMSR_H,
0218 .prio = IPIC_SIPRR_A,
0219 .force = IPIC_SIFCR_H,
0220 .bit = 2,
0221 .prio_mask = 2,
0222 },
0223 [35] = {
0224 .mask = IPIC_SIMSR_H,
0225 .prio = IPIC_SIPRR_A,
0226 .force = IPIC_SIFCR_H,
0227 .bit = 3,
0228 .prio_mask = 3,
0229 },
0230 [36] = {
0231 .mask = IPIC_SIMSR_H,
0232 .prio = IPIC_SIPRR_A,
0233 .force = IPIC_SIFCR_H,
0234 .bit = 4,
0235 .prio_mask = 4,
0236 },
0237 [37] = {
0238 .mask = IPIC_SIMSR_H,
0239 .prio = IPIC_SIPRR_A,
0240 .force = IPIC_SIFCR_H,
0241 .bit = 5,
0242 .prio_mask = 5,
0243 },
0244 [38] = {
0245 .mask = IPIC_SIMSR_H,
0246 .prio = IPIC_SIPRR_A,
0247 .force = IPIC_SIFCR_H,
0248 .bit = 6,
0249 .prio_mask = 6,
0250 },
0251 [39] = {
0252 .mask = IPIC_SIMSR_H,
0253 .prio = IPIC_SIPRR_A,
0254 .force = IPIC_SIFCR_H,
0255 .bit = 7,
0256 .prio_mask = 7,
0257 },
0258 [40] = {
0259 .mask = IPIC_SIMSR_H,
0260 .prio = IPIC_SIPRR_B,
0261 .force = IPIC_SIFCR_H,
0262 .bit = 8,
0263 .prio_mask = 0,
0264 },
0265 [41] = {
0266 .mask = IPIC_SIMSR_H,
0267 .prio = IPIC_SIPRR_B,
0268 .force = IPIC_SIFCR_H,
0269 .bit = 9,
0270 .prio_mask = 1,
0271 },
0272 [42] = {
0273 .mask = IPIC_SIMSR_H,
0274 .prio = IPIC_SIPRR_B,
0275 .force = IPIC_SIFCR_H,
0276 .bit = 10,
0277 .prio_mask = 2,
0278 },
0279 [43] = {
0280 .mask = IPIC_SIMSR_H,
0281 .prio = IPIC_SIPRR_B,
0282 .force = IPIC_SIFCR_H,
0283 .bit = 11,
0284 .prio_mask = 3,
0285 },
0286 [44] = {
0287 .mask = IPIC_SIMSR_H,
0288 .prio = IPIC_SIPRR_B,
0289 .force = IPIC_SIFCR_H,
0290 .bit = 12,
0291 .prio_mask = 4,
0292 },
0293 [45] = {
0294 .mask = IPIC_SIMSR_H,
0295 .prio = IPIC_SIPRR_B,
0296 .force = IPIC_SIFCR_H,
0297 .bit = 13,
0298 .prio_mask = 5,
0299 },
0300 [46] = {
0301 .mask = IPIC_SIMSR_H,
0302 .prio = IPIC_SIPRR_B,
0303 .force = IPIC_SIFCR_H,
0304 .bit = 14,
0305 .prio_mask = 6,
0306 },
0307 [47] = {
0308 .mask = IPIC_SIMSR_H,
0309 .prio = IPIC_SIPRR_B,
0310 .force = IPIC_SIFCR_H,
0311 .bit = 15,
0312 .prio_mask = 7,
0313 },
0314 [48] = {
0315 .ack = IPIC_SEPNR,
0316 .mask = IPIC_SEMSR,
0317 .prio = IPIC_SMPRR_A,
0318 .force = IPIC_SEFCR,
0319 .bit = 0,
0320 .prio_mask = 4,
0321 },
0322 [64] = {
0323 .mask = IPIC_SIMSR_L,
0324 .prio = IPIC_SMPRR_A,
0325 .force = IPIC_SIFCR_L,
0326 .bit = 0,
0327 .prio_mask = 0,
0328 },
0329 [65] = {
0330 .mask = IPIC_SIMSR_L,
0331 .prio = IPIC_SMPRR_A,
0332 .force = IPIC_SIFCR_L,
0333 .bit = 1,
0334 .prio_mask = 1,
0335 },
0336 [66] = {
0337 .mask = IPIC_SIMSR_L,
0338 .prio = IPIC_SMPRR_A,
0339 .force = IPIC_SIFCR_L,
0340 .bit = 2,
0341 .prio_mask = 2,
0342 },
0343 [67] = {
0344 .mask = IPIC_SIMSR_L,
0345 .prio = IPIC_SMPRR_A,
0346 .force = IPIC_SIFCR_L,
0347 .bit = 3,
0348 .prio_mask = 3,
0349 },
0350 [68] = {
0351 .mask = IPIC_SIMSR_L,
0352 .prio = IPIC_SMPRR_B,
0353 .force = IPIC_SIFCR_L,
0354 .bit = 4,
0355 .prio_mask = 0,
0356 },
0357 [69] = {
0358 .mask = IPIC_SIMSR_L,
0359 .prio = IPIC_SMPRR_B,
0360 .force = IPIC_SIFCR_L,
0361 .bit = 5,
0362 .prio_mask = 1,
0363 },
0364 [70] = {
0365 .mask = IPIC_SIMSR_L,
0366 .prio = IPIC_SMPRR_B,
0367 .force = IPIC_SIFCR_L,
0368 .bit = 6,
0369 .prio_mask = 2,
0370 },
0371 [71] = {
0372 .mask = IPIC_SIMSR_L,
0373 .prio = IPIC_SMPRR_B,
0374 .force = IPIC_SIFCR_L,
0375 .bit = 7,
0376 .prio_mask = 3,
0377 },
0378 [72] = {
0379 .mask = IPIC_SIMSR_L,
0380 .prio = 0,
0381 .force = IPIC_SIFCR_L,
0382 .bit = 8,
0383 },
0384 [73] = {
0385 .mask = IPIC_SIMSR_L,
0386 .prio = 0,
0387 .force = IPIC_SIFCR_L,
0388 .bit = 9,
0389 },
0390 [74] = {
0391 .mask = IPIC_SIMSR_L,
0392 .prio = 0,
0393 .force = IPIC_SIFCR_L,
0394 .bit = 10,
0395 },
0396 [75] = {
0397 .mask = IPIC_SIMSR_L,
0398 .prio = 0,
0399 .force = IPIC_SIFCR_L,
0400 .bit = 11,
0401 },
0402 [76] = {
0403 .mask = IPIC_SIMSR_L,
0404 .prio = 0,
0405 .force = IPIC_SIFCR_L,
0406 .bit = 12,
0407 },
0408 [77] = {
0409 .mask = IPIC_SIMSR_L,
0410 .prio = 0,
0411 .force = IPIC_SIFCR_L,
0412 .bit = 13,
0413 },
0414 [78] = {
0415 .mask = IPIC_SIMSR_L,
0416 .prio = 0,
0417 .force = IPIC_SIFCR_L,
0418 .bit = 14,
0419 },
0420 [79] = {
0421 .mask = IPIC_SIMSR_L,
0422 .prio = 0,
0423 .force = IPIC_SIFCR_L,
0424 .bit = 15,
0425 },
0426 [80] = {
0427 .mask = IPIC_SIMSR_L,
0428 .prio = 0,
0429 .force = IPIC_SIFCR_L,
0430 .bit = 16,
0431 },
0432 [81] = {
0433 .mask = IPIC_SIMSR_L,
0434 .prio = 0,
0435 .force = IPIC_SIFCR_L,
0436 .bit = 17,
0437 },
0438 [82] = {
0439 .mask = IPIC_SIMSR_L,
0440 .prio = 0,
0441 .force = IPIC_SIFCR_L,
0442 .bit = 18,
0443 },
0444 [83] = {
0445 .mask = IPIC_SIMSR_L,
0446 .prio = 0,
0447 .force = IPIC_SIFCR_L,
0448 .bit = 19,
0449 },
0450 [84] = {
0451 .mask = IPIC_SIMSR_L,
0452 .prio = 0,
0453 .force = IPIC_SIFCR_L,
0454 .bit = 20,
0455 },
0456 [85] = {
0457 .mask = IPIC_SIMSR_L,
0458 .prio = 0,
0459 .force = IPIC_SIFCR_L,
0460 .bit = 21,
0461 },
0462 [86] = {
0463 .mask = IPIC_SIMSR_L,
0464 .prio = 0,
0465 .force = IPIC_SIFCR_L,
0466 .bit = 22,
0467 },
0468 [87] = {
0469 .mask = IPIC_SIMSR_L,
0470 .prio = 0,
0471 .force = IPIC_SIFCR_L,
0472 .bit = 23,
0473 },
0474 [88] = {
0475 .mask = IPIC_SIMSR_L,
0476 .prio = 0,
0477 .force = IPIC_SIFCR_L,
0478 .bit = 24,
0479 },
0480 [89] = {
0481 .mask = IPIC_SIMSR_L,
0482 .prio = 0,
0483 .force = IPIC_SIFCR_L,
0484 .bit = 25,
0485 },
0486 [90] = {
0487 .mask = IPIC_SIMSR_L,
0488 .prio = 0,
0489 .force = IPIC_SIFCR_L,
0490 .bit = 26,
0491 },
0492 [91] = {
0493 .mask = IPIC_SIMSR_L,
0494 .prio = 0,
0495 .force = IPIC_SIFCR_L,
0496 .bit = 27,
0497 },
0498 [94] = {
0499 .mask = IPIC_SIMSR_L,
0500 .prio = 0,
0501 .force = IPIC_SIFCR_L,
0502 .bit = 30,
0503 },
0504 };
0505
0506 static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg)
0507 {
0508 return in_be32(base + (reg >> 2));
0509 }
0510
0511 static inline void ipic_write(volatile u32 __iomem *base, unsigned int reg, u32 value)
0512 {
0513 out_be32(base + (reg >> 2), value);
0514 }
0515
0516 static inline struct ipic * ipic_from_irq(unsigned int virq)
0517 {
0518 return primary_ipic;
0519 }
0520
0521 static void ipic_unmask_irq(struct irq_data *d)
0522 {
0523 struct ipic *ipic = ipic_from_irq(d->irq);
0524 unsigned int src = irqd_to_hwirq(d);
0525 unsigned long flags;
0526 u32 temp;
0527
0528 raw_spin_lock_irqsave(&ipic_lock, flags);
0529
0530 temp = ipic_read(ipic->regs, ipic_info[src].mask);
0531 temp |= (1 << (31 - ipic_info[src].bit));
0532 ipic_write(ipic->regs, ipic_info[src].mask, temp);
0533
0534 raw_spin_unlock_irqrestore(&ipic_lock, flags);
0535 }
0536
0537 static void ipic_mask_irq(struct irq_data *d)
0538 {
0539 struct ipic *ipic = ipic_from_irq(d->irq);
0540 unsigned int src = irqd_to_hwirq(d);
0541 unsigned long flags;
0542 u32 temp;
0543
0544 raw_spin_lock_irqsave(&ipic_lock, flags);
0545
0546 temp = ipic_read(ipic->regs, ipic_info[src].mask);
0547 temp &= ~(1 << (31 - ipic_info[src].bit));
0548 ipic_write(ipic->regs, ipic_info[src].mask, temp);
0549
0550
0551
0552 mb();
0553
0554 raw_spin_unlock_irqrestore(&ipic_lock, flags);
0555 }
0556
0557 static void ipic_ack_irq(struct irq_data *d)
0558 {
0559 struct ipic *ipic = ipic_from_irq(d->irq);
0560 unsigned int src = irqd_to_hwirq(d);
0561 unsigned long flags;
0562 u32 temp;
0563
0564 raw_spin_lock_irqsave(&ipic_lock, flags);
0565
0566 temp = 1 << (31 - ipic_info[src].bit);
0567 ipic_write(ipic->regs, ipic_info[src].ack, temp);
0568
0569
0570
0571 mb();
0572
0573 raw_spin_unlock_irqrestore(&ipic_lock, flags);
0574 }
0575
0576 static void ipic_mask_irq_and_ack(struct irq_data *d)
0577 {
0578 struct ipic *ipic = ipic_from_irq(d->irq);
0579 unsigned int src = irqd_to_hwirq(d);
0580 unsigned long flags;
0581 u32 temp;
0582
0583 raw_spin_lock_irqsave(&ipic_lock, flags);
0584
0585 temp = ipic_read(ipic->regs, ipic_info[src].mask);
0586 temp &= ~(1 << (31 - ipic_info[src].bit));
0587 ipic_write(ipic->regs, ipic_info[src].mask, temp);
0588
0589 temp = 1 << (31 - ipic_info[src].bit);
0590 ipic_write(ipic->regs, ipic_info[src].ack, temp);
0591
0592
0593
0594 mb();
0595
0596 raw_spin_unlock_irqrestore(&ipic_lock, flags);
0597 }
0598
0599 static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type)
0600 {
0601 struct ipic *ipic = ipic_from_irq(d->irq);
0602 unsigned int src = irqd_to_hwirq(d);
0603 unsigned int vold, vnew, edibit;
0604
0605 if (flow_type == IRQ_TYPE_NONE)
0606 flow_type = IRQ_TYPE_LEVEL_LOW;
0607
0608
0609
0610 if (!(flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))) {
0611 printk(KERN_ERR "ipic: sense type 0x%x not supported\n",
0612 flow_type);
0613 return -EINVAL;
0614 }
0615
0616 if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !ipic_info[src].ack) {
0617 printk(KERN_ERR "ipic: edge sense not supported on internal "
0618 "interrupts\n");
0619 return -EINVAL;
0620
0621 }
0622
0623 irqd_set_trigger_type(d, flow_type);
0624 if (flow_type & IRQ_TYPE_LEVEL_LOW) {
0625 irq_set_handler_locked(d, handle_level_irq);
0626 d->chip = &ipic_level_irq_chip;
0627 } else {
0628 irq_set_handler_locked(d, handle_edge_irq);
0629 d->chip = &ipic_edge_irq_chip;
0630 }
0631
0632
0633
0634
0635 if (src == IPIC_IRQ_EXT0)
0636 edibit = 15;
0637 else
0638 if (src >= IPIC_IRQ_EXT1 && src <= IPIC_IRQ_EXT7)
0639 edibit = (14 - (src - IPIC_IRQ_EXT1));
0640 else
0641 return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL;
0642
0643 vold = ipic_read(ipic->regs, IPIC_SECNR);
0644 if ((flow_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_FALLING) {
0645 vnew = vold | (1 << edibit);
0646 } else {
0647 vnew = vold & ~(1 << edibit);
0648 }
0649 if (vold != vnew)
0650 ipic_write(ipic->regs, IPIC_SECNR, vnew);
0651 return IRQ_SET_MASK_OK_NOCOPY;
0652 }
0653
0654
0655 static struct irq_chip ipic_level_irq_chip = {
0656 .name = "IPIC",
0657 .irq_unmask = ipic_unmask_irq,
0658 .irq_mask = ipic_mask_irq,
0659 .irq_mask_ack = ipic_mask_irq,
0660 .irq_set_type = ipic_set_irq_type,
0661 };
0662
0663 static struct irq_chip ipic_edge_irq_chip = {
0664 .name = "IPIC",
0665 .irq_unmask = ipic_unmask_irq,
0666 .irq_mask = ipic_mask_irq,
0667 .irq_mask_ack = ipic_mask_irq_and_ack,
0668 .irq_ack = ipic_ack_irq,
0669 .irq_set_type = ipic_set_irq_type,
0670 };
0671
0672 static int ipic_host_match(struct irq_domain *h, struct device_node *node,
0673 enum irq_domain_bus_token bus_token)
0674 {
0675
0676 struct device_node *of_node = irq_domain_get_of_node(h);
0677 return of_node == NULL || of_node == node;
0678 }
0679
0680 static int ipic_host_map(struct irq_domain *h, unsigned int virq,
0681 irq_hw_number_t hw)
0682 {
0683 struct ipic *ipic = h->host_data;
0684
0685 irq_set_chip_data(virq, ipic);
0686 irq_set_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq);
0687
0688
0689 irq_set_irq_type(virq, IRQ_TYPE_NONE);
0690
0691 return 0;
0692 }
0693
0694 static const struct irq_domain_ops ipic_host_ops = {
0695 .match = ipic_host_match,
0696 .map = ipic_host_map,
0697 .xlate = irq_domain_xlate_onetwocell,
0698 };
0699
0700 struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
0701 {
0702 struct ipic *ipic;
0703 struct resource res;
0704 u32 temp = 0, ret;
0705
0706 ret = of_address_to_resource(node, 0, &res);
0707 if (ret)
0708 return NULL;
0709
0710 ipic = kzalloc(sizeof(*ipic), GFP_KERNEL);
0711 if (ipic == NULL)
0712 return NULL;
0713
0714 ipic->irqhost = irq_domain_add_linear(node, NR_IPIC_INTS,
0715 &ipic_host_ops, ipic);
0716 if (ipic->irqhost == NULL) {
0717 kfree(ipic);
0718 return NULL;
0719 }
0720
0721 ipic->regs = ioremap(res.start, resource_size(&res));
0722
0723
0724 ipic_write(ipic->regs, IPIC_SICNR, 0x0);
0725
0726
0727
0728 if (flags & IPIC_SPREADMODE_GRP_A)
0729 temp |= SICFR_IPSA;
0730 if (flags & IPIC_SPREADMODE_GRP_B)
0731 temp |= SICFR_IPSB;
0732 if (flags & IPIC_SPREADMODE_GRP_C)
0733 temp |= SICFR_IPSC;
0734 if (flags & IPIC_SPREADMODE_GRP_D)
0735 temp |= SICFR_IPSD;
0736 if (flags & IPIC_SPREADMODE_MIX_A)
0737 temp |= SICFR_MPSA;
0738 if (flags & IPIC_SPREADMODE_MIX_B)
0739 temp |= SICFR_MPSB;
0740
0741 ipic_write(ipic->regs, IPIC_SICFR, temp);
0742
0743
0744 temp = 0;
0745 if (flags & IPIC_DISABLE_MCP_OUT)
0746 temp = SERCR_MCPR;
0747 ipic_write(ipic->regs, IPIC_SERCR, temp);
0748
0749
0750 temp = ipic_read(ipic->regs, IPIC_SEMSR);
0751
0752 if (flags & IPIC_IRQ0_MCP)
0753 temp |= SEMSR_SIRQ0;
0754 else
0755 temp &= ~SEMSR_SIRQ0;
0756
0757 ipic_write(ipic->regs, IPIC_SEMSR, temp);
0758
0759 primary_ipic = ipic;
0760 irq_set_default_host(primary_ipic->irqhost);
0761
0762 ipic_write(ipic->regs, IPIC_SIMSR_H, 0);
0763 ipic_write(ipic->regs, IPIC_SIMSR_L, 0);
0764
0765 printk ("IPIC (%d IRQ sources) at %p\n", NR_IPIC_INTS,
0766 primary_ipic->regs);
0767
0768 return ipic;
0769 }
0770
0771 void __init ipic_set_default_priority(void)
0772 {
0773 ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_PRIORITY_DEFAULT);
0774 ipic_write(primary_ipic->regs, IPIC_SIPRR_B, IPIC_PRIORITY_DEFAULT);
0775 ipic_write(primary_ipic->regs, IPIC_SIPRR_C, IPIC_PRIORITY_DEFAULT);
0776 ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_PRIORITY_DEFAULT);
0777 ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_PRIORITY_DEFAULT);
0778 ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_PRIORITY_DEFAULT);
0779 }
0780
0781 u32 ipic_get_mcp_status(void)
0782 {
0783 return primary_ipic ? ipic_read(primary_ipic->regs, IPIC_SERSR) : 0;
0784 }
0785
0786 void ipic_clear_mcp_status(u32 mask)
0787 {
0788 ipic_write(primary_ipic->regs, IPIC_SERSR, mask);
0789 }
0790
0791
0792 unsigned int ipic_get_irq(void)
0793 {
0794 int irq;
0795
0796 BUG_ON(primary_ipic == NULL);
0797
0798 #define IPIC_SIVCR_VECTOR_MASK 0x7f
0799 irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & IPIC_SIVCR_VECTOR_MASK;
0800
0801 if (irq == 0)
0802 return 0;
0803
0804 return irq_linear_revmap(primary_ipic->irqhost, irq);
0805 }
0806
0807 #ifdef CONFIG_SUSPEND
0808 static struct {
0809 u32 sicfr;
0810 u32 siprr[2];
0811 u32 simsr[2];
0812 u32 sicnr;
0813 u32 smprr[2];
0814 u32 semsr;
0815 u32 secnr;
0816 u32 sermr;
0817 u32 sercr;
0818 } ipic_saved_state;
0819
0820 static int ipic_suspend(void)
0821 {
0822 struct ipic *ipic = primary_ipic;
0823
0824 ipic_saved_state.sicfr = ipic_read(ipic->regs, IPIC_SICFR);
0825 ipic_saved_state.siprr[0] = ipic_read(ipic->regs, IPIC_SIPRR_A);
0826 ipic_saved_state.siprr[1] = ipic_read(ipic->regs, IPIC_SIPRR_D);
0827 ipic_saved_state.simsr[0] = ipic_read(ipic->regs, IPIC_SIMSR_H);
0828 ipic_saved_state.simsr[1] = ipic_read(ipic->regs, IPIC_SIMSR_L);
0829 ipic_saved_state.sicnr = ipic_read(ipic->regs, IPIC_SICNR);
0830 ipic_saved_state.smprr[0] = ipic_read(ipic->regs, IPIC_SMPRR_A);
0831 ipic_saved_state.smprr[1] = ipic_read(ipic->regs, IPIC_SMPRR_B);
0832 ipic_saved_state.semsr = ipic_read(ipic->regs, IPIC_SEMSR);
0833 ipic_saved_state.secnr = ipic_read(ipic->regs, IPIC_SECNR);
0834 ipic_saved_state.sermr = ipic_read(ipic->regs, IPIC_SERMR);
0835 ipic_saved_state.sercr = ipic_read(ipic->regs, IPIC_SERCR);
0836
0837 if (fsl_deep_sleep()) {
0838
0839
0840
0841
0842 ipic_write(ipic->regs, IPIC_SIMSR_H, 0);
0843 ipic_write(ipic->regs, IPIC_SIMSR_L, 0);
0844 ipic_write(ipic->regs, IPIC_SEMSR, 0);
0845 ipic_write(ipic->regs, IPIC_SERMR, 0);
0846 }
0847
0848 return 0;
0849 }
0850
0851 static void ipic_resume(void)
0852 {
0853 struct ipic *ipic = primary_ipic;
0854
0855 ipic_write(ipic->regs, IPIC_SICFR, ipic_saved_state.sicfr);
0856 ipic_write(ipic->regs, IPIC_SIPRR_A, ipic_saved_state.siprr[0]);
0857 ipic_write(ipic->regs, IPIC_SIPRR_D, ipic_saved_state.siprr[1]);
0858 ipic_write(ipic->regs, IPIC_SIMSR_H, ipic_saved_state.simsr[0]);
0859 ipic_write(ipic->regs, IPIC_SIMSR_L, ipic_saved_state.simsr[1]);
0860 ipic_write(ipic->regs, IPIC_SICNR, ipic_saved_state.sicnr);
0861 ipic_write(ipic->regs, IPIC_SMPRR_A, ipic_saved_state.smprr[0]);
0862 ipic_write(ipic->regs, IPIC_SMPRR_B, ipic_saved_state.smprr[1]);
0863 ipic_write(ipic->regs, IPIC_SEMSR, ipic_saved_state.semsr);
0864 ipic_write(ipic->regs, IPIC_SECNR, ipic_saved_state.secnr);
0865 ipic_write(ipic->regs, IPIC_SERMR, ipic_saved_state.sermr);
0866 ipic_write(ipic->regs, IPIC_SERCR, ipic_saved_state.sercr);
0867 }
0868 #else
0869 #define ipic_suspend NULL
0870 #define ipic_resume NULL
0871 #endif
0872
0873 static struct syscore_ops ipic_syscore_ops = {
0874 .suspend = ipic_suspend,
0875 .resume = ipic_resume,
0876 };
0877
0878 static int __init init_ipic_syscore(void)
0879 {
0880 if (!primary_ipic || !primary_ipic->regs)
0881 return -ENODEV;
0882
0883 printk(KERN_DEBUG "Registering ipic system core operations\n");
0884 register_syscore_ops(&ipic_syscore_ops);
0885
0886 return 0;
0887 }
0888
0889 subsys_initcall(init_ipic_syscore);