提交 10083072 编写于 作者: M Mark Maule 提交者: Greg Kroah-Hartman

[PATCH] PCI: per-platform IA64_{FIRST,LAST}_DEVICE_VECTOR definitions

Abstract IA64_FIRST_DEVICE_VECTOR/IA64_LAST_DEVICE_VECTOR since SN platforms
use a subset of the IA64 range.  Implement this by making the above macros
global variables which the platform can override in it setup code.

Also add a reserve_irq_vector() routine used by SN to mark a vector's as
in-use when that weren't allocated through assign_irq_vector().
Signed-off-by: NMark Maule <maule@sgi.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 fd58e55f
...@@ -46,6 +46,10 @@ ...@@ -46,6 +46,10 @@
#define IRQ_DEBUG 0 #define IRQ_DEBUG 0
/* These can be overridden in platform_irq_init */
int ia64_first_device_vector = IA64_DEF_FIRST_DEVICE_VECTOR;
int ia64_last_device_vector = IA64_DEF_LAST_DEVICE_VECTOR;
/* default base addr of IPI table */ /* default base addr of IPI table */
void __iomem *ipi_base_addr = ((void __iomem *) void __iomem *ipi_base_addr = ((void __iomem *)
(__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR)); (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR));
...@@ -60,7 +64,7 @@ __u8 isa_irq_to_vector_map[16] = { ...@@ -60,7 +64,7 @@ __u8 isa_irq_to_vector_map[16] = {
}; };
EXPORT_SYMBOL(isa_irq_to_vector_map); EXPORT_SYMBOL(isa_irq_to_vector_map);
static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)]; static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_MAX_DEVICE_VECTORS)];
int int
assign_irq_vector (int irq) assign_irq_vector (int irq)
...@@ -89,6 +93,19 @@ free_irq_vector (int vector) ...@@ -89,6 +93,19 @@ free_irq_vector (int vector)
printk(KERN_WARNING "%s: double free!\n", __FUNCTION__); printk(KERN_WARNING "%s: double free!\n", __FUNCTION__);
} }
int
reserve_irq_vector (int vector)
{
int pos;
if (vector < IA64_FIRST_DEVICE_VECTOR ||
vector > IA64_LAST_DEVICE_VECTOR)
return -EINVAL;
pos = vector - IA64_FIRST_DEVICE_VECTOR;
return test_and_set_bit(pos, ia64_vector_mask);
}
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
# define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE) # define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE)
#else #else
......
...@@ -202,6 +202,9 @@ void sn_irq_init(void) ...@@ -202,6 +202,9 @@ void sn_irq_init(void)
int i; int i;
irq_desc_t *base_desc = irq_desc; irq_desc_t *base_desc = irq_desc;
ia64_first_device_vector = IA64_SN2_FIRST_DEVICE_VECTOR;
ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR;
for (i = 0; i < NR_IRQS; i++) { for (i = 0; i < NR_IRQS; i++) {
if (base_desc[i].handler == &no_irq_type) { if (base_desc[i].handler == &no_irq_type) {
base_desc[i].handler = &irq_type_sn; base_desc[i].handler = &irq_type_sn;
...@@ -285,6 +288,7 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) ...@@ -285,6 +288,7 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info)
/* link it into the sn_irq[irq] list */ /* link it into the sn_irq[irq] list */
spin_lock(&sn_irq_info_lock); spin_lock(&sn_irq_info_lock);
list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]);
reserve_irq_vector(sn_irq_info->irq_irq);
spin_unlock(&sn_irq_info_lock); spin_unlock(&sn_irq_info_lock);
register_intr_pda(sn_irq_info); register_intr_pda(sn_irq_info);
...@@ -310,8 +314,11 @@ void sn_irq_unfixup(struct pci_dev *pci_dev) ...@@ -310,8 +314,11 @@ void sn_irq_unfixup(struct pci_dev *pci_dev)
spin_lock(&sn_irq_info_lock); spin_lock(&sn_irq_info_lock);
list_del_rcu(&sn_irq_info->list); list_del_rcu(&sn_irq_info->list);
spin_unlock(&sn_irq_info_lock); spin_unlock(&sn_irq_info_lock);
if (list_empty(sn_irq_lh[sn_irq_info->irq_irq]))
free_irq_vector(sn_irq_info->irq_irq);
call_rcu(&sn_irq_info->rcu, sn_irq_info_free); call_rcu(&sn_irq_info->rcu, sn_irq_info_free);
pci_dev_put(pci_dev); pci_dev_put(pci_dev);
} }
static inline void static inline void
......
...@@ -35,7 +35,7 @@ static int nr_msix_devices; ...@@ -35,7 +35,7 @@ static int nr_msix_devices;
#ifndef CONFIG_X86_IO_APIC #ifndef CONFIG_X86_IO_APIC
int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1};
u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; u8 irq_vector[NR_IRQ_VECTORS];
#endif #endif
static struct msi_ops *msi_ops; static struct msi_ops *msi_ops;
...@@ -383,6 +383,10 @@ static int msi_init(void) ...@@ -383,6 +383,10 @@ static int msi_init(void)
return status; return status;
} }
#ifndef CONFIG_X86_IO_APIC
irq_vector[0] = FIRST_DEVICE_VECTOR;
#endif
if (last_alloc_vector < 0) { if (last_alloc_vector < 0) {
pci_msi_enable = 0; pci_msi_enable = 0;
printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n"); printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n");
......
...@@ -47,9 +47,19 @@ typedef u8 ia64_vector; ...@@ -47,9 +47,19 @@ typedef u8 ia64_vector;
#define IA64_CMC_VECTOR 0x1f /* corrected machine-check interrupt vector */ #define IA64_CMC_VECTOR 0x1f /* corrected machine-check interrupt vector */
/* /*
* Vectors 0x20-0x2f are reserved for legacy ISA IRQs. * Vectors 0x20-0x2f are reserved for legacy ISA IRQs.
* Use vectors 0x30-0xe7 as the default device vector range for ia64.
* Platforms may choose to reduce this range in platform_irq_setup, but the
* platform range must fall within
* [IA64_DEF_FIRST_DEVICE_VECTOR..IA64_DEF_LAST_DEVICE_VECTOR]
*/ */
#define IA64_FIRST_DEVICE_VECTOR 0x30 extern int ia64_first_device_vector;
#define IA64_LAST_DEVICE_VECTOR 0xe7 extern int ia64_last_device_vector;
#define IA64_DEF_FIRST_DEVICE_VECTOR 0x30
#define IA64_DEF_LAST_DEVICE_VECTOR 0xe7
#define IA64_FIRST_DEVICE_VECTOR ia64_first_device_vector
#define IA64_LAST_DEVICE_VECTOR ia64_last_device_vector
#define IA64_MAX_DEVICE_VECTORS (IA64_DEF_LAST_DEVICE_VECTOR - IA64_DEF_FIRST_DEVICE_VECTOR + 1)
#define IA64_NUM_DEVICE_VECTORS (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1) #define IA64_NUM_DEVICE_VECTORS (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1)
#define IA64_MCA_RENDEZ_VECTOR 0xe8 /* MCA rendez interrupt */ #define IA64_MCA_RENDEZ_VECTOR 0xe8 /* MCA rendez interrupt */
...@@ -83,6 +93,7 @@ extern struct hw_interrupt_type irq_type_ia64_lsapic; /* CPU-internal interrupt ...@@ -83,6 +93,7 @@ extern struct hw_interrupt_type irq_type_ia64_lsapic; /* CPU-internal interrupt
extern int assign_irq_vector (int irq); /* allocate a free vector */ extern int assign_irq_vector (int irq); /* allocate a free vector */
extern void free_irq_vector (int vector); extern void free_irq_vector (int vector);
extern int reserve_irq_vector (int vector);
extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect);
extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); extern void register_percpu_irq (ia64_vector vec, struct irqaction *action);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册