/*
  * Dynamic irq allocate and deallocation
  */
-int create_irq(void)
+unsigned int create_irq_nr(unsigned int irq_want)
 {
        /* Allocate an unused irq */
-       int irq;
-       int new;
+       unsigned int irq;
+       unsigned int new;
        unsigned long flags;
        struct irq_cfg *cfg_new;
 
-       irq = -ENOSPC;
+#ifndef CONFIG_HAVE_SPARSE_IRQ
+       irq_want = nr_irqs - 1;
+#endif
+
+       irq = 0;
        spin_lock_irqsave(&vector_lock, flags);
-       for (new = (nr_irqs - 1); new >= 0; new--) {
+       for (new = irq_want; new > 0; new--) {
                if (platform_legacy_irq(new))
                        continue;
                cfg_new = irq_cfg(new);
        }
        spin_unlock_irqrestore(&vector_lock, flags);
 
-       if (irq >= 0) {
+       if (irq > 0) {
                dynamic_irq_init(irq);
        }
        return irq;
 }
 
+int create_irq(void)
+{
+       int irq;
+
+       irq = create_irq_nr(nr_irqs - 1);
+
+       if (irq == 0)
+               irq = -1;
+
+       return irq;
+}
+
 void destroy_irq(unsigned int irq)
 {
        unsigned long flags;
        return 0;
 }
 
+static unsigned int build_irq_for_pci_dev(struct pci_dev *dev)
+{
+       unsigned int irq;
+
+       irq = dev->bus->number;
+       irq <<= 8;
+       irq |= dev->devfn;
+       irq <<= 12;
+
+       return irq;
+}
+
 int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
 {
-       int irq, ret;
+       unsigned int irq;
+       int ret;
+       unsigned int irq_want;
 
-       irq = create_irq();
-       if (irq < 0)
-               return irq;
+       irq_want = build_irq_for_pci_dev(dev) + 0x100;
+
+       irq = create_irq_nr(irq_want);
+       if (irq == 0)
+               return -1;
 
 #ifdef CONFIG_INTR_REMAP
        if (!intr_remapping_enabled)
 
 int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
 {
-       int irq, ret, sub_handle;
+       unsigned int irq;
+       int ret, sub_handle;
        struct msi_desc *desc;
+       unsigned int irq_want;
+
 #ifdef CONFIG_INTR_REMAP
        struct intel_iommu *iommu = 0;
        int index = 0;
 #endif
 
+       irq_want = build_irq_for_pci_dev(dev) + 0x100;
        sub_handle = 0;
        list_for_each_entry(desc, &dev->msi_list, list) {
-               irq = create_irq();
-               if (irq < 0)
-                       return irq;
+               irq = create_irq_nr(irq_want--);
+               if (irq == 0)
+                       return -1;
 #ifdef CONFIG_INTR_REMAP
                if (!intr_remapping_enabled)
                        goto no_ir;
 
                action = desc->action;
                if (!action && !any_count)
                        goto skip;
-               seq_printf(p, "%3d: ",i);
+               seq_printf(p, "%#x: ",i);
 #ifndef CONFIG_SMP
                seq_printf(p, "%10u ", kstat_irqs(i));
 #else
 
        write_ht_irq_msg(irq, &msg);
 }
 
+static unsigned int build_irq_for_pci_dev(struct pci_dev *dev)
+{
+       unsigned int irq;
+
+       irq = dev->bus->number;
+       irq <<= 8;
+       irq |= dev->devfn;
+       irq <<= 12;
+
+       return irq;
+}
+
 /**
  * __ht_create_irq - create an irq and attach it to a device.
  * @dev: The hypertransport device to find the irq capability on.
        u32 data;
        int max_irq;
        int pos;
-       int irq;
+       unsigned int irq;
+       unsigned int irq_want;
 
        pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ);
        if (!pos)
        cfg->msg.address_lo = 0xffffffff;
        cfg->msg.address_hi = 0xffffffff;
 
+       irq_want= build_irq_for_pci_dev(dev);
+#ifdef CONFIG_HAVE_SPARSE_IRQ
+       irq = create_irq_nr(irq_want + idx);
+#else
        irq = create_irq();
-       if (irq < 0) {
+#endif
+       if (irq == 0) {
                kfree(cfg);
                return -EBUSY;
        }
 
                }
 
 #ifdef CONFIG_HAVE_SPARSE_IRQ
-               seq_printf(p, " %u:%u", j, per_irq_sum);
+               seq_printf(p, " %#x:%u", j, per_irq_sum);
 #else
                seq_printf(p, " %u", per_irq_sum);
 #endif
 
 extern void set_irq_probe(unsigned int irq);
 
 /* Handle dynamic irq creation and destruction */
+extern unsigned int create_irq_nr(unsigned int irq_want);
 extern int create_irq(void);
 extern void destroy_irq(unsigned int irq);