Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * External Interrupt Controller on Spider South Bridge
0004  *
0005  * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
0006  *
0007  * Author: Arnd Bergmann <arndb@de.ibm.com>
0008  */
0009 
0010 #include <linux/interrupt.h>
0011 #include <linux/irq.h>
0012 #include <linux/ioport.h>
0013 #include <linux/of_address.h>
0014 #include <linux/of_irq.h>
0015 #include <linux/pgtable.h>
0016 
0017 #include <asm/io.h>
0018 
0019 #include "interrupt.h"
0020 
0021 /* register layout taken from Spider spec, table 7.4-4 */
0022 enum {
0023     TIR_DEN     = 0x004, /* Detection Enable Register */
0024     TIR_MSK     = 0x084, /* Mask Level Register */
0025     TIR_EDC     = 0x0c0, /* Edge Detection Clear Register */
0026     TIR_PNDA    = 0x100, /* Pending Register A */
0027     TIR_PNDB    = 0x104, /* Pending Register B */
0028     TIR_CS      = 0x144, /* Current Status Register */
0029     TIR_LCSA    = 0x150, /* Level Current Status Register A */
0030     TIR_LCSB    = 0x154, /* Level Current Status Register B */
0031     TIR_LCSC    = 0x158, /* Level Current Status Register C */
0032     TIR_LCSD    = 0x15c, /* Level Current Status Register D */
0033     TIR_CFGA    = 0x200, /* Setting Register A0 */
0034     TIR_CFGB    = 0x204, /* Setting Register B0 */
0035             /* 0x208 ... 0x3ff Setting Register An/Bn */
0036     TIR_PPNDA   = 0x400, /* Packet Pending Register A */
0037     TIR_PPNDB   = 0x404, /* Packet Pending Register B */
0038     TIR_PIERA   = 0x408, /* Packet Output Error Register A */
0039     TIR_PIERB   = 0x40c, /* Packet Output Error Register B */
0040     TIR_PIEN    = 0x444, /* Packet Output Enable Register */
0041     TIR_PIPND   = 0x454, /* Packet Output Pending Register */
0042     TIRDID      = 0x484, /* Spider Device ID Register */
0043     REISTIM     = 0x500, /* Reissue Command Timeout Time Setting */
0044     REISTIMEN   = 0x504, /* Reissue Command Timeout Setting */
0045     REISWAITEN  = 0x508, /* Reissue Wait Control*/
0046 };
0047 
0048 #define SPIDER_CHIP_COUNT   4
0049 #define SPIDER_SRC_COUNT    64
0050 #define SPIDER_IRQ_INVALID  63
0051 
0052 struct spider_pic {
0053     struct irq_domain       *host;
0054     void __iomem        *regs;
0055     unsigned int        node_id;
0056 };
0057 static struct spider_pic spider_pics[SPIDER_CHIP_COUNT];
0058 
0059 static struct spider_pic *spider_irq_data_to_pic(struct irq_data *d)
0060 {
0061     return irq_data_get_irq_chip_data(d);
0062 }
0063 
0064 static void __iomem *spider_get_irq_config(struct spider_pic *pic,
0065                        unsigned int src)
0066 {
0067     return pic->regs + TIR_CFGA + 8 * src;
0068 }
0069 
0070 static void spider_unmask_irq(struct irq_data *d)
0071 {
0072     struct spider_pic *pic = spider_irq_data_to_pic(d);
0073     void __iomem *cfg = spider_get_irq_config(pic, irqd_to_hwirq(d));
0074 
0075     out_be32(cfg, in_be32(cfg) | 0x30000000u);
0076 }
0077 
0078 static void spider_mask_irq(struct irq_data *d)
0079 {
0080     struct spider_pic *pic = spider_irq_data_to_pic(d);
0081     void __iomem *cfg = spider_get_irq_config(pic, irqd_to_hwirq(d));
0082 
0083     out_be32(cfg, in_be32(cfg) & ~0x30000000u);
0084 }
0085 
0086 static void spider_ack_irq(struct irq_data *d)
0087 {
0088     struct spider_pic *pic = spider_irq_data_to_pic(d);
0089     unsigned int src = irqd_to_hwirq(d);
0090 
0091     /* Reset edge detection logic if necessary
0092      */
0093     if (irqd_is_level_type(d))
0094         return;
0095 
0096     /* Only interrupts 47 to 50 can be set to edge */
0097     if (src < 47 || src > 50)
0098         return;
0099 
0100     /* Perform the clear of the edge logic */
0101     out_be32(pic->regs + TIR_EDC, 0x100 | (src & 0xf));
0102 }
0103 
0104 static int spider_set_irq_type(struct irq_data *d, unsigned int type)
0105 {
0106     unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
0107     struct spider_pic *pic = spider_irq_data_to_pic(d);
0108     unsigned int hw = irqd_to_hwirq(d);
0109     void __iomem *cfg = spider_get_irq_config(pic, hw);
0110     u32 old_mask;
0111     u32 ic;
0112 
0113     /* Note that only level high is supported for most interrupts */
0114     if (sense != IRQ_TYPE_NONE && sense != IRQ_TYPE_LEVEL_HIGH &&
0115         (hw < 47 || hw > 50))
0116         return -EINVAL;
0117 
0118     /* Decode sense type */
0119     switch(sense) {
0120     case IRQ_TYPE_EDGE_RISING:
0121         ic = 0x3;
0122         break;
0123     case IRQ_TYPE_EDGE_FALLING:
0124         ic = 0x2;
0125         break;
0126     case IRQ_TYPE_LEVEL_LOW:
0127         ic = 0x0;
0128         break;
0129     case IRQ_TYPE_LEVEL_HIGH:
0130     case IRQ_TYPE_NONE:
0131         ic = 0x1;
0132         break;
0133     default:
0134         return -EINVAL;
0135     }
0136 
0137     /* Configure the source. One gross hack that was there before and
0138      * that I've kept around is the priority to the BE which I set to
0139      * be the same as the interrupt source number. I don't know whether
0140      * that's supposed to make any kind of sense however, we'll have to
0141      * decide that, but for now, I'm not changing the behaviour.
0142      */
0143     old_mask = in_be32(cfg) & 0x30000000u;
0144     out_be32(cfg, old_mask | (ic << 24) | (0x7 << 16) |
0145          (pic->node_id << 4) | 0xe);
0146     out_be32(cfg + 4, (0x2 << 16) | (hw & 0xff));
0147 
0148     return 0;
0149 }
0150 
0151 static struct irq_chip spider_pic = {
0152     .name = "SPIDER",
0153     .irq_unmask = spider_unmask_irq,
0154     .irq_mask = spider_mask_irq,
0155     .irq_ack = spider_ack_irq,
0156     .irq_set_type = spider_set_irq_type,
0157 };
0158 
0159 static int spider_host_map(struct irq_domain *h, unsigned int virq,
0160             irq_hw_number_t hw)
0161 {
0162     irq_set_chip_data(virq, h->host_data);
0163     irq_set_chip_and_handler(virq, &spider_pic, handle_level_irq);
0164 
0165     /* Set default irq type */
0166     irq_set_irq_type(virq, IRQ_TYPE_NONE);
0167 
0168     return 0;
0169 }
0170 
0171 static int spider_host_xlate(struct irq_domain *h, struct device_node *ct,
0172                const u32 *intspec, unsigned int intsize,
0173                irq_hw_number_t *out_hwirq, unsigned int *out_flags)
0174 
0175 {
0176     /* Spider interrupts have 2 cells, first is the interrupt source,
0177      * second, well, I don't know for sure yet ... We mask the top bits
0178      * because old device-trees encode a node number in there
0179      */
0180     *out_hwirq = intspec[0] & 0x3f;
0181     *out_flags = IRQ_TYPE_LEVEL_HIGH;
0182     return 0;
0183 }
0184 
0185 static const struct irq_domain_ops spider_host_ops = {
0186     .map = spider_host_map,
0187     .xlate = spider_host_xlate,
0188 };
0189 
0190 static void spider_irq_cascade(struct irq_desc *desc)
0191 {
0192     struct irq_chip *chip = irq_desc_get_chip(desc);
0193     struct spider_pic *pic = irq_desc_get_handler_data(desc);
0194     unsigned int cs;
0195 
0196     cs = in_be32(pic->regs + TIR_CS) >> 24;
0197     if (cs != SPIDER_IRQ_INVALID)
0198         generic_handle_domain_irq(pic->host, cs);
0199 
0200     chip->irq_eoi(&desc->irq_data);
0201 }
0202 
0203 /* For hooking up the cascade we have a problem. Our device-tree is
0204  * crap and we don't know on which BE iic interrupt we are hooked on at
0205  * least not the "standard" way. We can reconstitute it based on two
0206  * informations though: which BE node we are connected to and whether
0207  * we are connected to IOIF0 or IOIF1. Right now, we really only care
0208  * about the IBM cell blade and we know that its firmware gives us an
0209  * interrupt-map property which is pretty strange.
0210  */
0211 static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
0212 {
0213     unsigned int virq;
0214     const u32 *imap, *tmp;
0215     int imaplen, intsize, unit;
0216     struct device_node *iic;
0217     struct device_node *of_node;
0218 
0219     of_node = irq_domain_get_of_node(pic->host);
0220 
0221     /* First, we check whether we have a real "interrupts" in the device
0222      * tree in case the device-tree is ever fixed
0223      */
0224     virq = irq_of_parse_and_map(of_node, 0);
0225     if (virq)
0226         return virq;
0227 
0228     /* Now do the horrible hacks */
0229     tmp = of_get_property(of_node, "#interrupt-cells", NULL);
0230     if (tmp == NULL)
0231         return 0;
0232     intsize = *tmp;
0233     imap = of_get_property(of_node, "interrupt-map", &imaplen);
0234     if (imap == NULL || imaplen < (intsize + 1))
0235         return 0;
0236     iic = of_find_node_by_phandle(imap[intsize]);
0237     if (iic == NULL)
0238         return 0;
0239     imap += intsize + 1;
0240     tmp = of_get_property(iic, "#interrupt-cells", NULL);
0241     if (tmp == NULL) {
0242         of_node_put(iic);
0243         return 0;
0244     }
0245     intsize = *tmp;
0246     /* Assume unit is last entry of interrupt specifier */
0247     unit = imap[intsize - 1];
0248     /* Ok, we have a unit, now let's try to get the node */
0249     tmp = of_get_property(iic, "ibm,interrupt-server-ranges", NULL);
0250     if (tmp == NULL) {
0251         of_node_put(iic);
0252         return 0;
0253     }
0254     /* ugly as hell but works for now */
0255     pic->node_id = (*tmp) >> 1;
0256     of_node_put(iic);
0257 
0258     /* Ok, now let's get cracking. You may ask me why I just didn't match
0259      * the iic host from the iic OF node, but that way I'm still compatible
0260      * with really really old old firmwares for which we don't have a node
0261      */
0262     /* Manufacture an IIC interrupt number of class 2 */
0263     virq = irq_create_mapping(NULL,
0264                   (pic->node_id << IIC_IRQ_NODE_SHIFT) |
0265                   (2 << IIC_IRQ_CLASS_SHIFT) |
0266                   unit);
0267     if (!virq)
0268         printk(KERN_ERR "spider_pic: failed to map cascade !");
0269     return virq;
0270 }
0271 
0272 
0273 static void __init spider_init_one(struct device_node *of_node, int chip,
0274                    unsigned long addr)
0275 {
0276     struct spider_pic *pic = &spider_pics[chip];
0277     int i, virq;
0278 
0279     /* Map registers */
0280     pic->regs = ioremap(addr, 0x1000);
0281     if (pic->regs == NULL)
0282         panic("spider_pic: can't map registers !");
0283 
0284     /* Allocate a host */
0285     pic->host = irq_domain_add_linear(of_node, SPIDER_SRC_COUNT,
0286                       &spider_host_ops, pic);
0287     if (pic->host == NULL)
0288         panic("spider_pic: can't allocate irq host !");
0289 
0290     /* Go through all sources and disable them */
0291     for (i = 0; i < SPIDER_SRC_COUNT; i++) {
0292         void __iomem *cfg = pic->regs + TIR_CFGA + 8 * i;
0293         out_be32(cfg, in_be32(cfg) & ~0x30000000u);
0294     }
0295 
0296     /* do not mask any interrupts because of level */
0297     out_be32(pic->regs + TIR_MSK, 0x0);
0298 
0299     /* enable interrupt packets to be output */
0300     out_be32(pic->regs + TIR_PIEN, in_be32(pic->regs + TIR_PIEN) | 0x1);
0301 
0302     /* Hook up the cascade interrupt to the iic and nodeid */
0303     virq = spider_find_cascade_and_node(pic);
0304     if (!virq)
0305         return;
0306     irq_set_handler_data(virq, pic);
0307     irq_set_chained_handler(virq, spider_irq_cascade);
0308 
0309     printk(KERN_INFO "spider_pic: node %d, addr: 0x%lx %pOF\n",
0310            pic->node_id, addr, of_node);
0311 
0312     /* Enable the interrupt detection enable bit. Do this last! */
0313     out_be32(pic->regs + TIR_DEN, in_be32(pic->regs + TIR_DEN) | 0x1);
0314 }
0315 
0316 void __init spider_init_IRQ(void)
0317 {
0318     struct resource r;
0319     struct device_node *dn;
0320     int chip = 0;
0321 
0322     /* XXX node numbers are totally bogus. We _hope_ we get the device
0323      * nodes in the right order here but that's definitely not guaranteed,
0324      * we need to get the node from the device tree instead.
0325      * There is currently no proper property for it (but our whole
0326      * device-tree is bogus anyway) so all we can do is pray or maybe test
0327      * the address and deduce the node-id
0328      */
0329     for_each_node_by_name(dn, "interrupt-controller") {
0330         if (of_device_is_compatible(dn, "CBEA,platform-spider-pic")) {
0331             if (of_address_to_resource(dn, 0, &r)) {
0332                 printk(KERN_WARNING "spider-pic: Failed\n");
0333                 continue;
0334             }
0335         } else if (of_device_is_compatible(dn, "sti,platform-spider-pic")
0336                && (chip < 2)) {
0337             static long hard_coded_pics[] =
0338                 { 0x24000008000ul, 0x34000008000ul};
0339             r.start = hard_coded_pics[chip];
0340         } else
0341             continue;
0342         spider_init_one(dn, chip++, r.start);
0343     }
0344 }