int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) { struct msi_msg msg; unsigned long dest_phys_id; int irq, vector; cpumask_t mask; irq = create_irq(); if (irq < 0) return irq; set_irq_msi(irq, desc); cpus_and(mask, irq_to_domain(irq), cpu_online_map); dest_phys_id = cpu_physical_id(first_cpu(mask)); vector = irq_to_vector(irq); msg.address_hi = 0; msg.address_lo = MSI_ADDR_HEADER | MSI_ADDR_DESTMODE_PHYS | MSI_ADDR_REDIRECTION_CPU | MSI_ADDR_DESTID_CPU(dest_phys_id); msg.data = MSI_DATA_TRIGGER_EDGE | MSI_DATA_LEVEL_ASSERT | MSI_DATA_DELIVERY_FIXED | MSI_DATA_VECTOR(vector); write_msi_msg(irq, &msg); set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq); return 0; }
static void ics_set_irq(void *opaque, int srcno, int val) { ICSState *ics = (ICSState *)opaque; if (ics->irqs[srcno].flags & XICS_FLAGS_IRQ_LSI) { set_irq_lsi(ics, srcno, val); } else { set_irq_msi(ics, srcno, val); } }
static void ics_set_irq(void *opaque, int srcno, int val) { ICSState *ics = (ICSState *)opaque; if (ics->islsi[srcno]) { set_irq_lsi(ics, srcno, val); } else { set_irq_msi(ics, srcno, val); } }
static void ics_set_irq(void *opaque, int srcno, int val) { struct ics_state *ics = (struct ics_state *)opaque; struct ics_irq_state *irq = ics->irqs + srcno; if (irq->type == XICS_LSI) { set_irq_lsi(ics, srcno, val); } else { set_irq_msi(ics, srcno, val); } }
/* * public hook interface to allocate an msi interrupt */ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) { struct pcie_port *pp = ((struct pci_sys_data *)pdev->bus->sysdata)->pport; int irq = pcie_msi_create_irq(pp); struct msi_msg msg; if (irq < 0) return irq; set_irq_msi(irq, desc); msg.address_hi = 0x0; msg.address_lo = (u32)pp->msi_addr; msg.data = (irq - pp->msi_irq_base) & 0x1f; PCIE_INFO("Setup msi msg(0, %x, %x), irq=%d\n", msg.address_lo, msg.data, irq); write_msi_msg(irq, &msg); set_irq_chip_and_handler(irq, &ubi32_pcie_msi_chip, handle_simple_irq); return 0; }
int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) { int id, irq = create_irq(); struct msi_msg msg; if (irq < 0) return irq; set_irq_msi(irq, desc); msg.address_hi = 0x0; msg.address_lo = IOP13XX_MU_MIMR_PCI; id = iop13xx_cpu_id(); msg.data = (id << IOP13XX_MU_MIMR_CORE_SELECT) | (irq & 0x7f); write_msi_msg(irq, &msg); set_irq_chip_and_handler(irq, &iop13xx_msi_chip, handle_simple_irq); return 0; }
int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) { struct msi_msg msg; int widget; int status; nasid_t nasid; u64 bus_addr; struct sn_irq_info *sn_irq_info; struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); int irq; if (!entry->msi_attrib.is_64) return -EINVAL; if (bussoft == NULL) return -EINVAL; if (provider == NULL || provider->dma_map_consistent == NULL) return -EINVAL; irq = create_irq(); if (irq < 0) return irq; /* * Set up the vector plumbing. Let the prom (via sn_intr_alloc) * decide which cpu to direct this msi at by default. */ nasid = NASID_GET(bussoft->bs_base); widget = (nasid & 1) ? TIO_SWIN_WIDGETNUM(bussoft->bs_base) : SWIN_WIDGETNUM(bussoft->bs_base); sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); if (! sn_irq_info) { destroy_irq(irq); return -ENOMEM; } status = sn_intr_alloc(nasid, widget, sn_irq_info, irq, -1, -1); if (status) { kfree(sn_irq_info); destroy_irq(irq); return -ENOMEM; } sn_irq_info->irq_int_bit = -1; /* mark this as an MSI irq */ sn_irq_fixup(pdev, sn_irq_info); /* Prom probably should fill these in, but doesn't ... */ sn_irq_info->irq_bridge_type = bussoft->bs_asic_type; sn_irq_info->irq_bridge = (void *)bussoft->bs_base; /* * Map the xio address into bus space */ bus_addr = (*provider->dma_map_consistent)(pdev, sn_irq_info->irq_xtalkaddr, sizeof(sn_irq_info->irq_xtalkaddr), SN_DMA_MSI|SN_DMA_ADDR_XIO); if (! bus_addr) { sn_intr_free(nasid, widget, sn_irq_info); kfree(sn_irq_info); destroy_irq(irq); return -ENOMEM; } sn_msi_info[irq].sn_irq_info = sn_irq_info; sn_msi_info[irq].pci_addr = bus_addr; msg.address_hi = (u32)(bus_addr >> 32); msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff); /* * In the SN platform, bit 16 is a "send vector" bit which * must be present in order to move the vector through the system. */ msg.data = 0x100 + irq; set_irq_msi(irq, entry); write_msi_msg(irq, &msg); set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq); return 0; }