Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * arch/powerpc/sysdev/ipic.c
0004  *
0005  * IPIC routines implementations.
0006  *
0007  * Copyright 2005 Freescale Semiconductor, Inc.
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     /* mb() can't guarantee that masking is finished.  But it does finish
0551      * for nearly all cases. */
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     /* mb() can't guarantee that ack is finished.  But it does finish
0570      * for nearly all cases. */
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     /* mb() can't guarantee that ack is finished.  But it does finish
0593      * for nearly all cases. */
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     /* ipic supports only low assertion and high-to-low change senses
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     /* ipic supports only edge mode on external interrupts */
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     /* only EXT IRQ senses are programmable on ipic
0633      * internal IRQ senses are LEVEL_LOW
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 /* level interrupts and edge interrupts have different ack operations */
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     /* Exact match, unless ipic node is NULL */
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     /* Set default irq type */
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     /* init hw */
0724     ipic_write(ipic->regs, IPIC_SICNR, 0x0);
0725 
0726     /* default priority scheme is grouped. If spread mode is required
0727      * configure SICFR accordingly */
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     /* handle MCP route */
0744     temp = 0;
0745     if (flags & IPIC_DISABLE_MCP_OUT)
0746         temp = SERCR_MCPR;
0747     ipic_write(ipic->regs, IPIC_SERCR, temp);
0748 
0749     /* handle routing of IRQ0 to MCP */
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 /* Return an interrupt vector or 0 if no interrupt is pending. */
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)    /* 0 --> no irq is pending */
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         /* In deep sleep, make sure there can be no
0839          * pending interrupts, as this can cause
0840          * problems on 831x.
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);