diff options
| author | Mark Maule <maule@sgi.com> | 2006-04-14 17:03:49 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-06-21 14:59:59 -0400 |
| commit | 10083072bfabc40bc47306e512c158c57cf55c2e (patch) | |
| tree | 2c7c3f08ae779594026e67a7a36915c2f97d73b9 | |
| parent | fd58e55fcf5568e51da2ed54d7acd049c3fdb184 (diff) | |
[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: Mark Maule <maule@sgi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
| -rw-r--r-- | arch/ia64/kernel/irq_ia64.c | 19 | ||||
| -rw-r--r-- | arch/ia64/sn/kernel/irq.c | 7 | ||||
| -rw-r--r-- | drivers/pci/msi.c | 6 | ||||
| -rw-r--r-- | include/asm-ia64/hw_irq.h | 15 |
4 files changed, 43 insertions, 4 deletions
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 6c4d59fd0364..ef9a2b49307a 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c | |||
| @@ -46,6 +46,10 @@ | |||
| 46 | 46 | ||
| 47 | #define IRQ_DEBUG 0 | 47 | #define IRQ_DEBUG 0 |
| 48 | 48 | ||
| 49 | /* These can be overridden in platform_irq_init */ | ||
| 50 | int ia64_first_device_vector = IA64_DEF_FIRST_DEVICE_VECTOR; | ||
| 51 | int ia64_last_device_vector = IA64_DEF_LAST_DEVICE_VECTOR; | ||
| 52 | |||
| 49 | /* default base addr of IPI table */ | 53 | /* default base addr of IPI table */ |
| 50 | void __iomem *ipi_base_addr = ((void __iomem *) | 54 | void __iomem *ipi_base_addr = ((void __iomem *) |
| 51 | (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR)); | 55 | (__IA64_UNCACHED_OFFSET | IA64_IPI_DEFAULT_BASE_ADDR)); |
| @@ -60,7 +64,7 @@ __u8 isa_irq_to_vector_map[16] = { | |||
| 60 | }; | 64 | }; |
| 61 | EXPORT_SYMBOL(isa_irq_to_vector_map); | 65 | EXPORT_SYMBOL(isa_irq_to_vector_map); |
| 62 | 66 | ||
| 63 | static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_NUM_DEVICE_VECTORS)]; | 67 | static unsigned long ia64_vector_mask[BITS_TO_LONGS(IA64_MAX_DEVICE_VECTORS)]; |
| 64 | 68 | ||
| 65 | int | 69 | int |
| 66 | assign_irq_vector (int irq) | 70 | assign_irq_vector (int irq) |
| @@ -89,6 +93,19 @@ free_irq_vector (int vector) | |||
| 89 | printk(KERN_WARNING "%s: double free!\n", __FUNCTION__); | 93 | printk(KERN_WARNING "%s: double free!\n", __FUNCTION__); |
| 90 | } | 94 | } |
| 91 | 95 | ||
| 96 | int | ||
| 97 | reserve_irq_vector (int vector) | ||
| 98 | { | ||
| 99 | int pos; | ||
| 100 | |||
| 101 | if (vector < IA64_FIRST_DEVICE_VECTOR || | ||
| 102 | vector > IA64_LAST_DEVICE_VECTOR) | ||
| 103 | return -EINVAL; | ||
| 104 | |||
| 105 | pos = vector - IA64_FIRST_DEVICE_VECTOR; | ||
| 106 | return test_and_set_bit(pos, ia64_vector_mask); | ||
| 107 | } | ||
| 108 | |||
| 92 | #ifdef CONFIG_SMP | 109 | #ifdef CONFIG_SMP |
| 93 | # define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE) | 110 | # define IS_RESCHEDULE(vec) (vec == IA64_IPI_RESCHEDULE) |
| 94 | #else | 111 | #else |
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index c265e02f5036..db187f5cdae1 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c | |||
| @@ -202,6 +202,9 @@ void sn_irq_init(void) | |||
| 202 | int i; | 202 | int i; |
| 203 | irq_desc_t *base_desc = irq_desc; | 203 | irq_desc_t *base_desc = irq_desc; |
| 204 | 204 | ||
| 205 | ia64_first_device_vector = IA64_SN2_FIRST_DEVICE_VECTOR; | ||
| 206 | ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR; | ||
| 207 | |||
| 205 | for (i = 0; i < NR_IRQS; i++) { | 208 | for (i = 0; i < NR_IRQS; i++) { |
| 206 | if (base_desc[i].handler == &no_irq_type) { | 209 | if (base_desc[i].handler == &no_irq_type) { |
| 207 | base_desc[i].handler = &irq_type_sn; | 210 | 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 | /* link it into the sn_irq[irq] list */ | 288 | /* link it into the sn_irq[irq] list */ |
| 286 | spin_lock(&sn_irq_info_lock); | 289 | spin_lock(&sn_irq_info_lock); |
| 287 | list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); | 290 | list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); |
| 291 | reserve_irq_vector(sn_irq_info->irq_irq); | ||
| 288 | spin_unlock(&sn_irq_info_lock); | 292 | spin_unlock(&sn_irq_info_lock); |
| 289 | 293 | ||
| 290 | register_intr_pda(sn_irq_info); | 294 | register_intr_pda(sn_irq_info); |
| @@ -310,8 +314,11 @@ void sn_irq_unfixup(struct pci_dev *pci_dev) | |||
| 310 | spin_lock(&sn_irq_info_lock); | 314 | spin_lock(&sn_irq_info_lock); |
| 311 | list_del_rcu(&sn_irq_info->list); | 315 | list_del_rcu(&sn_irq_info->list); |
| 312 | spin_unlock(&sn_irq_info_lock); | 316 | spin_unlock(&sn_irq_info_lock); |
| 317 | if (list_empty(sn_irq_lh[sn_irq_info->irq_irq])) | ||
| 318 | free_irq_vector(sn_irq_info->irq_irq); | ||
| 313 | call_rcu(&sn_irq_info->rcu, sn_irq_info_free); | 319 | call_rcu(&sn_irq_info->rcu, sn_irq_info_free); |
| 314 | pci_dev_put(pci_dev); | 320 | pci_dev_put(pci_dev); |
| 321 | |||
| 315 | } | 322 | } |
| 316 | 323 | ||
| 317 | static inline void | 324 | static inline void |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 55ff52df5fe7..f8105783da2f 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
| @@ -35,7 +35,7 @@ static int nr_msix_devices; | |||
| 35 | 35 | ||
| 36 | #ifndef CONFIG_X86_IO_APIC | 36 | #ifndef CONFIG_X86_IO_APIC |
| 37 | int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; | 37 | int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; |
| 38 | u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; | 38 | u8 irq_vector[NR_IRQ_VECTORS]; |
| 39 | #endif | 39 | #endif |
| 40 | 40 | ||
| 41 | static struct msi_ops *msi_ops; | 41 | static struct msi_ops *msi_ops; |
| @@ -383,6 +383,10 @@ static int msi_init(void) | |||
| 383 | return status; | 383 | return status; |
| 384 | } | 384 | } |
| 385 | 385 | ||
| 386 | #ifndef CONFIG_X86_IO_APIC | ||
| 387 | irq_vector[0] = FIRST_DEVICE_VECTOR; | ||
| 388 | #endif | ||
| 389 | |||
| 386 | if (last_alloc_vector < 0) { | 390 | if (last_alloc_vector < 0) { |
| 387 | pci_msi_enable = 0; | 391 | pci_msi_enable = 0; |
| 388 | printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n"); | 392 | printk(KERN_WARNING "PCI: No interrupt vectors available for MSI\n"); |
diff --git a/include/asm-ia64/hw_irq.h b/include/asm-ia64/hw_irq.h index 0cf119b42f7d..ea8b8c407ab4 100644 --- a/include/asm-ia64/hw_irq.h +++ b/include/asm-ia64/hw_irq.h | |||
| @@ -47,9 +47,19 @@ typedef u8 ia64_vector; | |||
| 47 | #define IA64_CMC_VECTOR 0x1f /* corrected machine-check interrupt vector */ | 47 | #define IA64_CMC_VECTOR 0x1f /* corrected machine-check interrupt vector */ |
| 48 | /* | 48 | /* |
| 49 | * Vectors 0x20-0x2f are reserved for legacy ISA IRQs. | 49 | * Vectors 0x20-0x2f are reserved for legacy ISA IRQs. |
| 50 | * Use vectors 0x30-0xe7 as the default device vector range for ia64. | ||
| 51 | * Platforms may choose to reduce this range in platform_irq_setup, but the | ||
| 52 | * platform range must fall within | ||
| 53 | * [IA64_DEF_FIRST_DEVICE_VECTOR..IA64_DEF_LAST_DEVICE_VECTOR] | ||
| 50 | */ | 54 | */ |
| 51 | #define IA64_FIRST_DEVICE_VECTOR 0x30 | 55 | extern int ia64_first_device_vector; |
| 52 | #define IA64_LAST_DEVICE_VECTOR 0xe7 | 56 | extern int ia64_last_device_vector; |
| 57 | |||
| 58 | #define IA64_DEF_FIRST_DEVICE_VECTOR 0x30 | ||
| 59 | #define IA64_DEF_LAST_DEVICE_VECTOR 0xe7 | ||
| 60 | #define IA64_FIRST_DEVICE_VECTOR ia64_first_device_vector | ||
| 61 | #define IA64_LAST_DEVICE_VECTOR ia64_last_device_vector | ||
| 62 | #define IA64_MAX_DEVICE_VECTORS (IA64_DEF_LAST_DEVICE_VECTOR - IA64_DEF_FIRST_DEVICE_VECTOR + 1) | ||
| 53 | #define IA64_NUM_DEVICE_VECTORS (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1) | 63 | #define IA64_NUM_DEVICE_VECTORS (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1) |
| 54 | 64 | ||
| 55 | #define IA64_MCA_RENDEZ_VECTOR 0xe8 /* MCA rendez interrupt */ | 65 | #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 | 93 | ||
| 84 | extern int assign_irq_vector (int irq); /* allocate a free vector */ | 94 | extern int assign_irq_vector (int irq); /* allocate a free vector */ |
| 85 | extern void free_irq_vector (int vector); | 95 | extern void free_irq_vector (int vector); |
| 96 | extern int reserve_irq_vector (int vector); | ||
| 86 | extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); | 97 | extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect); |
| 87 | extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); | 98 | extern void register_percpu_irq (ia64_vector vec, struct irqaction *action); |
| 88 | 99 | ||
