root/drivers/parisc/iosapic.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. iosapic_read
  2. iosapic_write
  3. iosapic_eoi
  4. iosapic_alloc_irt
  5. iosapic_load_irt
  6. iosapic_init
  7. irt_find_irqline
  8. iosapic_xlate_pin
  9. iosapic_rd_irt_entry
  10. iosapic_wr_irt_entry
  11. iosapic_set_irt_data
  12. iosapic_mask_irq
  13. iosapic_unmask_irq
  14. iosapic_eoi_irq
  15. iosapic_set_affinity_irq
  16. iosapic_fixup_irq
  17. iosapic_serial_irq
  18. iosapic_rd_version
  19. iosapic_register
  20. iosapic_prt_irt
  21. iosapic_prt_vi
  22. iosapic_prt_isi

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3 ** I/O Sapic Driver - PCI interrupt line support
   4 **
   5 **      (c) Copyright 1999 Grant Grundler
   6 **      (c) Copyright 1999 Hewlett-Packard Company
   7 **
   8 **
   9 ** The I/O sapic driver manages the Interrupt Redirection Table which is
  10 ** the control logic to convert PCI line based interrupts into a Message
  11 ** Signaled Interrupt (aka Transaction Based Interrupt, TBI).
  12 **
  13 ** Acronyms
  14 ** --------
  15 ** HPA  Hard Physical Address (aka MMIO address)
  16 ** IRQ  Interrupt ReQuest. Implies Line based interrupt.
  17 ** IRT  Interrupt Routing Table (provided by PAT firmware)
  18 ** IRdT Interrupt Redirection Table. IRQ line to TXN ADDR/DATA
  19 **      table which is implemented in I/O SAPIC.
  20 ** ISR  Interrupt Service Routine. aka Interrupt handler.
  21 ** MSI  Message Signaled Interrupt. PCI 2.2 functionality.
  22 **      aka Transaction Based Interrupt (or TBI).
  23 ** PA   Precision Architecture. HP's RISC architecture.
  24 ** RISC Reduced Instruction Set Computer.
  25 **
  26 **
  27 ** What's a Message Signalled Interrupt?
  28 ** -------------------------------------
  29 ** MSI is a write transaction which targets a processor and is similar
  30 ** to a processor write to memory or MMIO. MSIs can be generated by I/O
  31 ** devices as well as processors and require *architecture* to work.
  32 **
  33 ** PA only supports MSI. So I/O subsystems must either natively generate
  34 ** MSIs (e.g. GSC or HP-PB) or convert line based interrupts into MSIs
  35 ** (e.g. PCI and EISA).  IA64 supports MSIs via a "local SAPIC" which
  36 ** acts on behalf of a processor.
  37 **
  38 ** MSI allows any I/O device to interrupt any processor. This makes
  39 ** load balancing of the interrupt processing possible on an SMP platform.
  40 ** Interrupts are also ordered WRT to DMA data.  It's possible on I/O
  41 ** coherent systems to completely eliminate PIO reads from the interrupt
  42 ** path. The device and driver must be designed and implemented to
  43 ** guarantee all DMA has been issued (issues about atomicity here)
  44 ** before the MSI is issued. I/O status can then safely be read from
  45 ** DMA'd data by the ISR.
  46 **
  47 **
  48 ** PA Firmware
  49 ** -----------
  50 ** PA-RISC platforms have two fundamentally different types of firmware.
  51 ** For PCI devices, "Legacy" PDC initializes the "INTERRUPT_LINE" register
  52 ** and BARs similar to a traditional PC BIOS.
  53 ** The newer "PAT" firmware supports PDC calls which return tables.
  54 ** PAT firmware only initializes the PCI Console and Boot interface.
  55 ** With these tables, the OS can program all other PCI devices.
  56 **
  57 ** One such PAT PDC call returns the "Interrupt Routing Table" (IRT).
  58 ** The IRT maps each PCI slot's INTA-D "output" line to an I/O SAPIC
  59 ** input line.  If the IRT is not available, this driver assumes
  60 ** INTERRUPT_LINE register has been programmed by firmware. The latter
  61 ** case also means online addition of PCI cards can NOT be supported
  62 ** even if HW support is present.
  63 **
  64 ** All platforms with PAT firmware to date (Oct 1999) use one Interrupt
  65 ** Routing Table for the entire platform.
  66 **
  67 ** Where's the iosapic?
  68 ** --------------------
  69 ** I/O sapic is part of the "Core Electronics Complex". And on HP platforms
  70 ** it's integrated as part of the PCI bus adapter, "lba".  So no bus walk
  71 ** will discover I/O Sapic. I/O Sapic driver learns about each device
  72 ** when lba driver advertises the presence of the I/O sapic by calling
  73 ** iosapic_register().
  74 **
  75 **
  76 ** IRQ handling notes
  77 ** ------------------
  78 ** The IO-SAPIC can indicate to the CPU which interrupt was asserted.
  79 ** So, unlike the GSC-ASIC and Dino, we allocate one CPU interrupt per
  80 ** IO-SAPIC interrupt and call the device driver's handler directly.
  81 ** The IO-SAPIC driver hijacks the CPU interrupt handler so it can
  82 ** issue the End Of Interrupt command to the IO-SAPIC.
  83 **
  84 ** Overview of exported iosapic functions
  85 ** --------------------------------------
  86 ** (caveat: code isn't finished yet - this is just the plan)
  87 **
  88 ** iosapic_init:
  89 **   o initialize globals (lock, etc)
  90 **   o try to read IRT. Presence of IRT determines if this is
  91 **     a PAT platform or not.
  92 **
  93 ** iosapic_register():
  94 **   o create iosapic_info instance data structure
  95 **   o allocate vector_info array for this iosapic
  96 **   o initialize vector_info - read corresponding IRdT?
  97 **
  98 ** iosapic_xlate_pin: (only called by fixup_irq for PAT platform)
  99 **   o intr_pin = read cfg (INTERRUPT_PIN);
 100 **   o if (device under PCI-PCI bridge)
 101 **               translate slot/pin
 102 **
 103 ** iosapic_fixup_irq:
 104 **   o if PAT platform (IRT present)
 105 **         intr_pin = iosapic_xlate_pin(isi,pcidev):
 106 **         intr_line = find IRT entry(isi, PCI_SLOT(pcidev), intr_pin)
 107 **         save IRT entry into vector_info later
 108 **         write cfg INTERRUPT_LINE (with intr_line)?
 109 **     else
 110 **         intr_line = pcidev->irq
 111 **         IRT pointer = NULL
 112 **     endif
 113 **   o locate vector_info (needs: isi, intr_line)
 114 **   o allocate processor "irq" and get txn_addr/data
 115 **   o request_irq(processor_irq,  iosapic_interrupt, vector_info,...)
 116 **
 117 ** iosapic_enable_irq:
 118 **   o clear any pending IRQ on that line
 119 **   o enable IRdT - call enable_irq(vector[line]->processor_irq)
 120 **   o write EOI in case line is already asserted.
 121 **
 122 ** iosapic_disable_irq:
 123 **   o disable IRdT - call disable_irq(vector[line]->processor_irq)
 124 */
 125 
 126 #include <linux/pci.h>
 127 
 128 #include <asm/pdc.h>
 129 #include <asm/pdcpat.h>
 130 #ifdef CONFIG_SUPERIO
 131 #include <asm/superio.h>
 132 #endif
 133 
 134 #include <asm/ropes.h>
 135 #include "iosapic_private.h"
 136 
 137 #define MODULE_NAME "iosapic"
 138 
 139 /* "local" compile flags */
 140 #undef PCI_BRIDGE_FUNCS
 141 #undef DEBUG_IOSAPIC
 142 #undef DEBUG_IOSAPIC_IRT
 143 
 144 
 145 #ifdef DEBUG_IOSAPIC
 146 #define DBG(x...) printk(x)
 147 #else /* DEBUG_IOSAPIC */
 148 #define DBG(x...)
 149 #endif /* DEBUG_IOSAPIC */
 150 
 151 #ifdef DEBUG_IOSAPIC_IRT
 152 #define DBG_IRT(x...) printk(x)
 153 #else
 154 #define DBG_IRT(x...)
 155 #endif
 156 
 157 #ifdef CONFIG_64BIT
 158 #define COMPARE_IRTE_ADDR(irte, hpa)    ((irte)->dest_iosapic_addr == (hpa))
 159 #else
 160 #define COMPARE_IRTE_ADDR(irte, hpa)    \
 161                 ((irte)->dest_iosapic_addr == ((hpa) | 0xffffffff00000000ULL))
 162 #endif
 163 
 164 #define IOSAPIC_REG_SELECT              0x00
 165 #define IOSAPIC_REG_WINDOW              0x10
 166 #define IOSAPIC_REG_EOI                 0x40
 167 
 168 #define IOSAPIC_REG_VERSION             0x1
 169 
 170 #define IOSAPIC_IRDT_ENTRY(idx)         (0x10+(idx)*2)
 171 #define IOSAPIC_IRDT_ENTRY_HI(idx)      (0x11+(idx)*2)
 172 
 173 static inline unsigned int iosapic_read(void __iomem *iosapic, unsigned int reg)
 174 {
 175         writel(reg, iosapic + IOSAPIC_REG_SELECT);
 176         return readl(iosapic + IOSAPIC_REG_WINDOW);
 177 }
 178 
 179 static inline void iosapic_write(void __iomem *iosapic, unsigned int reg, u32 val)
 180 {
 181         writel(reg, iosapic + IOSAPIC_REG_SELECT);
 182         writel(val, iosapic + IOSAPIC_REG_WINDOW);
 183 }
 184 
 185 #define IOSAPIC_VERSION_MASK    0x000000ff
 186 #define IOSAPIC_VERSION(ver)    ((int) (ver & IOSAPIC_VERSION_MASK))
 187 
 188 #define IOSAPIC_MAX_ENTRY_MASK          0x00ff0000
 189 #define IOSAPIC_MAX_ENTRY_SHIFT         0x10
 190 #define IOSAPIC_IRDT_MAX_ENTRY(ver)     \
 191         (int) (((ver) & IOSAPIC_MAX_ENTRY_MASK) >> IOSAPIC_MAX_ENTRY_SHIFT)
 192 
 193 /* bits in the "low" I/O Sapic IRdT entry */
 194 #define IOSAPIC_IRDT_ENABLE       0x10000
 195 #define IOSAPIC_IRDT_PO_LOW       0x02000
 196 #define IOSAPIC_IRDT_LEVEL_TRIG   0x08000
 197 #define IOSAPIC_IRDT_MODE_LPRI    0x00100
 198 
 199 /* bits in the "high" I/O Sapic IRdT entry */
 200 #define IOSAPIC_IRDT_ID_EID_SHIFT              0x10
 201 
 202 
 203 static DEFINE_SPINLOCK(iosapic_lock);
 204 
 205 static inline void iosapic_eoi(void __iomem *addr, unsigned int data)
 206 {
 207         __raw_writel(data, addr);
 208 }
 209 
 210 /*
 211 ** REVISIT: future platforms may have more than one IRT.
 212 ** If so, the following three fields form a structure which
 213 ** then be linked into a list. Names are chosen to make searching
 214 ** for them easy - not necessarily accurate (eg "cell").
 215 **
 216 ** Alternative: iosapic_info could point to the IRT it's in.
 217 ** iosapic_register() could search a list of IRT's.
 218 */
 219 static struct irt_entry *irt_cell;
 220 static size_t irt_num_entry;
 221 
 222 static struct irt_entry *iosapic_alloc_irt(int num_entries)
 223 {
 224         unsigned long a;
 225 
 226         /* The IRT needs to be 8-byte aligned for the PDC call. 
 227          * Normally kmalloc would guarantee larger alignment, but
 228          * if CONFIG_DEBUG_SLAB is enabled, then we can get only
 229          * 4-byte alignment on 32-bit kernels
 230          */
 231         a = (unsigned long)kmalloc(sizeof(struct irt_entry) * num_entries + 8, GFP_KERNEL);
 232         a = (a + 7UL) & ~7UL;
 233         return (struct irt_entry *)a;
 234 }
 235 
 236 /**
 237  * iosapic_load_irt - Fill in the interrupt routing table
 238  * @cell_num: The cell number of the CPU we're currently executing on
 239  * @irt: The address to place the new IRT at
 240  * @return The number of entries found
 241  *
 242  * The "Get PCI INT Routing Table Size" option returns the number of 
 243  * entries in the PCI interrupt routing table for the cell specified 
 244  * in the cell_number argument.  The cell number must be for a cell 
 245  * within the caller's protection domain.
 246  *
 247  * The "Get PCI INT Routing Table" option returns, for the cell 
 248  * specified in the cell_number argument, the PCI interrupt routing 
 249  * table in the caller allocated memory pointed to by mem_addr.
 250  * We assume the IRT only contains entries for I/O SAPIC and
 251  * calculate the size based on the size of I/O sapic entries.
 252  *
 253  * The PCI interrupt routing table entry format is derived from the
 254  * IA64 SAL Specification 2.4.   The PCI interrupt routing table defines
 255  * the routing of PCI interrupt signals between the PCI device output
 256  * "pins" and the IO SAPICs' input "lines" (including core I/O PCI
 257  * devices).  This table does NOT include information for devices/slots
 258  * behind PCI to PCI bridges. See PCI to PCI Bridge Architecture Spec.
 259  * for the architected method of routing of IRQ's behind PPB's.
 260  */
 261 
 262 
 263 static int __init
 264 iosapic_load_irt(unsigned long cell_num, struct irt_entry **irt)
 265 {
 266         long status;              /* PDC return value status */
 267         struct irt_entry *table;  /* start of interrupt routing tbl */
 268         unsigned long num_entries = 0UL;
 269 
 270         BUG_ON(!irt);
 271 
 272         if (is_pdc_pat()) {
 273                 /* Use pat pdc routine to get interrupt routing table size */
 274                 DBG("calling get_irt_size (cell %ld)\n", cell_num);
 275                 status = pdc_pat_get_irt_size(&num_entries, cell_num);
 276                 DBG("get_irt_size: %ld\n", status);
 277 
 278                 BUG_ON(status != PDC_OK);
 279                 BUG_ON(num_entries == 0);
 280 
 281                 /*
 282                 ** allocate memory for interrupt routing table
 283                 ** This interface isn't really right. We are assuming
 284                 ** the contents of the table are exclusively
 285                 ** for I/O sapic devices.
 286                 */
 287                 table = iosapic_alloc_irt(num_entries);
 288                 if (table == NULL) {
 289                         printk(KERN_WARNING MODULE_NAME ": read_irt : can "
 290                                         "not alloc mem for IRT\n");
 291                         return 0;
 292                 }
 293 
 294                 /* get PCI INT routing table */
 295                 status = pdc_pat_get_irt(table, cell_num);
 296                 DBG("pdc_pat_get_irt: %ld\n", status);
 297                 WARN_ON(status != PDC_OK);
 298         } else {
 299                 /*
 300                 ** C3000/J5000 (and similar) platforms with Sprockets PDC
 301                 ** will return exactly one IRT for all iosapics.
 302                 ** So if we have one, don't need to get it again.
 303                 */
 304                 if (irt_cell)
 305                         return 0;
 306 
 307                 /* Should be using the Elroy's HPA, but it's ignored anyway */
 308                 status = pdc_pci_irt_size(&num_entries, 0);
 309                 DBG("pdc_pci_irt_size: %ld\n", status);
 310 
 311                 if (status != PDC_OK) {
 312                         /* Not a "legacy" system with I/O SAPIC either */
 313                         return 0;
 314                 }
 315 
 316                 BUG_ON(num_entries == 0);
 317 
 318                 table = iosapic_alloc_irt(num_entries);
 319                 if (!table) {
 320                         printk(KERN_WARNING MODULE_NAME ": read_irt : can "
 321                                         "not alloc mem for IRT\n");
 322                         return 0;
 323                 }
 324 
 325                 /* HPA ignored by this call too. */
 326                 status = pdc_pci_irt(num_entries, 0, table);
 327                 BUG_ON(status != PDC_OK);
 328         }
 329 
 330         /* return interrupt table address */
 331         *irt = table;
 332 
 333 #ifdef DEBUG_IOSAPIC_IRT
 334 {
 335         struct irt_entry *p = table;
 336         int i;
 337 
 338         printk(MODULE_NAME " Interrupt Routing Table (cell %ld)\n", cell_num);
 339         printk(MODULE_NAME " start = 0x%p num_entries %ld entry_size %d\n",
 340                 table,
 341                 num_entries,
 342                 (int) sizeof(struct irt_entry));
 343 
 344         for (i = 0 ; i < num_entries ; i++, p++) {
 345                 printk(MODULE_NAME " %02x %02x %02x %02x %02x %02x %02x %02x %08x%08x\n",
 346                 p->entry_type, p->entry_length, p->interrupt_type,
 347                 p->polarity_trigger, p->src_bus_irq_devno, p->src_bus_id,
 348                 p->src_seg_id, p->dest_iosapic_intin,
 349                 ((u32 *) p)[2],
 350                 ((u32 *) p)[3]
 351                 );
 352         }
 353 }
 354 #endif /* DEBUG_IOSAPIC_IRT */
 355 
 356         return num_entries;
 357 }
 358 
 359 
 360 
 361 void __init iosapic_init(void)
 362 {
 363         unsigned long cell = 0;
 364 
 365         DBG("iosapic_init()\n");
 366 
 367 #ifdef __LP64__
 368         if (is_pdc_pat()) {
 369                 int status;
 370                 struct pdc_pat_cell_num cell_info;
 371 
 372                 status = pdc_pat_cell_get_number(&cell_info);
 373                 if (status == PDC_OK) {
 374                         cell = cell_info.cell_num;
 375                 }
 376         }
 377 #endif
 378 
 379         /* get interrupt routing table for this cell */
 380         irt_num_entry = iosapic_load_irt(cell, &irt_cell);
 381         if (irt_num_entry == 0)
 382                 irt_cell = NULL;        /* old PDC w/o iosapic */
 383 }
 384 
 385 
 386 /*
 387 ** Return the IRT entry in case we need to look something else up.
 388 */
 389 static struct irt_entry *
 390 irt_find_irqline(struct iosapic_info *isi, u8 slot, u8 intr_pin)
 391 {
 392         struct irt_entry *i = irt_cell;
 393         int cnt;        /* track how many entries we've looked at */
 394         u8 irq_devno = (slot << IRT_DEV_SHIFT) | (intr_pin-1);
 395 
 396         DBG_IRT("irt_find_irqline() SLOT %d pin %d\n", slot, intr_pin);
 397 
 398         for (cnt=0; cnt < irt_num_entry; cnt++, i++) {
 399 
 400                 /*
 401                 ** Validate: entry_type, entry_length, interrupt_type
 402                 **
 403                 ** Difference between validate vs compare is the former
 404                 ** should print debug info and is not expected to "fail"
 405                 ** on current platforms.
 406                 */
 407                 if (i->entry_type != IRT_IOSAPIC_TYPE) {
 408                         DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry %d type %d\n", i, cnt, i->entry_type);
 409                         continue;
 410                 }
 411                 
 412                 if (i->entry_length != IRT_IOSAPIC_LENGTH) {
 413                         DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry %d  length %d\n", i, cnt, i->entry_length);
 414                         continue;
 415                 }
 416 
 417                 if (i->interrupt_type != IRT_VECTORED_INTR) {
 418                         DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry  %d interrupt_type %d\n", i, cnt, i->interrupt_type);
 419                         continue;
 420                 }
 421 
 422                 if (!COMPARE_IRTE_ADDR(i, isi->isi_hpa))
 423                         continue;
 424 
 425                 if ((i->src_bus_irq_devno & IRT_IRQ_DEVNO_MASK) != irq_devno)
 426                         continue;
 427 
 428                 /*
 429                 ** Ignore: src_bus_id and rc_seg_id correlate with
 430                 **         iosapic_info->isi_hpa on HP platforms.
 431                 **         If needed, pass in "PFA" (aka config space addr)
 432                 **         instead of slot.
 433                 */
 434 
 435                 /* Found it! */
 436                 return i;
 437         }
 438 
 439         printk(KERN_WARNING MODULE_NAME ": 0x%lx : no IRT entry for slot %d, pin %d\n",
 440                         isi->isi_hpa, slot, intr_pin);
 441         return NULL;
 442 }
 443 
 444 
 445 /*
 446 ** xlate_pin() supports the skewing of IRQ lines done by subsidiary bridges.
 447 ** Legacy PDC already does this translation for us and stores it in INTR_LINE.
 448 **
 449 ** PAT PDC needs to basically do what legacy PDC does:
 450 ** o read PIN
 451 ** o adjust PIN in case device is "behind" a PPB
 452 **     (eg 4-port 100BT and SCSI/LAN "Combo Card")
 453 ** o convert slot/pin to I/O SAPIC input line.
 454 **
 455 ** HP platforms only support:
 456 ** o one level of skewing for any number of PPBs
 457 ** o only support PCI-PCI Bridges.
 458 */
 459 static struct irt_entry *
 460 iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev)
 461 {
 462         u8 intr_pin, intr_slot;
 463 
 464         pci_read_config_byte(pcidev, PCI_INTERRUPT_PIN, &intr_pin);
 465 
 466         DBG_IRT("iosapic_xlate_pin(%s) SLOT %d pin %d\n",
 467                 pcidev->slot_name, PCI_SLOT(pcidev->devfn), intr_pin);
 468 
 469         if (intr_pin == 0) {
 470                 /* The device does NOT support/use IRQ lines.  */
 471                 return NULL;
 472         }
 473 
 474         /* Check if pcidev behind a PPB */
 475         if (pcidev->bus->parent) {
 476                 /* Convert pcidev INTR_PIN into something we
 477                 ** can lookup in the IRT.
 478                 */
 479 #ifdef PCI_BRIDGE_FUNCS
 480                 /*
 481                 ** Proposal #1:
 482                 **
 483                 ** call implementation specific translation function
 484                 ** This is architecturally "cleaner". HP-UX doesn't
 485                 ** support other secondary bus types (eg. E/ISA) directly.
 486                 ** May be needed for other processor (eg IA64) architectures
 487                 ** or by some ambitous soul who wants to watch TV.
 488                 */
 489                 if (pci_bridge_funcs->xlate_intr_line) {
 490                         intr_pin = pci_bridge_funcs->xlate_intr_line(pcidev);
 491                 }
 492 #else   /* PCI_BRIDGE_FUNCS */
 493                 struct pci_bus *p = pcidev->bus;
 494                 /*
 495                 ** Proposal #2:
 496                 ** The "pin" is skewed ((pin + dev - 1) % 4).
 497                 **
 498                 ** This isn't very clean since I/O SAPIC must assume:
 499                 **   - all platforms only have PCI busses.
 500                 **   - only PCI-PCI bridge (eg not PCI-EISA, PCI-PCMCIA)
 501                 **   - IRQ routing is only skewed once regardless of
 502                 **     the number of PPB's between iosapic and device.
 503                 **     (Bit3 expansion chassis follows this rule)
 504                 **
 505                 ** Advantage is it's really easy to implement.
 506                 */
 507                 intr_pin = pci_swizzle_interrupt_pin(pcidev, intr_pin);
 508 #endif /* PCI_BRIDGE_FUNCS */
 509 
 510                 /*
 511                  * Locate the host slot of the PPB.
 512                  */
 513                 while (p->parent->parent)
 514                         p = p->parent;
 515 
 516                 intr_slot = PCI_SLOT(p->self->devfn);
 517         } else {
 518                 intr_slot = PCI_SLOT(pcidev->devfn);
 519         }
 520         DBG_IRT("iosapic_xlate_pin:  bus %d slot %d pin %d\n",
 521                         pcidev->bus->busn_res.start, intr_slot, intr_pin);
 522 
 523         return irt_find_irqline(isi, intr_slot, intr_pin);
 524 }
 525 
 526 static void iosapic_rd_irt_entry(struct vector_info *vi , u32 *dp0, u32 *dp1)
 527 {
 528         struct iosapic_info *isp = vi->iosapic;
 529         u8 idx = vi->irqline;
 530 
 531         *dp0 = iosapic_read(isp->addr, IOSAPIC_IRDT_ENTRY(idx));
 532         *dp1 = iosapic_read(isp->addr, IOSAPIC_IRDT_ENTRY_HI(idx));
 533 }
 534 
 535 
 536 static void iosapic_wr_irt_entry(struct vector_info *vi, u32 dp0, u32 dp1)
 537 {
 538         struct iosapic_info *isp = vi->iosapic;
 539 
 540         DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %lx 0x%x 0x%x\n",
 541                 vi->irqline, isp->isi_hpa, dp0, dp1);
 542 
 543         iosapic_write(isp->addr, IOSAPIC_IRDT_ENTRY(vi->irqline), dp0);
 544 
 545         /* Read the window register to flush the writes down to HW  */
 546         dp0 = readl(isp->addr+IOSAPIC_REG_WINDOW);
 547 
 548         iosapic_write(isp->addr, IOSAPIC_IRDT_ENTRY_HI(vi->irqline), dp1);
 549 
 550         /* Read the window register to flush the writes down to HW  */
 551         dp1 = readl(isp->addr+IOSAPIC_REG_WINDOW);
 552 }
 553 
 554 /*
 555 ** set_irt prepares the data (dp0, dp1) according to the vector_info
 556 ** and target cpu (id_eid).  dp0/dp1 are then used to program I/O SAPIC
 557 ** IRdT for the given "vector" (aka IRQ line).
 558 */
 559 static void
 560 iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1)
 561 {
 562         u32 mode = 0;
 563         struct irt_entry *p = vi->irte;
 564 
 565         if ((p->polarity_trigger & IRT_PO_MASK) == IRT_ACTIVE_LO)
 566                 mode |= IOSAPIC_IRDT_PO_LOW;
 567 
 568         if (((p->polarity_trigger >> IRT_EL_SHIFT) & IRT_EL_MASK) == IRT_LEVEL_TRIG)
 569                 mode |= IOSAPIC_IRDT_LEVEL_TRIG;
 570 
 571         /*
 572         ** IA64 REVISIT
 573         ** PA doesn't support EXTINT or LPRIO bits.
 574         */
 575 
 576         *dp0 = mode | (u32) vi->txn_data;
 577 
 578         /*
 579         ** Extracting id_eid isn't a real clean way of getting it.
 580         ** But the encoding is the same for both PA and IA64 platforms.
 581         */
 582         if (is_pdc_pat()) {
 583                 /*
 584                 ** PAT PDC just hands it to us "right".
 585                 ** txn_addr comes from cpu_data[x].txn_addr.
 586                 */
 587                 *dp1 = (u32) (vi->txn_addr);
 588         } else {
 589                 /* 
 590                 ** eg if base_addr == 0xfffa0000),
 591                 **    we want to get 0xa0ff0000.
 592                 **
 593                 ** eid  0x0ff00000 -> 0x00ff0000
 594                 ** id   0x000ff000 -> 0xff000000
 595                 */
 596                 *dp1 = (((u32)vi->txn_addr & 0x0ff00000) >> 4) |
 597                         (((u32)vi->txn_addr & 0x000ff000) << 12);
 598         }
 599         DBG_IRT("iosapic_set_irt_data(): 0x%x 0x%x\n", *dp0, *dp1);
 600 }
 601 
 602 
 603 static void iosapic_mask_irq(struct irq_data *d)
 604 {
 605         unsigned long flags;
 606         struct vector_info *vi = irq_data_get_irq_chip_data(d);
 607         u32 d0, d1;
 608 
 609         spin_lock_irqsave(&iosapic_lock, flags);
 610         iosapic_rd_irt_entry(vi, &d0, &d1);
 611         d0 |= IOSAPIC_IRDT_ENABLE;
 612         iosapic_wr_irt_entry(vi, d0, d1);
 613         spin_unlock_irqrestore(&iosapic_lock, flags);
 614 }
 615 
 616 static void iosapic_unmask_irq(struct irq_data *d)
 617 {
 618         struct vector_info *vi = irq_data_get_irq_chip_data(d);
 619         u32 d0, d1;
 620 
 621         /* data is initialized by fixup_irq */
 622         WARN_ON(vi->txn_irq  == 0);
 623 
 624         iosapic_set_irt_data(vi, &d0, &d1);
 625         iosapic_wr_irt_entry(vi, d0, d1);
 626 
 627 #ifdef DEBUG_IOSAPIC_IRT
 628 {
 629         u32 *t = (u32 *) ((ulong) vi->eoi_addr & ~0xffUL);
 630         printk("iosapic_enable_irq(): regs %p", vi->eoi_addr);
 631         for ( ; t < vi->eoi_addr; t++)
 632                 printk(" %x", readl(t));
 633         printk("\n");
 634 }
 635 
 636 printk("iosapic_enable_irq(): sel ");
 637 {
 638         struct iosapic_info *isp = vi->iosapic;
 639 
 640         for (d0=0x10; d0<0x1e; d0++) {
 641                 d1 = iosapic_read(isp->addr, d0);
 642                 printk(" %x", d1);
 643         }
 644 }
 645 printk("\n");
 646 #endif
 647 
 648         /*
 649          * Issuing I/O SAPIC an EOI causes an interrupt IFF IRQ line is
 650          * asserted.  IRQ generally should not be asserted when a driver
 651          * enables their IRQ. It can lead to "interesting" race conditions
 652          * in the driver initialization sequence.
 653          */
 654         DBG(KERN_DEBUG "enable_irq(%d): eoi(%p, 0x%x)\n", d->irq,
 655                         vi->eoi_addr, vi->eoi_data);
 656         iosapic_eoi(vi->eoi_addr, vi->eoi_data);
 657 }
 658 
 659 static void iosapic_eoi_irq(struct irq_data *d)
 660 {
 661         struct vector_info *vi = irq_data_get_irq_chip_data(d);
 662 
 663         iosapic_eoi(vi->eoi_addr, vi->eoi_data);
 664         cpu_eoi_irq(d);
 665 }
 666 
 667 #ifdef CONFIG_SMP
 668 static int iosapic_set_affinity_irq(struct irq_data *d,
 669                                     const struct cpumask *dest, bool force)
 670 {
 671         struct vector_info *vi = irq_data_get_irq_chip_data(d);
 672         u32 d0, d1, dummy_d0;
 673         unsigned long flags;
 674         int dest_cpu;
 675 
 676         dest_cpu = cpu_check_affinity(d, dest);
 677         if (dest_cpu < 0)
 678                 return -1;
 679 
 680         cpumask_copy(irq_data_get_affinity_mask(d), cpumask_of(dest_cpu));
 681         vi->txn_addr = txn_affinity_addr(d->irq, dest_cpu);
 682 
 683         spin_lock_irqsave(&iosapic_lock, flags);
 684         /* d1 contains the destination CPU, so only want to set that
 685          * entry */
 686         iosapic_rd_irt_entry(vi, &d0, &d1);
 687         iosapic_set_irt_data(vi, &dummy_d0, &d1);
 688         iosapic_wr_irt_entry(vi, d0, d1);
 689         spin_unlock_irqrestore(&iosapic_lock, flags);
 690 
 691         return 0;
 692 }
 693 #endif
 694 
 695 static struct irq_chip iosapic_interrupt_type = {
 696         .name           =       "IO-SAPIC-level",
 697         .irq_unmask     =       iosapic_unmask_irq,
 698         .irq_mask       =       iosapic_mask_irq,
 699         .irq_ack        =       cpu_ack_irq,
 700         .irq_eoi        =       iosapic_eoi_irq,
 701 #ifdef CONFIG_SMP
 702         .irq_set_affinity =     iosapic_set_affinity_irq,
 703 #endif
 704 };
 705 
 706 int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
 707 {
 708         struct iosapic_info *isi = isi_obj;
 709         struct irt_entry *irte = NULL;  /* only used if PAT PDC */
 710         struct vector_info *vi;
 711         int isi_line;   /* line used by device */
 712 
 713         if (!isi) {
 714                 printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
 715                         pci_name(pcidev));
 716                 return -1;
 717         }
 718 
 719 #ifdef CONFIG_SUPERIO
 720         /*
 721          * HACK ALERT! (non-compliant PCI device support)
 722          *
 723          * All SuckyIO interrupts are routed through the PIC's on function 1.
 724          * But SuckyIO OHCI USB controller gets an IRT entry anyway because
 725          * it advertises INT D for INT_PIN.  Use that IRT entry to get the
 726          * SuckyIO interrupt routing for PICs on function 1 (*BLEECCHH*).
 727          */
 728         if (is_superio_device(pcidev)) {
 729                 /* We must call superio_fixup_irq() to register the pdev */
 730                 pcidev->irq = superio_fixup_irq(pcidev);
 731 
 732                 /* Don't return if need to program the IOSAPIC's IRT... */
 733                 if (PCI_FUNC(pcidev->devfn) != SUPERIO_USB_FN)
 734                         return pcidev->irq;
 735         }
 736 #endif /* CONFIG_SUPERIO */
 737 
 738         /* lookup IRT entry for isi/slot/pin set */
 739         irte = iosapic_xlate_pin(isi, pcidev);
 740         if (!irte) {
 741                 printk("iosapic: no IRTE for %s (IRQ not connected?)\n",
 742                                 pci_name(pcidev));
 743                 return -1;
 744         }
 745         DBG_IRT("iosapic_fixup_irq(): irte %p %x %x %x %x %x %x %x %x\n",
 746                 irte,
 747                 irte->entry_type,
 748                 irte->entry_length,
 749                 irte->polarity_trigger,
 750                 irte->src_bus_irq_devno,
 751                 irte->src_bus_id,
 752                 irte->src_seg_id,
 753                 irte->dest_iosapic_intin,
 754                 (u32) irte->dest_iosapic_addr);
 755         isi_line = irte->dest_iosapic_intin;
 756 
 757         /* get vector info for this input line */
 758         vi = isi->isi_vector + isi_line;
 759         DBG_IRT("iosapic_fixup_irq:  line %d vi 0x%p\n", isi_line, vi);
 760 
 761         /* If this IRQ line has already been setup, skip it */
 762         if (vi->irte)
 763                 goto out;
 764 
 765         vi->irte = irte;
 766 
 767         /*
 768          * Allocate processor IRQ
 769          *
 770          * XXX/FIXME The txn_alloc_irq() code and related code should be
 771          * moved to enable_irq(). That way we only allocate processor IRQ
 772          * bits for devices that actually have drivers claiming them.
 773          * Right now we assign an IRQ to every PCI device present,
 774          * regardless of whether it's used or not.
 775          */
 776         vi->txn_irq = txn_alloc_irq(8);
 777 
 778         if (vi->txn_irq < 0)
 779                 panic("I/O sapic: couldn't get TXN IRQ\n");
 780 
 781         /* enable_irq() will use txn_* to program IRdT */
 782         vi->txn_addr = txn_alloc_addr(vi->txn_irq);
 783         vi->txn_data = txn_alloc_data(vi->txn_irq);
 784 
 785         vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI;
 786         vi->eoi_data = cpu_to_le32(vi->txn_data);
 787 
 788         cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi);
 789 
 790  out:
 791         pcidev->irq = vi->txn_irq;
 792 
 793         DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
 794                 PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->devfn),
 795                 pcidev->vendor, pcidev->device, isi_line, pcidev->irq);
 796 
 797         return pcidev->irq;
 798 }
 799 
 800 static struct iosapic_info *iosapic_list;
 801 
 802 #ifdef CONFIG_64BIT
 803 int iosapic_serial_irq(struct parisc_device *dev)
 804 {
 805         struct iosapic_info *isi;
 806         struct irt_entry *irte;
 807         struct vector_info *vi;
 808         int cnt;
 809         int intin;
 810 
 811         intin = (dev->mod_info >> 24) & 15;
 812 
 813         /* lookup IRT entry for isi/slot/pin set */
 814         for (cnt = 0; cnt < irt_num_entry; cnt++) {
 815                 irte = &irt_cell[cnt];
 816                 if (COMPARE_IRTE_ADDR(irte, dev->mod0) &&
 817                     irte->dest_iosapic_intin == intin)
 818                         break;
 819         }
 820         if (cnt >= irt_num_entry)
 821                 return 0; /* no irq found, force polling */
 822 
 823         DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n",
 824                 irte,
 825                 irte->entry_type,
 826                 irte->entry_length,
 827                 irte->polarity_trigger,
 828                 irte->src_bus_irq_devno,
 829                 irte->src_bus_id,
 830                 irte->src_seg_id,
 831                 irte->dest_iosapic_intin,
 832                 (u32) irte->dest_iosapic_addr);
 833 
 834         /* search for iosapic */
 835         for (isi = iosapic_list; isi; isi = isi->isi_next)
 836                 if (isi->isi_hpa == dev->mod0)
 837                         break;
 838         if (!isi)
 839                 return 0; /* no iosapic found, force polling */
 840 
 841         /* get vector info for this input line */
 842         vi = isi->isi_vector + intin;
 843         DBG_IRT("iosapic_serial_irq:  line %d vi 0x%p\n", iosapic_intin, vi);
 844 
 845         /* If this IRQ line has already been setup, skip it */
 846         if (vi->irte)
 847                 goto out;
 848 
 849         vi->irte = irte;
 850 
 851         /*
 852          * Allocate processor IRQ
 853          *
 854          * XXX/FIXME The txn_alloc_irq() code and related code should be
 855          * moved to enable_irq(). That way we only allocate processor IRQ
 856          * bits for devices that actually have drivers claiming them.
 857          * Right now we assign an IRQ to every PCI device present,
 858          * regardless of whether it's used or not.
 859          */
 860         vi->txn_irq = txn_alloc_irq(8);
 861 
 862         if (vi->txn_irq < 0)
 863                 panic("I/O sapic: couldn't get TXN IRQ\n");
 864 
 865         /* enable_irq() will use txn_* to program IRdT */
 866         vi->txn_addr = txn_alloc_addr(vi->txn_irq);
 867         vi->txn_data = txn_alloc_data(vi->txn_irq);
 868 
 869         vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI;
 870         vi->eoi_data = cpu_to_le32(vi->txn_data);
 871 
 872         cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi);
 873 
 874  out:
 875 
 876         return vi->txn_irq;
 877 }
 878 #endif
 879 
 880 
 881 /*
 882 ** squirrel away the I/O Sapic Version
 883 */
 884 static unsigned int
 885 iosapic_rd_version(struct iosapic_info *isi)
 886 {
 887         return iosapic_read(isi->addr, IOSAPIC_REG_VERSION);
 888 }
 889 
 890 
 891 /*
 892 ** iosapic_register() is called by "drivers" with an integrated I/O SAPIC.
 893 ** Caller must be certain they have an I/O SAPIC and know its MMIO address.
 894 **
 895 **      o allocate iosapic_info and add it to the list
 896 **      o read iosapic version and squirrel that away
 897 **      o read size of IRdT.
 898 **      o allocate and initialize isi_vector[]
 899 **      o allocate irq region
 900 */
 901 void *iosapic_register(unsigned long hpa)
 902 {
 903         struct iosapic_info *isi = NULL;
 904         struct irt_entry *irte = irt_cell;
 905         struct vector_info *vip;
 906         int cnt;        /* track how many entries we've looked at */
 907 
 908         /*
 909          * Astro based platforms can only support PCI OLARD if they implement
 910          * PAT PDC.  Legacy PDC omits LBAs with no PCI devices from the IRT.
 911          * Search the IRT and ignore iosapic's which aren't in the IRT.
 912          */
 913         for (cnt=0; cnt < irt_num_entry; cnt++, irte++) {
 914                 WARN_ON(IRT_IOSAPIC_TYPE != irte->entry_type);
 915                 if (COMPARE_IRTE_ADDR(irte, hpa))
 916                         break;
 917         }
 918 
 919         if (cnt >= irt_num_entry) {
 920                 DBG("iosapic_register() ignoring 0x%lx (NOT FOUND)\n", hpa);
 921                 return NULL;
 922         }
 923 
 924         isi = kzalloc(sizeof(struct iosapic_info), GFP_KERNEL);
 925         if (!isi) {
 926                 BUG();
 927                 return NULL;
 928         }
 929 
 930         isi->addr = ioremap_nocache(hpa, 4096);
 931         isi->isi_hpa = hpa;
 932         isi->isi_version = iosapic_rd_version(isi);
 933         isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1;
 934 
 935         vip = isi->isi_vector = kcalloc(isi->isi_num_vectors,
 936                                         sizeof(struct vector_info), GFP_KERNEL);
 937         if (vip == NULL) {
 938                 kfree(isi);
 939                 return NULL;
 940         }
 941 
 942         for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) {
 943                 vip->irqline = (unsigned char) cnt;
 944                 vip->iosapic = isi;
 945         }
 946         isi->isi_next = iosapic_list;
 947         iosapic_list = isi;
 948         return isi;
 949 }
 950 
 951 
 952 #ifdef DEBUG_IOSAPIC
 953 
 954 static void
 955 iosapic_prt_irt(void *irt, long num_entry)
 956 {
 957         unsigned int i, *irp = (unsigned int *) irt;
 958 
 959 
 960         printk(KERN_DEBUG MODULE_NAME ": Interrupt Routing Table (%lx entries)\n", num_entry);
 961 
 962         for (i=0; i<num_entry; i++, irp += 4) {
 963                 printk(KERN_DEBUG "%p : %2d %.8x %.8x %.8x %.8x\n",
 964                                         irp, i, irp[0], irp[1], irp[2], irp[3]);
 965         }
 966 }
 967 
 968 
 969 static void
 970 iosapic_prt_vi(struct vector_info *vi)
 971 {
 972         printk(KERN_DEBUG MODULE_NAME ": vector_info[%d] is at %p\n", vi->irqline, vi);
 973         printk(KERN_DEBUG "\t\tstatus:   %.4x\n", vi->status);
 974         printk(KERN_DEBUG "\t\ttxn_irq:  %d\n",  vi->txn_irq);
 975         printk(KERN_DEBUG "\t\ttxn_addr: %lx\n", vi->txn_addr);
 976         printk(KERN_DEBUG "\t\ttxn_data: %lx\n", vi->txn_data);
 977         printk(KERN_DEBUG "\t\teoi_addr: %p\n",  vi->eoi_addr);
 978         printk(KERN_DEBUG "\t\teoi_data: %x\n",  vi->eoi_data);
 979 }
 980 
 981 
 982 static void
 983 iosapic_prt_isi(struct iosapic_info *isi)
 984 {
 985         printk(KERN_DEBUG MODULE_NAME ": io_sapic_info at %p\n", isi);
 986         printk(KERN_DEBUG "\t\tisi_hpa:       %lx\n", isi->isi_hpa);
 987         printk(KERN_DEBUG "\t\tisi_status:    %x\n", isi->isi_status);
 988         printk(KERN_DEBUG "\t\tisi_version:   %x\n", isi->isi_version);
 989         printk(KERN_DEBUG "\t\tisi_vector:    %p\n", isi->isi_vector);
 990 }
 991 #endif /* DEBUG_IOSAPIC */

/* [<][>][^][v][top][bottom][index][help] */