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