x86: use 28 bits irq NR for pci msi/msix and ht
authorYinghai Lu <yhlu.kernel@gmail.com>
Wed, 20 Aug 2008 03:50:22 +0000 (20:50 -0700)
committerIngo Molnar <mingo@elte.hu>
Thu, 16 Oct 2008 14:52:52 +0000 (16:52 +0200)
also print out irq no in /proc/interrups and /proc/stat in hex, so could
tell bus/dev/func.

Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
arch/x86/kernel/io_apic_64.c
arch/x86/kernel/irq_64.c
drivers/pci/htirq.c
fs/proc/proc_misc.c
include/linux/irq.h

index 8ab7ae01773f309a330cb41f8637f1f0c3368c71..b0d4abc55a11ccaa99888710dc2c6dd4770bf23c 100644 (file)
@@ -2520,17 +2520,21 @@ device_initcall(ioapic_init_sysfs);
 /*
  * 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);
@@ -2545,12 +2549,24 @@ int create_irq(void)
        }
        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;
@@ -2803,13 +2819,29 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc, int irq)
        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)
@@ -2836,18 +2868,22 @@ error:
 
 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;
index 7bd841a9c6404541a1a897f91644a6afc3483c2f..348a11168c2b391f5147bd613f169b93a42446f1 100644 (file)
@@ -112,7 +112,7 @@ int show_interrupts(struct seq_file *p, void *v)
                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
index 279c940a00397444a8d49e03e1ec68386f78fc3c..7c5aef13fcdb7dd675e4562aee0492fe1f5747ae 100644 (file)
@@ -82,6 +82,18 @@ void unmask_ht_irq(unsigned int irq)
        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.
@@ -97,7 +109,8 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
        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)
@@ -125,8 +138,13 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
        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;
        }
index 72dd739a7f8acdecf647d0df97a5c1aaca8eb7e0..d68c3592fe4adf02e383dd14f462451abbae6e65 100644 (file)
@@ -589,7 +589,7 @@ static int show_stat(struct seq_file *p, void *v)
                }
 
 #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
index 788d5a35a580d3a8b42571ff152dec92b6ff73e2..704136138dc744a150a3a5fb3e57b88e5b46c434 100644 (file)
@@ -399,6 +399,7 @@ extern void set_irq_noprobe(unsigned int irq);
 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);