aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/io_apic_64.c64
-rw-r--r--arch/x86/kernel/irq_64.c2
-rw-r--r--drivers/pci/htirq.c22
-rw-r--r--fs/proc/proc_misc.c2
-rw-r--r--include/linux/irq.h1
5 files changed, 73 insertions, 18 deletions
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index 8ab7ae01773f..b0d4abc55a11 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -2520,17 +2520,21 @@ device_initcall(ioapic_init_sysfs);
2520/* 2520/*
2521 * Dynamic irq allocate and deallocation 2521 * Dynamic irq allocate and deallocation
2522 */ 2522 */
2523int create_irq(void) 2523unsigned int create_irq_nr(unsigned int irq_want)
2524{ 2524{
2525 /* Allocate an unused irq */ 2525 /* Allocate an unused irq */
2526 int irq; 2526 unsigned int irq;
2527 int new; 2527 unsigned int new;
2528 unsigned long flags; 2528 unsigned long flags;
2529 struct irq_cfg *cfg_new; 2529 struct irq_cfg *cfg_new;
2530 2530
2531 irq = -ENOSPC; 2531#ifndef CONFIG_HAVE_SPARSE_IRQ
2532 irq_want = nr_irqs - 1;
2533#endif
2534
2535 irq = 0;
2532 spin_lock_irqsave(&vector_lock, flags); 2536 spin_lock_irqsave(&vector_lock, flags);
2533 for (new = (nr_irqs - 1); new >= 0; new--) { 2537 for (new = irq_want; new > 0; new--) {
2534 if (platform_legacy_irq(new)) 2538 if (platform_legacy_irq(new))
2535 continue; 2539 continue;
2536 cfg_new = irq_cfg(new); 2540 cfg_new = irq_cfg(new);
@@ -2545,12 +2549,24 @@ int create_irq(void)
2545 } 2549 }
2546 spin_unlock_irqrestore(&vector_lock, flags); 2550 spin_unlock_irqrestore(&vector_lock, flags);
2547 2551
2548 if (irq >= 0) { 2552 if (irq > 0) {
2549 dynamic_irq_init(irq); 2553 dynamic_irq_init(irq);
2550 } 2554 }
2551 return irq; 2555 return irq;
2552} 2556}
2553 2557
2558int create_irq(void)
2559{
2560 int irq;
2561
2562 irq = create_irq_nr(nr_irqs - 1);
2563
2564 if (irq == 0)
2565 irq = -1;
2566
2567 return irq;
2568}
2569
2554void destroy_irq(unsigned int irq) 2570void destroy_irq(unsigned int irq)
2555{ 2571{
2556 unsigned long flags; 2572 unsigned long flags;
@@ -2803,13 +2819,29 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc, int irq)
2803 return 0; 2819 return 0;
2804} 2820}
2805 2821
2822static unsigned int build_irq_for_pci_dev(struct pci_dev *dev)
2823{
2824 unsigned int irq;
2825
2826 irq = dev->bus->number;
2827 irq <<= 8;
2828 irq |= dev->devfn;
2829 irq <<= 12;
2830
2831 return irq;
2832}
2833
2806int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) 2834int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
2807{ 2835{
2808 int irq, ret; 2836 unsigned int irq;
2837 int ret;
2838 unsigned int irq_want;
2809 2839
2810 irq = create_irq(); 2840 irq_want = build_irq_for_pci_dev(dev) + 0x100;
2811 if (irq < 0) 2841
2812 return irq; 2842 irq = create_irq_nr(irq_want);
2843 if (irq == 0)
2844 return -1;
2813 2845
2814#ifdef CONFIG_INTR_REMAP 2846#ifdef CONFIG_INTR_REMAP
2815 if (!intr_remapping_enabled) 2847 if (!intr_remapping_enabled)
@@ -2836,18 +2868,22 @@ error:
2836 2868
2837int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 2869int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
2838{ 2870{
2839 int irq, ret, sub_handle; 2871 unsigned int irq;
2872 int ret, sub_handle;
2840 struct msi_desc *desc; 2873 struct msi_desc *desc;
2874 unsigned int irq_want;
2875
2841#ifdef CONFIG_INTR_REMAP 2876#ifdef CONFIG_INTR_REMAP
2842 struct intel_iommu *iommu = 0; 2877 struct intel_iommu *iommu = 0;
2843 int index = 0; 2878 int index = 0;
2844#endif 2879#endif
2845 2880
2881 irq_want = build_irq_for_pci_dev(dev) + 0x100;
2846 sub_handle = 0; 2882 sub_handle = 0;
2847 list_for_each_entry(desc, &dev->msi_list, list) { 2883 list_for_each_entry(desc, &dev->msi_list, list) {
2848 irq = create_irq(); 2884 irq = create_irq_nr(irq_want--);
2849 if (irq < 0) 2885 if (irq == 0)
2850 return irq; 2886 return -1;
2851#ifdef CONFIG_INTR_REMAP 2887#ifdef CONFIG_INTR_REMAP
2852 if (!intr_remapping_enabled) 2888 if (!intr_remapping_enabled)
2853 goto no_ir; 2889 goto no_ir;
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 7bd841a9c640..348a11168c2b 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -112,7 +112,7 @@ int show_interrupts(struct seq_file *p, void *v)
112 action = desc->action; 112 action = desc->action;
113 if (!action && !any_count) 113 if (!action && !any_count)
114 goto skip; 114 goto skip;
115 seq_printf(p, "%3d: ",i); 115 seq_printf(p, "%#x: ",i);
116#ifndef CONFIG_SMP 116#ifndef CONFIG_SMP
117 seq_printf(p, "%10u ", kstat_irqs(i)); 117 seq_printf(p, "%10u ", kstat_irqs(i));
118#else 118#else
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c
index 279c940a0039..7c5aef13fcdb 100644
--- a/drivers/pci/htirq.c
+++ b/drivers/pci/htirq.c
@@ -82,6 +82,18 @@ void unmask_ht_irq(unsigned int irq)
82 write_ht_irq_msg(irq, &msg); 82 write_ht_irq_msg(irq, &msg);
83} 83}
84 84
85static unsigned int build_irq_for_pci_dev(struct pci_dev *dev)
86{
87 unsigned int irq;
88
89 irq = dev->bus->number;
90 irq <<= 8;
91 irq |= dev->devfn;
92 irq <<= 12;
93
94 return irq;
95}
96
85/** 97/**
86 * __ht_create_irq - create an irq and attach it to a device. 98 * __ht_create_irq - create an irq and attach it to a device.
87 * @dev: The hypertransport device to find the irq capability on. 99 * @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)
97 u32 data; 109 u32 data;
98 int max_irq; 110 int max_irq;
99 int pos; 111 int pos;
100 int irq; 112 unsigned int irq;
113 unsigned int irq_want;
101 114
102 pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ); 115 pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ);
103 if (!pos) 116 if (!pos)
@@ -125,8 +138,13 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
125 cfg->msg.address_lo = 0xffffffff; 138 cfg->msg.address_lo = 0xffffffff;
126 cfg->msg.address_hi = 0xffffffff; 139 cfg->msg.address_hi = 0xffffffff;
127 140
141 irq_want= build_irq_for_pci_dev(dev);
142#ifdef CONFIG_HAVE_SPARSE_IRQ
143 irq = create_irq_nr(irq_want + idx);
144#else
128 irq = create_irq(); 145 irq = create_irq();
129 if (irq < 0) { 146#endif
147 if (irq == 0) {
130 kfree(cfg); 148 kfree(cfg);
131 return -EBUSY; 149 return -EBUSY;
132 } 150 }
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 72dd739a7f8a..d68c3592fe4a 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -589,7 +589,7 @@ static int show_stat(struct seq_file *p, void *v)
589 } 589 }
590 590
591#ifdef CONFIG_HAVE_SPARSE_IRQ 591#ifdef CONFIG_HAVE_SPARSE_IRQ
592 seq_printf(p, " %u:%u", j, per_irq_sum); 592 seq_printf(p, " %#x:%u", j, per_irq_sum);
593#else 593#else
594 seq_printf(p, " %u", per_irq_sum); 594 seq_printf(p, " %u", per_irq_sum);
595#endif 595#endif
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 788d5a35a580..704136138dc7 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -399,6 +399,7 @@ extern void set_irq_noprobe(unsigned int irq);
399extern void set_irq_probe(unsigned int irq); 399extern void set_irq_probe(unsigned int irq);
400 400
401/* Handle dynamic irq creation and destruction */ 401/* Handle dynamic irq creation and destruction */
402extern unsigned int create_irq_nr(unsigned int irq_want);
402extern int create_irq(void); 403extern int create_irq(void);
403extern void destroy_irq(unsigned int irq); 404extern void destroy_irq(unsigned int irq);
404 405