^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2005-2009, 2010 Cavium Networks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/msi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <asm/octeon/octeon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/octeon/cvmx-npi-defs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/octeon/cvmx-pci-defs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/octeon/cvmx-npei-defs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/octeon/cvmx-sli-defs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <asm/octeon/cvmx-pexp-defs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/octeon/pci-octeon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Each bit in msi_free_irq_bitmask represents a MSI interrupt that is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * in use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static u64 msi_free_irq_bitmask[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Each bit in msi_multiple_irq_bitmask tells that the device using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * this bit in msi_free_irq_bitmask is also using the next bit. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * is used so we can disable all of the MSI interrupts when a device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * uses multiple.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static u64 msi_multiple_irq_bitmask[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * This lock controls updates to msi_free_irq_bitmask and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * msi_multiple_irq_bitmask.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static DEFINE_SPINLOCK(msi_free_irq_bitmask_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * Number of MSI IRQs used. This variable is set up in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * the module init time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int msi_irq_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Called when a driver request MSI interrupts instead of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * legacy INT A-D. This routine will allocate multiple interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * for MSI devices that support them. A device can override this by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * programming the MSI control bits [6:4] before calling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * pci_enable_msi().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * @dev: Device requesting MSI interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * @desc: MSI descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Returns 0 on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct msi_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u16 control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int configured_private_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int request_private_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int irq_step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) u64 search_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * Read the MSI config to figure out how many IRQs this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * wants. Most devices only want 1, which will give
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * configured_private_bits and request_private_bits equal 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * If the number of private bits has been configured then use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * that value instead of the requested number. This gives the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * driver the chance to override the number of interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * before calling pci_enable_msi().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) configured_private_bits = (control & PCI_MSI_FLAGS_QSIZE) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (configured_private_bits == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /* Nothing is configured, so use the hardware requested size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) request_private_bits = (control & PCI_MSI_FLAGS_QMASK) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Use the number of configured bits, assuming the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * driver wanted to override the hardware request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) request_private_bits = configured_private_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * The PCI 2.3 spec mandates that there are at most 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * interrupts. If this device asks for more, only give it one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (request_private_bits > 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) request_private_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) try_only_one:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * The IRQs have to be aligned on a power of two based on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * number being requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) irq_step = 1 << request_private_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* Mask with one bit for each IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) search_mask = (1 << irq_step) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * We're going to search msi_free_irq_bitmask_lock for zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * bits. This represents an MSI interrupt number that isn't in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) spin_lock(&msi_free_irq_bitmask_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) for (index = 0; index < msi_irq_size/64; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) for (irq = 0; irq < 64; irq += irq_step) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if ((msi_free_irq_bitmask[index] & (search_mask << irq)) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) msi_free_irq_bitmask[index] |= search_mask << irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) msi_multiple_irq_bitmask[index] |= (search_mask >> 1) << irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) goto msi_irq_allocated;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) msi_irq_allocated:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) spin_unlock(&msi_free_irq_bitmask_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Make sure the search for available interrupts didn't fail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (irq >= 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (request_private_bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) pr_err("arch_setup_msi_irq: Unable to find %d free interrupts, trying just one",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 1 << request_private_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) request_private_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) goto try_only_one;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) panic("arch_setup_msi_irq: Unable to find a free MSI interrupt");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* MSI interrupts start at logical IRQ OCTEON_IRQ_MSI_BIT0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) irq += index*64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) irq += OCTEON_IRQ_MSI_BIT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) switch (octeon_dma_bar_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) case OCTEON_DMA_BAR_TYPE_SMALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* When not using big bar, Bar 0 is based at 128MB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) msg.address_lo =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ((128ul << 20) + CVMX_PCI_MSI_RCV) & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) msg.address_hi = ((128ul << 20) + CVMX_PCI_MSI_RCV) >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) case OCTEON_DMA_BAR_TYPE_BIG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* When using big bar, Bar 0 is based at 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) msg.address_lo = (0 + CVMX_PCI_MSI_RCV) & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) msg.address_hi = (0 + CVMX_PCI_MSI_RCV) >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case OCTEON_DMA_BAR_TYPE_PCIE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* When using PCIe, Bar 0 is based at 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* FIXME CVMX_NPEI_MSI_RCV* other than 0? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) msg.address_lo = (0 + CVMX_NPEI_PCIE_MSI_RCV) & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) msg.address_hi = (0 + CVMX_NPEI_PCIE_MSI_RCV) >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) case OCTEON_DMA_BAR_TYPE_PCIE2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* When using PCIe2, Bar 0 is based at 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) msg.address_lo = (0 + CVMX_SLI_PCIE_MSI_RCV) & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) msg.address_hi = (0 + CVMX_SLI_PCIE_MSI_RCV) >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) panic("arch_setup_msi_irq: Invalid octeon_dma_bar_type");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) msg.data = irq - OCTEON_IRQ_MSI_BIT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* Update the number of IRQs the device has available to it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) control &= ~PCI_MSI_FLAGS_QSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) control |= request_private_bits << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) irq_set_msi_desc(irq, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) pci_write_msi_msg(irq, &msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return 0;
^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) int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct msi_desc *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * MSI-X is not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (type == PCI_CAP_ID_MSIX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * If an architecture wants to support multiple MSI, it needs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * override arch_setup_msi_irqs()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (type == PCI_CAP_ID_MSI && nvec > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) for_each_pci_msi_entry(entry, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) ret = arch_setup_msi_irq(dev, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return -ENOSPC;
^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) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * Called when a device no longer needs its MSI interrupts. All
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * MSI interrupts for the device are freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * @irq: The devices first irq number. There may be multple in sequence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) void arch_teardown_msi_irq(unsigned int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) int number_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) u64 bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) int index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int irq0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if ((irq < OCTEON_IRQ_MSI_BIT0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) || (irq > msi_irq_size + OCTEON_IRQ_MSI_BIT0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) panic("arch_teardown_msi_irq: Attempted to teardown illegal "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) "MSI interrupt (%d)", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) irq -= OCTEON_IRQ_MSI_BIT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) index = irq / 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) irq0 = irq % 64;
^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) * Count the number of IRQs we need to free by looking at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * msi_multiple_irq_bitmask. Each bit set means that the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * IRQ is also owned by this device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) number_irqs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) while ((irq0 + number_irqs < 64) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) (msi_multiple_irq_bitmask[index]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) & (1ull << (irq0 + number_irqs))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) number_irqs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) number_irqs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* Mask with one bit for each IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) bitmask = (1 << number_irqs) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /* Shift the mask to the correct bit location */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) bitmask <<= irq0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if ((msi_free_irq_bitmask[index] & bitmask) != bitmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) panic("arch_teardown_msi_irq: Attempted to teardown MSI "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) "interrupt (%d) not in use", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /* Checks are done, update the in use bitmask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) spin_lock(&msi_free_irq_bitmask_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) msi_free_irq_bitmask[index] &= ~bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) msi_multiple_irq_bitmask[index] &= ~bitmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) spin_unlock(&msi_free_irq_bitmask_lock);
^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) static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static u64 msi_rcv_reg[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static u64 mis_ena_reg[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static void octeon_irq_msi_enable_pcie(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u64 en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int msi_number = data->irq - OCTEON_IRQ_MSI_BIT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) int irq_index = msi_number >> 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int irq_bit = msi_number & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) en = cvmx_read_csr(mis_ena_reg[irq_index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) en |= 1ull << irq_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) cvmx_write_csr(mis_ena_reg[irq_index], en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) cvmx_read_csr(mis_ena_reg[irq_index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static void octeon_irq_msi_disable_pcie(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) u64 en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) int msi_number = data->irq - OCTEON_IRQ_MSI_BIT0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) int irq_index = msi_number >> 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int irq_bit = msi_number & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) raw_spin_lock_irqsave(&octeon_irq_msi_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) en = cvmx_read_csr(mis_ena_reg[irq_index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) en &= ~(1ull << irq_bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) cvmx_write_csr(mis_ena_reg[irq_index], en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) cvmx_read_csr(mis_ena_reg[irq_index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static struct irq_chip octeon_irq_chip_msi_pcie = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .name = "MSI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .irq_enable = octeon_irq_msi_enable_pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .irq_disable = octeon_irq_msi_disable_pcie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static void octeon_irq_msi_enable_pci(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * Octeon PCI doesn't have the ability to mask/unmask MSI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * interrupts individually. Instead of masking/unmasking them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * in groups of 16, we simple assume MSI devices are well
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * behaved. MSI interrupts are always enable and the ACK is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * assumed to be enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) */
^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) static void octeon_irq_msi_disable_pci(struct irq_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* See comment in enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static struct irq_chip octeon_irq_chip_msi_pci = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) .name = "MSI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) .irq_enable = octeon_irq_msi_enable_pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) .irq_disable = octeon_irq_msi_disable_pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * Called by the interrupt handling code when an MSI interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * occurs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static irqreturn_t __octeon_msi_do_interrupt(int index, u64 msi_bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) bit = fls64(msi_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (bit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) bit--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* Acknowledge it first. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) cvmx_write_csr(msi_rcv_reg[index], 1ull << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) irq = bit + OCTEON_IRQ_MSI_BIT0 + 64 * index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) do_IRQ(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) #define OCTEON_MSI_INT_HANDLER_X(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) static irqreturn_t octeon_msi_interrupt##x(int cpl, void *dev_id) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) u64 msi_bits = cvmx_read_csr(msi_rcv_reg[(x)]); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return __octeon_msi_do_interrupt((x), msi_bits); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * Create octeon_msi_interrupt{0-3} function body
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) OCTEON_MSI_INT_HANDLER_X(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) OCTEON_MSI_INT_HANDLER_X(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) OCTEON_MSI_INT_HANDLER_X(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) OCTEON_MSI_INT_HANDLER_X(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * Initializes the MSI interrupt handling code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) int __init octeon_msi_initialize(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct irq_chip *msi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_INVALID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) } else if (octeon_dma_bar_type == OCTEON_DMA_BAR_TYPE_PCIE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) msi_rcv_reg[0] = CVMX_PEXP_NPEI_MSI_RCV0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) msi_rcv_reg[1] = CVMX_PEXP_NPEI_MSI_RCV1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) msi_rcv_reg[2] = CVMX_PEXP_NPEI_MSI_RCV2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) msi_rcv_reg[3] = CVMX_PEXP_NPEI_MSI_RCV3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) mis_ena_reg[0] = CVMX_PEXP_NPEI_MSI_ENB0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) mis_ena_reg[1] = CVMX_PEXP_NPEI_MSI_ENB1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) mis_ena_reg[2] = CVMX_PEXP_NPEI_MSI_ENB2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) mis_ena_reg[3] = CVMX_PEXP_NPEI_MSI_ENB3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) msi = &octeon_irq_chip_msi_pcie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) msi_rcv_reg[0] = CVMX_NPI_NPI_MSI_RCV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) #define INVALID_GENERATE_ADE 0x8700000000000000ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) msi_rcv_reg[1] = INVALID_GENERATE_ADE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) msi_rcv_reg[2] = INVALID_GENERATE_ADE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) msi_rcv_reg[3] = INVALID_GENERATE_ADE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) mis_ena_reg[0] = INVALID_GENERATE_ADE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) mis_ena_reg[1] = INVALID_GENERATE_ADE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) mis_ena_reg[2] = INVALID_GENERATE_ADE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) mis_ena_reg[3] = INVALID_GENERATE_ADE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) msi = &octeon_irq_chip_msi_pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) for (irq = OCTEON_IRQ_MSI_BIT0; irq <= OCTEON_IRQ_MSI_LAST; irq++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) irq_set_chip_and_handler(irq, msi, handle_simple_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 0, "MSI[0:63]", octeon_msi_interrupt0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) panic("request_irq(OCTEON_IRQ_PCI_MSI0) failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (request_irq(OCTEON_IRQ_PCI_MSI1, octeon_msi_interrupt1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 0, "MSI[64:127]", octeon_msi_interrupt1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) panic("request_irq(OCTEON_IRQ_PCI_MSI1) failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (request_irq(OCTEON_IRQ_PCI_MSI2, octeon_msi_interrupt2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 0, "MSI[127:191]", octeon_msi_interrupt2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) panic("request_irq(OCTEON_IRQ_PCI_MSI2) failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (request_irq(OCTEON_IRQ_PCI_MSI3, octeon_msi_interrupt3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 0, "MSI[192:255]", octeon_msi_interrupt3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) panic("request_irq(OCTEON_IRQ_PCI_MSI3) failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) msi_irq_size = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) } else if (octeon_is_pci_host()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 0, "MSI[0:15]", octeon_msi_interrupt0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) panic("request_irq(OCTEON_IRQ_PCI_MSI0) failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (request_irq(OCTEON_IRQ_PCI_MSI1, octeon_msi_interrupt0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 0, "MSI[16:31]", octeon_msi_interrupt0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) panic("request_irq(OCTEON_IRQ_PCI_MSI1) failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (request_irq(OCTEON_IRQ_PCI_MSI2, octeon_msi_interrupt0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 0, "MSI[32:47]", octeon_msi_interrupt0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) panic("request_irq(OCTEON_IRQ_PCI_MSI2) failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (request_irq(OCTEON_IRQ_PCI_MSI3, octeon_msi_interrupt0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 0, "MSI[48:63]", octeon_msi_interrupt0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) panic("request_irq(OCTEON_IRQ_PCI_MSI3) failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) msi_irq_size = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) subsys_initcall(octeon_msi_initialize);