Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003 ** I/O Sapic Driver - PCI interrupt line support
0004 **
0005 **      (c) Copyright 1999 Grant Grundler
0006 **      (c) Copyright 1999 Hewlett-Packard Company
0007 **
0008 **
0009 ** The I/O sapic driver manages the Interrupt Redirection Table which is
0010 ** the control logic to convert PCI line based interrupts into a Message
0011 ** Signaled Interrupt (aka Transaction Based Interrupt, TBI).
0012 **
0013 ** Acronyms
0014 ** --------
0015 ** HPA  Hard Physical Address (aka MMIO address)
0016 ** IRQ  Interrupt ReQuest. Implies Line based interrupt.
0017 ** IRT  Interrupt Routing Table (provided by PAT firmware)
0018 ** IRdT Interrupt Redirection Table. IRQ line to TXN ADDR/DATA
0019 **      table which is implemented in I/O SAPIC.
0020 ** ISR  Interrupt Service Routine. aka Interrupt handler.
0021 ** MSI  Message Signaled Interrupt. PCI 2.2 functionality.
0022 **      aka Transaction Based Interrupt (or TBI).
0023 ** PA   Precision Architecture. HP's RISC architecture.
0024 ** RISC Reduced Instruction Set Computer.
0025 **
0026 **
0027 ** What's a Message Signalled Interrupt?
0028 ** -------------------------------------
0029 ** MSI is a write transaction which targets a processor and is similar
0030 ** to a processor write to memory or MMIO. MSIs can be generated by I/O
0031 ** devices as well as processors and require *architecture* to work.
0032 **
0033 ** PA only supports MSI. So I/O subsystems must either natively generate
0034 ** MSIs (e.g. GSC or HP-PB) or convert line based interrupts into MSIs
0035 ** (e.g. PCI and EISA).  IA64 supports MSIs via a "local SAPIC" which
0036 ** acts on behalf of a processor.
0037 **
0038 ** MSI allows any I/O device to interrupt any processor. This makes
0039 ** load balancing of the interrupt processing possible on an SMP platform.
0040 ** Interrupts are also ordered WRT to DMA data.  It's possible on I/O
0041 ** coherent systems to completely eliminate PIO reads from the interrupt
0042 ** path. The device and driver must be designed and implemented to
0043 ** guarantee all DMA has been issued (issues about atomicity here)
0044 ** before the MSI is issued. I/O status can then safely be read from
0045 ** DMA'd data by the ISR.
0046 **
0047 **
0048 ** PA Firmware
0049 ** -----------
0050 ** PA-RISC platforms have two fundamentally different types of firmware.
0051 ** For PCI devices, "Legacy" PDC initializes the "INTERRUPT_LINE" register
0052 ** and BARs similar to a traditional PC BIOS.
0053 ** The newer "PAT" firmware supports PDC calls which return tables.
0054 ** PAT firmware only initializes the PCI Console and Boot interface.
0055 ** With these tables, the OS can program all other PCI devices.
0056 **
0057 ** One such PAT PDC call returns the "Interrupt Routing Table" (IRT).
0058 ** The IRT maps each PCI slot's INTA-D "output" line to an I/O SAPIC
0059 ** input line.  If the IRT is not available, this driver assumes
0060 ** INTERRUPT_LINE register has been programmed by firmware. The latter
0061 ** case also means online addition of PCI cards can NOT be supported
0062 ** even if HW support is present.
0063 **
0064 ** All platforms with PAT firmware to date (Oct 1999) use one Interrupt
0065 ** Routing Table for the entire platform.
0066 **
0067 ** Where's the iosapic?
0068 ** --------------------
0069 ** I/O sapic is part of the "Core Electronics Complex". And on HP platforms
0070 ** it's integrated as part of the PCI bus adapter, "lba".  So no bus walk
0071 ** will discover I/O Sapic. I/O Sapic driver learns about each device
0072 ** when lba driver advertises the presence of the I/O sapic by calling
0073 ** iosapic_register().
0074 **
0075 **
0076 ** IRQ handling notes
0077 ** ------------------
0078 ** The IO-SAPIC can indicate to the CPU which interrupt was asserted.
0079 ** So, unlike the GSC-ASIC and Dino, we allocate one CPU interrupt per
0080 ** IO-SAPIC interrupt and call the device driver's handler directly.
0081 ** The IO-SAPIC driver hijacks the CPU interrupt handler so it can
0082 ** issue the End Of Interrupt command to the IO-SAPIC.
0083 **
0084 ** Overview of exported iosapic functions
0085 ** --------------------------------------
0086 ** (caveat: code isn't finished yet - this is just the plan)
0087 **
0088 ** iosapic_init:
0089 **   o initialize globals (lock, etc)
0090 **   o try to read IRT. Presence of IRT determines if this is
0091 **     a PAT platform or not.
0092 **
0093 ** iosapic_register():
0094 **   o create iosapic_info instance data structure
0095 **   o allocate vector_info array for this iosapic
0096 **   o initialize vector_info - read corresponding IRdT?
0097 **
0098 ** iosapic_xlate_pin: (only called by fixup_irq for PAT platform)
0099 **   o intr_pin = read cfg (INTERRUPT_PIN);
0100 **   o if (device under PCI-PCI bridge)
0101 **               translate slot/pin
0102 **
0103 ** iosapic_fixup_irq:
0104 **   o if PAT platform (IRT present)
0105 **     intr_pin = iosapic_xlate_pin(isi,pcidev):
0106 **         intr_line = find IRT entry(isi, PCI_SLOT(pcidev), intr_pin)
0107 **         save IRT entry into vector_info later
0108 **         write cfg INTERRUPT_LINE (with intr_line)?
0109 **     else
0110 **         intr_line = pcidev->irq
0111 **         IRT pointer = NULL
0112 **     endif
0113 **   o locate vector_info (needs: isi, intr_line)
0114 **   o allocate processor "irq" and get txn_addr/data
0115 **   o request_irq(processor_irq,  iosapic_interrupt, vector_info,...)
0116 **
0117 ** iosapic_enable_irq:
0118 **   o clear any pending IRQ on that line
0119 **   o enable IRdT - call enable_irq(vector[line]->processor_irq)
0120 **   o write EOI in case line is already asserted.
0121 **
0122 ** iosapic_disable_irq:
0123 **   o disable IRdT - call disable_irq(vector[line]->processor_irq)
0124 */
0125 
0126 #include <linux/pci.h>
0127 
0128 #include <asm/pdc.h>
0129 #include <asm/pdcpat.h>
0130 #ifdef CONFIG_SUPERIO
0131 #include <asm/superio.h>
0132 #endif
0133 
0134 #include <asm/ropes.h>
0135 #include "iosapic_private.h"
0136 
0137 #define MODULE_NAME "iosapic"
0138 
0139 /* "local" compile flags */
0140 #undef PCI_BRIDGE_FUNCS
0141 #undef DEBUG_IOSAPIC
0142 #undef DEBUG_IOSAPIC_IRT
0143 
0144 
0145 #ifdef DEBUG_IOSAPIC
0146 #define DBG(x...) printk(x)
0147 #else /* DEBUG_IOSAPIC */
0148 #define DBG(x...)
0149 #endif /* DEBUG_IOSAPIC */
0150 
0151 #ifdef DEBUG_IOSAPIC_IRT
0152 #define DBG_IRT(x...) printk(x)
0153 #else
0154 #define DBG_IRT(x...)
0155 #endif
0156 
0157 #ifdef CONFIG_64BIT
0158 #define COMPARE_IRTE_ADDR(irte, hpa)    ((irte)->dest_iosapic_addr == (hpa))
0159 #else
0160 #define COMPARE_IRTE_ADDR(irte, hpa)    \
0161         ((irte)->dest_iosapic_addr == ((hpa) | 0xffffffff00000000ULL))
0162 #endif
0163 
0164 #define IOSAPIC_REG_SELECT              0x00
0165 #define IOSAPIC_REG_WINDOW              0x10
0166 #define IOSAPIC_REG_EOI                 0x40
0167 
0168 #define IOSAPIC_REG_VERSION     0x1
0169 
0170 #define IOSAPIC_IRDT_ENTRY(idx)     (0x10+(idx)*2)
0171 #define IOSAPIC_IRDT_ENTRY_HI(idx)  (0x11+(idx)*2)
0172 
0173 static inline unsigned int iosapic_read(void __iomem *iosapic, unsigned int reg)
0174 {
0175     writel(reg, iosapic + IOSAPIC_REG_SELECT);
0176     return readl(iosapic + IOSAPIC_REG_WINDOW);
0177 }
0178 
0179 static inline void iosapic_write(void __iomem *iosapic, unsigned int reg, u32 val)
0180 {
0181     writel(reg, iosapic + IOSAPIC_REG_SELECT);
0182     writel(val, iosapic + IOSAPIC_REG_WINDOW);
0183 }
0184 
0185 #define IOSAPIC_VERSION_MASK    0x000000ff
0186 #define IOSAPIC_VERSION(ver)    ((int) (ver & IOSAPIC_VERSION_MASK))
0187 
0188 #define IOSAPIC_MAX_ENTRY_MASK          0x00ff0000
0189 #define IOSAPIC_MAX_ENTRY_SHIFT         0x10
0190 #define IOSAPIC_IRDT_MAX_ENTRY(ver) \
0191     (int) (((ver) & IOSAPIC_MAX_ENTRY_MASK) >> IOSAPIC_MAX_ENTRY_SHIFT)
0192 
0193 /* bits in the "low" I/O Sapic IRdT entry */
0194 #define IOSAPIC_IRDT_ENABLE       0x10000
0195 #define IOSAPIC_IRDT_PO_LOW       0x02000
0196 #define IOSAPIC_IRDT_LEVEL_TRIG   0x08000
0197 #define IOSAPIC_IRDT_MODE_LPRI    0x00100
0198 
0199 /* bits in the "high" I/O Sapic IRdT entry */
0200 #define IOSAPIC_IRDT_ID_EID_SHIFT              0x10
0201 
0202 
0203 static DEFINE_SPINLOCK(iosapic_lock);
0204 
0205 static inline void iosapic_eoi(void __iomem *addr, unsigned int data)
0206 {
0207     __raw_writel(data, addr);
0208 }
0209 
0210 /*
0211 ** REVISIT: future platforms may have more than one IRT.
0212 ** If so, the following three fields form a structure which
0213 ** then be linked into a list. Names are chosen to make searching
0214 ** for them easy - not necessarily accurate (eg "cell").
0215 **
0216 ** Alternative: iosapic_info could point to the IRT it's in.
0217 ** iosapic_register() could search a list of IRT's.
0218 */
0219 static struct irt_entry *irt_cell;
0220 static size_t irt_num_entry;
0221 
0222 static struct irt_entry *iosapic_alloc_irt(int num_entries)
0223 {
0224     return kcalloc(num_entries, sizeof(struct irt_entry), GFP_KERNEL);
0225 }
0226 
0227 /**
0228  * iosapic_load_irt - Fill in the interrupt routing table
0229  * @cell_num: The cell number of the CPU we're currently executing on
0230  * @irt: The address to place the new IRT at
0231  * @return The number of entries found
0232  *
0233  * The "Get PCI INT Routing Table Size" option returns the number of 
0234  * entries in the PCI interrupt routing table for the cell specified 
0235  * in the cell_number argument.  The cell number must be for a cell 
0236  * within the caller's protection domain.
0237  *
0238  * The "Get PCI INT Routing Table" option returns, for the cell 
0239  * specified in the cell_number argument, the PCI interrupt routing 
0240  * table in the caller allocated memory pointed to by mem_addr.
0241  * We assume the IRT only contains entries for I/O SAPIC and
0242  * calculate the size based on the size of I/O sapic entries.
0243  *
0244  * The PCI interrupt routing table entry format is derived from the
0245  * IA64 SAL Specification 2.4.   The PCI interrupt routing table defines
0246  * the routing of PCI interrupt signals between the PCI device output
0247  * "pins" and the IO SAPICs' input "lines" (including core I/O PCI
0248  * devices).  This table does NOT include information for devices/slots
0249  * behind PCI to PCI bridges. See PCI to PCI Bridge Architecture Spec.
0250  * for the architected method of routing of IRQ's behind PPB's.
0251  */
0252 
0253 
0254 static int __init
0255 iosapic_load_irt(unsigned long cell_num, struct irt_entry **irt)
0256 {
0257     long status;              /* PDC return value status */
0258     struct irt_entry *table;  /* start of interrupt routing tbl */
0259     unsigned long num_entries = 0UL;
0260 
0261     BUG_ON(!irt);
0262 
0263     if (is_pdc_pat()) {
0264         /* Use pat pdc routine to get interrupt routing table size */
0265         DBG("calling get_irt_size (cell %ld)\n", cell_num);
0266         status = pdc_pat_get_irt_size(&num_entries, cell_num);
0267         DBG("get_irt_size: %ld\n", status);
0268 
0269         BUG_ON(status != PDC_OK);
0270         BUG_ON(num_entries == 0);
0271 
0272         /*
0273         ** allocate memory for interrupt routing table
0274         ** This interface isn't really right. We are assuming
0275         ** the contents of the table are exclusively
0276         ** for I/O sapic devices.
0277         */
0278         table = iosapic_alloc_irt(num_entries);
0279         if (table == NULL) {
0280             printk(KERN_WARNING MODULE_NAME ": read_irt : can "
0281                     "not alloc mem for IRT\n");
0282             return 0;
0283         }
0284 
0285         /* get PCI INT routing table */
0286         status = pdc_pat_get_irt(table, cell_num);
0287         DBG("pdc_pat_get_irt: %ld\n", status);
0288         WARN_ON(status != PDC_OK);
0289     } else {
0290         /*
0291         ** C3000/J5000 (and similar) platforms with Sprockets PDC
0292         ** will return exactly one IRT for all iosapics.
0293         ** So if we have one, don't need to get it again.
0294         */
0295         if (irt_cell)
0296             return 0;
0297 
0298         /* Should be using the Elroy's HPA, but it's ignored anyway */
0299         status = pdc_pci_irt_size(&num_entries, 0);
0300         DBG("pdc_pci_irt_size: %ld\n", status);
0301 
0302         if (status != PDC_OK) {
0303             /* Not a "legacy" system with I/O SAPIC either */
0304             return 0;
0305         }
0306 
0307         BUG_ON(num_entries == 0);
0308 
0309         table = iosapic_alloc_irt(num_entries);
0310         if (!table) {
0311             printk(KERN_WARNING MODULE_NAME ": read_irt : can "
0312                     "not alloc mem for IRT\n");
0313             return 0;
0314         }
0315 
0316         /* HPA ignored by this call too. */
0317         status = pdc_pci_irt(num_entries, 0, table);
0318         BUG_ON(status != PDC_OK);
0319     }
0320 
0321     /* return interrupt table address */
0322     *irt = table;
0323 
0324 #ifdef DEBUG_IOSAPIC_IRT
0325 {
0326     struct irt_entry *p = table;
0327     int i;
0328 
0329     printk(MODULE_NAME " Interrupt Routing Table (cell %ld)\n", cell_num);
0330     printk(MODULE_NAME " start = 0x%p num_entries %ld entry_size %d\n",
0331         table,
0332         num_entries,
0333         (int) sizeof(struct irt_entry));
0334 
0335     for (i = 0 ; i < num_entries ; i++, p++) {
0336         printk(MODULE_NAME " %02x %02x %02x %02x %02x %02x %02x %02x %08x%08x\n",
0337         p->entry_type, p->entry_length, p->interrupt_type,
0338         p->polarity_trigger, p->src_bus_irq_devno, p->src_bus_id,
0339         p->src_seg_id, p->dest_iosapic_intin,
0340         ((u32 *) p)[2],
0341         ((u32 *) p)[3]
0342         );
0343     }
0344 }
0345 #endif /* DEBUG_IOSAPIC_IRT */
0346 
0347     return num_entries;
0348 }
0349 
0350 
0351 
0352 void __init iosapic_init(void)
0353 {
0354     unsigned long cell = 0;
0355 
0356     DBG("iosapic_init()\n");
0357 
0358 #ifdef __LP64__
0359     if (is_pdc_pat()) {
0360         int status;
0361         struct pdc_pat_cell_num cell_info;
0362 
0363         status = pdc_pat_cell_get_number(&cell_info);
0364         if (status == PDC_OK) {
0365             cell = cell_info.cell_num;
0366         }
0367     }
0368 #endif
0369 
0370     /* get interrupt routing table for this cell */
0371     irt_num_entry = iosapic_load_irt(cell, &irt_cell);
0372     if (irt_num_entry == 0)
0373         irt_cell = NULL;    /* old PDC w/o iosapic */
0374 }
0375 
0376 
0377 /*
0378 ** Return the IRT entry in case we need to look something else up.
0379 */
0380 static struct irt_entry *
0381 irt_find_irqline(struct iosapic_info *isi, u8 slot, u8 intr_pin)
0382 {
0383     struct irt_entry *i = irt_cell;
0384     int cnt;    /* track how many entries we've looked at */
0385     u8 irq_devno = (slot << IRT_DEV_SHIFT) | (intr_pin-1);
0386 
0387     DBG_IRT("irt_find_irqline() SLOT %d pin %d\n", slot, intr_pin);
0388 
0389     for (cnt=0; cnt < irt_num_entry; cnt++, i++) {
0390 
0391         /*
0392         ** Validate: entry_type, entry_length, interrupt_type
0393         **
0394         ** Difference between validate vs compare is the former
0395         ** should print debug info and is not expected to "fail"
0396         ** on current platforms.
0397         */
0398         if (i->entry_type != IRT_IOSAPIC_TYPE) {
0399             DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry %d type %d\n", i, cnt, i->entry_type);
0400             continue;
0401         }
0402         
0403         if (i->entry_length != IRT_IOSAPIC_LENGTH) {
0404             DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry %d  length %d\n", i, cnt, i->entry_length);
0405             continue;
0406         }
0407 
0408         if (i->interrupt_type != IRT_VECTORED_INTR) {
0409             DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry  %d interrupt_type %d\n", i, cnt, i->interrupt_type);
0410             continue;
0411         }
0412 
0413         if (!COMPARE_IRTE_ADDR(i, isi->isi_hpa))
0414             continue;
0415 
0416         if ((i->src_bus_irq_devno & IRT_IRQ_DEVNO_MASK) != irq_devno)
0417             continue;
0418 
0419         /*
0420         ** Ignore: src_bus_id and rc_seg_id correlate with
0421         **         iosapic_info->isi_hpa on HP platforms.
0422         **         If needed, pass in "PFA" (aka config space addr)
0423         **         instead of slot.
0424         */
0425 
0426         /* Found it! */
0427         return i;
0428     }
0429 
0430     printk(KERN_WARNING MODULE_NAME ": 0x%lx : no IRT entry for slot %d, pin %d\n",
0431             isi->isi_hpa, slot, intr_pin);
0432     return NULL;
0433 }
0434 
0435 
0436 /*
0437 ** xlate_pin() supports the skewing of IRQ lines done by subsidiary bridges.
0438 ** Legacy PDC already does this translation for us and stores it in INTR_LINE.
0439 **
0440 ** PAT PDC needs to basically do what legacy PDC does:
0441 ** o read PIN
0442 ** o adjust PIN in case device is "behind" a PPB
0443 **     (eg 4-port 100BT and SCSI/LAN "Combo Card")
0444 ** o convert slot/pin to I/O SAPIC input line.
0445 **
0446 ** HP platforms only support:
0447 ** o one level of skewing for any number of PPBs
0448 ** o only support PCI-PCI Bridges.
0449 */
0450 static struct irt_entry *
0451 iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev)
0452 {
0453     u8 intr_pin, intr_slot;
0454 
0455     pci_read_config_byte(pcidev, PCI_INTERRUPT_PIN, &intr_pin);
0456 
0457     DBG_IRT("iosapic_xlate_pin(%s) SLOT %d pin %d\n",
0458         pcidev->slot_name, PCI_SLOT(pcidev->devfn), intr_pin);
0459 
0460     if (intr_pin == 0) {
0461         /* The device does NOT support/use IRQ lines.  */
0462         return NULL;
0463     }
0464 
0465     /* Check if pcidev behind a PPB */
0466     if (pcidev->bus->parent) {
0467         /* Convert pcidev INTR_PIN into something we
0468         ** can lookup in the IRT.
0469         */
0470 #ifdef PCI_BRIDGE_FUNCS
0471         /*
0472         ** Proposal #1:
0473         **
0474         ** call implementation specific translation function
0475         ** This is architecturally "cleaner". HP-UX doesn't
0476         ** support other secondary bus types (eg. E/ISA) directly.
0477         ** May be needed for other processor (eg IA64) architectures
0478         ** or by some ambitous soul who wants to watch TV.
0479         */
0480         if (pci_bridge_funcs->xlate_intr_line) {
0481             intr_pin = pci_bridge_funcs->xlate_intr_line(pcidev);
0482         }
0483 #else   /* PCI_BRIDGE_FUNCS */
0484         struct pci_bus *p = pcidev->bus;
0485         /*
0486         ** Proposal #2:
0487         ** The "pin" is skewed ((pin + dev - 1) % 4).
0488         **
0489         ** This isn't very clean since I/O SAPIC must assume:
0490         **   - all platforms only have PCI busses.
0491         **   - only PCI-PCI bridge (eg not PCI-EISA, PCI-PCMCIA)
0492         **   - IRQ routing is only skewed once regardless of
0493         **     the number of PPB's between iosapic and device.
0494         **     (Bit3 expansion chassis follows this rule)
0495         **
0496         ** Advantage is it's really easy to implement.
0497         */
0498         intr_pin = pci_swizzle_interrupt_pin(pcidev, intr_pin);
0499 #endif /* PCI_BRIDGE_FUNCS */
0500 
0501         /*
0502          * Locate the host slot of the PPB.
0503          */
0504         while (p->parent->parent)
0505             p = p->parent;
0506 
0507         intr_slot = PCI_SLOT(p->self->devfn);
0508     } else {
0509         intr_slot = PCI_SLOT(pcidev->devfn);
0510     }
0511     DBG_IRT("iosapic_xlate_pin:  bus %d slot %d pin %d\n",
0512             pcidev->bus->busn_res.start, intr_slot, intr_pin);
0513 
0514     return irt_find_irqline(isi, intr_slot, intr_pin);
0515 }
0516 
0517 static void iosapic_rd_irt_entry(struct vector_info *vi , u32 *dp0, u32 *dp1)
0518 {
0519     struct iosapic_info *isp = vi->iosapic;
0520     u8 idx = vi->irqline;
0521 
0522     *dp0 = iosapic_read(isp->addr, IOSAPIC_IRDT_ENTRY(idx));
0523     *dp1 = iosapic_read(isp->addr, IOSAPIC_IRDT_ENTRY_HI(idx));
0524 }
0525 
0526 
0527 static void iosapic_wr_irt_entry(struct vector_info *vi, u32 dp0, u32 dp1)
0528 {
0529     struct iosapic_info *isp = vi->iosapic;
0530 
0531     DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %lx 0x%x 0x%x\n",
0532         vi->irqline, isp->isi_hpa, dp0, dp1);
0533 
0534     iosapic_write(isp->addr, IOSAPIC_IRDT_ENTRY(vi->irqline), dp0);
0535 
0536     /* Read the window register to flush the writes down to HW  */
0537     dp0 = readl(isp->addr+IOSAPIC_REG_WINDOW);
0538 
0539     iosapic_write(isp->addr, IOSAPIC_IRDT_ENTRY_HI(vi->irqline), dp1);
0540 
0541     /* Read the window register to flush the writes down to HW  */
0542     dp1 = readl(isp->addr+IOSAPIC_REG_WINDOW);
0543 }
0544 
0545 /*
0546 ** set_irt prepares the data (dp0, dp1) according to the vector_info
0547 ** and target cpu (id_eid).  dp0/dp1 are then used to program I/O SAPIC
0548 ** IRdT for the given "vector" (aka IRQ line).
0549 */
0550 static void
0551 iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1)
0552 {
0553     u32 mode = 0;
0554     struct irt_entry *p = vi->irte;
0555 
0556     if ((p->polarity_trigger & IRT_PO_MASK) == IRT_ACTIVE_LO)
0557         mode |= IOSAPIC_IRDT_PO_LOW;
0558 
0559     if (((p->polarity_trigger >> IRT_EL_SHIFT) & IRT_EL_MASK) == IRT_LEVEL_TRIG)
0560         mode |= IOSAPIC_IRDT_LEVEL_TRIG;
0561 
0562     /*
0563     ** IA64 REVISIT
0564     ** PA doesn't support EXTINT or LPRIO bits.
0565     */
0566 
0567     *dp0 = mode | (u32) vi->txn_data;
0568 
0569     /*
0570     ** Extracting id_eid isn't a real clean way of getting it.
0571     ** But the encoding is the same for both PA and IA64 platforms.
0572     */
0573     if (is_pdc_pat()) {
0574         /*
0575         ** PAT PDC just hands it to us "right".
0576         ** txn_addr comes from cpu_data[x].txn_addr.
0577         */
0578         *dp1 = (u32) (vi->txn_addr);
0579     } else {
0580         /* 
0581         ** eg if base_addr == 0xfffa0000),
0582         **    we want to get 0xa0ff0000.
0583         **
0584         ** eid  0x0ff00000 -> 0x00ff0000
0585         ** id   0x000ff000 -> 0xff000000
0586         */
0587         *dp1 = (((u32)vi->txn_addr & 0x0ff00000) >> 4) |
0588             (((u32)vi->txn_addr & 0x000ff000) << 12);
0589     }
0590     DBG_IRT("iosapic_set_irt_data(): 0x%x 0x%x\n", *dp0, *dp1);
0591 }
0592 
0593 
0594 static void iosapic_mask_irq(struct irq_data *d)
0595 {
0596     unsigned long flags;
0597     struct vector_info *vi = irq_data_get_irq_chip_data(d);
0598     u32 d0, d1;
0599 
0600     spin_lock_irqsave(&iosapic_lock, flags);
0601     iosapic_rd_irt_entry(vi, &d0, &d1);
0602     d0 |= IOSAPIC_IRDT_ENABLE;
0603     iosapic_wr_irt_entry(vi, d0, d1);
0604     spin_unlock_irqrestore(&iosapic_lock, flags);
0605 }
0606 
0607 static void iosapic_unmask_irq(struct irq_data *d)
0608 {
0609     struct vector_info *vi = irq_data_get_irq_chip_data(d);
0610     u32 d0, d1;
0611 
0612     /* data is initialized by fixup_irq */
0613     WARN_ON(vi->txn_irq  == 0);
0614 
0615     iosapic_set_irt_data(vi, &d0, &d1);
0616     iosapic_wr_irt_entry(vi, d0, d1);
0617 
0618 #ifdef DEBUG_IOSAPIC_IRT
0619 {
0620     u32 *t = (u32 *) ((ulong) vi->eoi_addr & ~0xffUL);
0621     printk("iosapic_enable_irq(): regs %p", vi->eoi_addr);
0622     for ( ; t < vi->eoi_addr; t++)
0623         printk(" %x", readl(t));
0624     printk("\n");
0625 }
0626 
0627 printk("iosapic_enable_irq(): sel ");
0628 {
0629     struct iosapic_info *isp = vi->iosapic;
0630 
0631     for (d0=0x10; d0<0x1e; d0++) {
0632         d1 = iosapic_read(isp->addr, d0);
0633         printk(" %x", d1);
0634     }
0635 }
0636 printk("\n");
0637 #endif
0638 
0639     /*
0640      * Issuing I/O SAPIC an EOI causes an interrupt IFF IRQ line is
0641      * asserted.  IRQ generally should not be asserted when a driver
0642      * enables their IRQ. It can lead to "interesting" race conditions
0643      * in the driver initialization sequence.
0644      */
0645     DBG(KERN_DEBUG "enable_irq(%d): eoi(%p, 0x%x)\n", d->irq,
0646             vi->eoi_addr, vi->eoi_data);
0647     iosapic_eoi(vi->eoi_addr, vi->eoi_data);
0648 }
0649 
0650 static void iosapic_eoi_irq(struct irq_data *d)
0651 {
0652     struct vector_info *vi = irq_data_get_irq_chip_data(d);
0653 
0654     iosapic_eoi(vi->eoi_addr, vi->eoi_data);
0655     cpu_eoi_irq(d);
0656 }
0657 
0658 #ifdef CONFIG_SMP
0659 static int iosapic_set_affinity_irq(struct irq_data *d,
0660                     const struct cpumask *dest, bool force)
0661 {
0662     struct vector_info *vi = irq_data_get_irq_chip_data(d);
0663     u32 d0, d1, dummy_d0;
0664     unsigned long flags;
0665     int dest_cpu;
0666 
0667     dest_cpu = cpu_check_affinity(d, dest);
0668     if (dest_cpu < 0)
0669         return -1;
0670 
0671     irq_data_update_affinity(d, cpumask_of(dest_cpu));
0672     vi->txn_addr = txn_affinity_addr(d->irq, dest_cpu);
0673 
0674     spin_lock_irqsave(&iosapic_lock, flags);
0675     /* d1 contains the destination CPU, so only want to set that
0676      * entry */
0677     iosapic_rd_irt_entry(vi, &d0, &d1);
0678     iosapic_set_irt_data(vi, &dummy_d0, &d1);
0679     iosapic_wr_irt_entry(vi, d0, d1);
0680     spin_unlock_irqrestore(&iosapic_lock, flags);
0681 
0682     return 0;
0683 }
0684 #endif
0685 
0686 static struct irq_chip iosapic_interrupt_type = {
0687     .name       =   "IO-SAPIC-level",
0688     .irq_unmask =   iosapic_unmask_irq,
0689     .irq_mask   =   iosapic_mask_irq,
0690     .irq_ack    =   cpu_ack_irq,
0691     .irq_eoi    =   iosapic_eoi_irq,
0692 #ifdef CONFIG_SMP
0693     .irq_set_affinity = iosapic_set_affinity_irq,
0694 #endif
0695 };
0696 
0697 int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
0698 {
0699     struct iosapic_info *isi = isi_obj;
0700     struct irt_entry *irte = NULL;  /* only used if PAT PDC */
0701     struct vector_info *vi;
0702     int isi_line;   /* line used by device */
0703 
0704     if (!isi) {
0705         printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
0706             pci_name(pcidev));
0707         return -1;
0708     }
0709 
0710 #ifdef CONFIG_SUPERIO
0711     /*
0712      * HACK ALERT! (non-compliant PCI device support)
0713      *
0714      * All SuckyIO interrupts are routed through the PIC's on function 1.
0715      * But SuckyIO OHCI USB controller gets an IRT entry anyway because
0716      * it advertises INT D for INT_PIN.  Use that IRT entry to get the
0717      * SuckyIO interrupt routing for PICs on function 1 (*BLEECCHH*).
0718      */
0719     if (is_superio_device(pcidev)) {
0720         /* We must call superio_fixup_irq() to register the pdev */
0721         pcidev->irq = superio_fixup_irq(pcidev);
0722 
0723         /* Don't return if need to program the IOSAPIC's IRT... */
0724         if (PCI_FUNC(pcidev->devfn) != SUPERIO_USB_FN)
0725             return pcidev->irq;
0726     }
0727 #endif /* CONFIG_SUPERIO */
0728 
0729     /* lookup IRT entry for isi/slot/pin set */
0730     irte = iosapic_xlate_pin(isi, pcidev);
0731     if (!irte) {
0732         printk("iosapic: no IRTE for %s (IRQ not connected?)\n",
0733                 pci_name(pcidev));
0734         return -1;
0735     }
0736     DBG_IRT("iosapic_fixup_irq(): irte %p %x %x %x %x %x %x %x %x\n",
0737         irte,
0738         irte->entry_type,
0739         irte->entry_length,
0740         irte->polarity_trigger,
0741         irte->src_bus_irq_devno,
0742         irte->src_bus_id,
0743         irte->src_seg_id,
0744         irte->dest_iosapic_intin,
0745         (u32) irte->dest_iosapic_addr);
0746     isi_line = irte->dest_iosapic_intin;
0747 
0748     /* get vector info for this input line */
0749     vi = isi->isi_vector + isi_line;
0750     DBG_IRT("iosapic_fixup_irq:  line %d vi 0x%p\n", isi_line, vi);
0751 
0752     /* If this IRQ line has already been setup, skip it */
0753     if (vi->irte)
0754         goto out;
0755 
0756     vi->irte = irte;
0757 
0758     /*
0759      * Allocate processor IRQ
0760      *
0761      * XXX/FIXME The txn_alloc_irq() code and related code should be
0762      * moved to enable_irq(). That way we only allocate processor IRQ
0763      * bits for devices that actually have drivers claiming them.
0764      * Right now we assign an IRQ to every PCI device present,
0765      * regardless of whether it's used or not.
0766      */
0767     vi->txn_irq = txn_alloc_irq(8);
0768 
0769     if (vi->txn_irq < 0)
0770         panic("I/O sapic: couldn't get TXN IRQ\n");
0771 
0772     /* enable_irq() will use txn_* to program IRdT */
0773     vi->txn_addr = txn_alloc_addr(vi->txn_irq);
0774     vi->txn_data = txn_alloc_data(vi->txn_irq);
0775 
0776     vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI;
0777     vi->eoi_data = cpu_to_le32(vi->txn_data);
0778 
0779     cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi);
0780 
0781  out:
0782     pcidev->irq = vi->txn_irq;
0783 
0784     DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
0785         PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->devfn),
0786         pcidev->vendor, pcidev->device, isi_line, pcidev->irq);
0787 
0788     return pcidev->irq;
0789 }
0790 
0791 static struct iosapic_info *iosapic_list;
0792 
0793 #ifdef CONFIG_64BIT
0794 int iosapic_serial_irq(struct parisc_device *dev)
0795 {
0796     struct iosapic_info *isi;
0797     struct irt_entry *irte;
0798     struct vector_info *vi;
0799     int cnt;
0800     int intin;
0801 
0802     intin = (dev->mod_info >> 24) & 15;
0803 
0804     /* lookup IRT entry for isi/slot/pin set */
0805     for (cnt = 0; cnt < irt_num_entry; cnt++) {
0806         irte = &irt_cell[cnt];
0807         if (COMPARE_IRTE_ADDR(irte, dev->mod0) &&
0808             irte->dest_iosapic_intin == intin)
0809             break;
0810     }
0811     if (cnt >= irt_num_entry)
0812         return 0; /* no irq found, force polling */
0813 
0814     DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n",
0815         irte,
0816         irte->entry_type,
0817         irte->entry_length,
0818         irte->polarity_trigger,
0819         irte->src_bus_irq_devno,
0820         irte->src_bus_id,
0821         irte->src_seg_id,
0822         irte->dest_iosapic_intin,
0823         (u32) irte->dest_iosapic_addr);
0824 
0825     /* search for iosapic */
0826     for (isi = iosapic_list; isi; isi = isi->isi_next)
0827         if (isi->isi_hpa == dev->mod0)
0828             break;
0829     if (!isi)
0830         return 0; /* no iosapic found, force polling */
0831 
0832     /* get vector info for this input line */
0833     vi = isi->isi_vector + intin;
0834     DBG_IRT("iosapic_serial_irq:  line %d vi 0x%p\n", iosapic_intin, vi);
0835 
0836     /* If this IRQ line has already been setup, skip it */
0837     if (vi->irte)
0838         goto out;
0839 
0840     vi->irte = irte;
0841 
0842     /*
0843      * Allocate processor IRQ
0844      *
0845      * XXX/FIXME The txn_alloc_irq() code and related code should be
0846      * moved to enable_irq(). That way we only allocate processor IRQ
0847      * bits for devices that actually have drivers claiming them.
0848      * Right now we assign an IRQ to every PCI device present,
0849      * regardless of whether it's used or not.
0850      */
0851     vi->txn_irq = txn_alloc_irq(8);
0852 
0853     if (vi->txn_irq < 0)
0854         panic("I/O sapic: couldn't get TXN IRQ\n");
0855 
0856     /* enable_irq() will use txn_* to program IRdT */
0857     vi->txn_addr = txn_alloc_addr(vi->txn_irq);
0858     vi->txn_data = txn_alloc_data(vi->txn_irq);
0859 
0860     vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI;
0861     vi->eoi_data = cpu_to_le32(vi->txn_data);
0862 
0863     cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi);
0864 
0865  out:
0866 
0867     return vi->txn_irq;
0868 }
0869 #endif
0870 
0871 
0872 /*
0873 ** squirrel away the I/O Sapic Version
0874 */
0875 static unsigned int
0876 iosapic_rd_version(struct iosapic_info *isi)
0877 {
0878     return iosapic_read(isi->addr, IOSAPIC_REG_VERSION);
0879 }
0880 
0881 
0882 /*
0883 ** iosapic_register() is called by "drivers" with an integrated I/O SAPIC.
0884 ** Caller must be certain they have an I/O SAPIC and know its MMIO address.
0885 **
0886 **  o allocate iosapic_info and add it to the list
0887 **  o read iosapic version and squirrel that away
0888 **  o read size of IRdT.
0889 **  o allocate and initialize isi_vector[]
0890 **  o allocate irq region
0891 */
0892 void *iosapic_register(unsigned long hpa)
0893 {
0894     struct iosapic_info *isi = NULL;
0895     struct irt_entry *irte = irt_cell;
0896     struct vector_info *vip;
0897     int cnt;    /* track how many entries we've looked at */
0898 
0899     /*
0900      * Astro based platforms can only support PCI OLARD if they implement
0901      * PAT PDC.  Legacy PDC omits LBAs with no PCI devices from the IRT.
0902      * Search the IRT and ignore iosapic's which aren't in the IRT.
0903      */
0904     for (cnt=0; cnt < irt_num_entry; cnt++, irte++) {
0905         WARN_ON(IRT_IOSAPIC_TYPE != irte->entry_type);
0906         if (COMPARE_IRTE_ADDR(irte, hpa))
0907             break;
0908     }
0909 
0910     if (cnt >= irt_num_entry) {
0911         DBG("iosapic_register() ignoring 0x%lx (NOT FOUND)\n", hpa);
0912         return NULL;
0913     }
0914 
0915     isi = kzalloc(sizeof(struct iosapic_info), GFP_KERNEL);
0916     if (!isi) {
0917         BUG();
0918         return NULL;
0919     }
0920 
0921     isi->addr = ioremap(hpa, 4096);
0922     isi->isi_hpa = hpa;
0923     isi->isi_version = iosapic_rd_version(isi);
0924     isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1;
0925 
0926     vip = isi->isi_vector = kcalloc(isi->isi_num_vectors,
0927                     sizeof(struct vector_info), GFP_KERNEL);
0928     if (vip == NULL) {
0929         kfree(isi);
0930         return NULL;
0931     }
0932 
0933     for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) {
0934         vip->irqline = (unsigned char) cnt;
0935         vip->iosapic = isi;
0936     }
0937     isi->isi_next = iosapic_list;
0938     iosapic_list = isi;
0939     return isi;
0940 }
0941 
0942 
0943 #ifdef DEBUG_IOSAPIC
0944 
0945 static void
0946 iosapic_prt_irt(void *irt, long num_entry)
0947 {
0948     unsigned int i, *irp = (unsigned int *) irt;
0949 
0950 
0951     printk(KERN_DEBUG MODULE_NAME ": Interrupt Routing Table (%lx entries)\n", num_entry);
0952 
0953     for (i=0; i<num_entry; i++, irp += 4) {
0954         printk(KERN_DEBUG "%p : %2d %.8x %.8x %.8x %.8x\n",
0955                     irp, i, irp[0], irp[1], irp[2], irp[3]);
0956     }
0957 }
0958 
0959 
0960 static void
0961 iosapic_prt_vi(struct vector_info *vi)
0962 {
0963     printk(KERN_DEBUG MODULE_NAME ": vector_info[%d] is at %p\n", vi->irqline, vi);
0964     printk(KERN_DEBUG "\t\tstatus:   %.4x\n", vi->status);
0965     printk(KERN_DEBUG "\t\ttxn_irq:  %d\n",  vi->txn_irq);
0966     printk(KERN_DEBUG "\t\ttxn_addr: %lx\n", vi->txn_addr);
0967     printk(KERN_DEBUG "\t\ttxn_data: %lx\n", vi->txn_data);
0968     printk(KERN_DEBUG "\t\teoi_addr: %p\n",  vi->eoi_addr);
0969     printk(KERN_DEBUG "\t\teoi_data: %x\n",  vi->eoi_data);
0970 }
0971 
0972 
0973 static void
0974 iosapic_prt_isi(struct iosapic_info *isi)
0975 {
0976     printk(KERN_DEBUG MODULE_NAME ": io_sapic_info at %p\n", isi);
0977     printk(KERN_DEBUG "\t\tisi_hpa:       %lx\n", isi->isi_hpa);
0978     printk(KERN_DEBUG "\t\tisi_status:    %x\n", isi->isi_status);
0979     printk(KERN_DEBUG "\t\tisi_version:   %x\n", isi->isi_version);
0980     printk(KERN_DEBUG "\t\tisi_vector:    %p\n", isi->isi_vector);
0981 }
0982 #endif /* DEBUG_IOSAPIC */