};
DEFINE_PER_CPU(int[IA64_NUM_VECTORS], vector_irq) = {
- [0 ... IA64_NUM_VECTORS - 1] = IA64_SPURIOUS_INT_VECTOR
+ [0 ... IA64_NUM_VECTORS - 1] = -1
};
-static cpumask_t vector_table[IA64_MAX_DEVICE_VECTORS] = {
- [0 ... IA64_MAX_DEVICE_VECTORS - 1] = CPU_MASK_NONE
+static cpumask_t vector_table[IA64_NUM_VECTORS] = {
+ [0 ... IA64_NUM_VECTORS - 1] = CPU_MASK_NONE
};
static int irq_status[NR_IRQS] = {
return -1;
}
-static void reserve_irq(unsigned int irq)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&vector_lock, flags);
- irq_status[irq] = IRQ_RSVD;
- spin_unlock_irqrestore(&vector_lock, flags);
-}
-
static inline int find_unassigned_irq(void)
{
int irq;
static inline int find_unassigned_vector(cpumask_t domain)
{
cpumask_t mask;
- int pos;
+ int pos, vector;
cpus_and(mask, domain, cpu_online_map);
if (cpus_empty(mask))
return -EINVAL;
for (pos = 0; pos < IA64_NUM_DEVICE_VECTORS; pos++) {
- cpus_and(mask, domain, vector_table[pos]);
+ vector = IA64_FIRST_DEVICE_VECTOR + pos;
+ cpus_and(mask, domain, vector_table[vector]);
if (!cpus_empty(mask))
continue;
- return IA64_FIRST_DEVICE_VECTOR + pos;
+ return vector;
}
return -ENOSPC;
}
static int __bind_irq_vector(int irq, int vector, cpumask_t domain)
{
cpumask_t mask;
- int cpu, pos;
+ int cpu;
struct irq_cfg *cfg = &irq_cfg[irq];
+ BUG_ON((unsigned)irq >= NR_IRQS);
+ BUG_ON((unsigned)vector >= IA64_NUM_VECTORS);
+
cpus_and(mask, domain, cpu_online_map);
if (cpus_empty(mask))
return -EINVAL;
cfg->vector = vector;
cfg->domain = domain;
irq_status[irq] = IRQ_USED;
- pos = vector - IA64_FIRST_DEVICE_VECTOR;
- cpus_or(vector_table[pos], vector_table[pos], domain);
+ cpus_or(vector_table[vector], vector_table[vector], domain);
return 0;
}
static void __clear_irq_vector(int irq)
{
- int vector, cpu, pos;
+ int vector, cpu;
cpumask_t mask;
cpumask_t domain;
struct irq_cfg *cfg = &irq_cfg[irq];
domain = cfg->domain;
cpus_and(mask, cfg->domain, cpu_online_map);
for_each_cpu_mask(cpu, mask)
- per_cpu(vector_irq, cpu)[vector] = IA64_SPURIOUS_INT_VECTOR;
+ per_cpu(vector_irq, cpu)[vector] = -1;
cfg->vector = IRQ_VECTOR_UNASSIGNED;
cfg->domain = CPU_MASK_NONE;
irq_status[irq] = IRQ_UNUSED;
- pos = vector - IA64_FIRST_DEVICE_VECTOR;
- cpus_andnot(vector_table[pos], vector_table[pos], domain);
+ cpus_andnot(vector_table[vector], vector_table[vector], domain);
}
static void clear_irq_vector(int irq)
{
unsigned long flags;
int vector, cpu;
- cpumask_t domain;
+ cpumask_t domain = CPU_MASK_NONE;
vector = -ENOSPC;
spin_lock_irqsave(&vector_lock, flags);
- if (irq < 0) {
- goto out;
- }
for_each_online_cpu(cpu) {
domain = vector_allocation_domain(cpu);
vector = find_unassigned_vector(domain);
}
if (vector < 0)
goto out;
+ if (irq == AUTO_ASSIGN)
+ irq = vector;
BUG_ON(__bind_irq_vector(irq, vector, domain));
out:
spin_unlock_irqrestore(&vector_lock, flags);
/* Clear vector_irq */
for (vector = 0; vector < IA64_NUM_VECTORS; ++vector)
- per_cpu(vector_irq, cpu)[vector] = IA64_SPURIOUS_INT_VECTOR;
+ per_cpu(vector_irq, cpu)[vector] = -1;
/* Mark the inuse vectors */
for (irq = 0; irq < NR_IRQS; ++irq) {
if (!cpu_isset(cpu, irq_cfg[irq].domain))
vector_domain_type = VECTOR_DOMAIN_PERCPU;
no_int_routing = 1;
}
- return 1;
+ return 0;
}
early_param("vector", parse_vector_domain);
#else
void destroy_and_reserve_irq(unsigned int irq)
{
+ unsigned long flags;
+
dynamic_irq_cleanup(irq);
- clear_irq_vector(irq);
- reserve_irq(irq);
+ spin_lock_irqsave(&vector_lock, flags);
+ __clear_irq_vector(irq);
+ irq_status[irq] = IRQ_RSVD;
+ spin_unlock_irqrestore(&vector_lock, flags);
}
static int __reassign_irq_vector(int irq, int cpu)
{
unsigned long flags;
int irq, vector, cpu;
- cpumask_t domain;
+ cpumask_t domain = CPU_MASK_NONE;
irq = vector = -ENOSPC;
spin_lock_irqsave(&vector_lock, flags);
} else if (unlikely(IS_RESCHEDULE(vector)))
kstat_this_cpu.irqs[vector]++;
else {
+ int irq = local_vector_to_irq(vector);
+
ia64_setreg(_IA64_REG_CR_TPR, vector);
ia64_srlz_d();
- generic_handle_irq(local_vector_to_irq(vector));
+ if (unlikely(irq < 0)) {
+ printk(KERN_ERR "%s: Unexpected interrupt "
+ "vector %d on CPU %d is not mapped "
+ "to any IRQ!\n", __FUNCTION__, vector,
+ smp_processor_id());
+ } else
+ generic_handle_irq(irq);
/*
* Disable interrupts and send EOI:
kstat_this_cpu.irqs[vector]++;
else {
struct pt_regs *old_regs = set_irq_regs(NULL);
+ int irq = local_vector_to_irq(vector);
ia64_setreg(_IA64_REG_CR_TPR, vector);
ia64_srlz_d();
* it will work. I hope it works!.
* Probably could shared code.
*/
- vectors_in_migration[local_vector_to_irq(vector)]=0;
- generic_handle_irq(local_vector_to_irq(vector));
+ if (unlikely(irq < 0)) {
+ printk(KERN_ERR "%s: Unexpected interrupt "
+ "vector %d on CPU %d not being mapped "
+ "to any IRQ!!\n", __FUNCTION__, vector,
+ smp_processor_id());
+ } else {
+ vectors_in_migration[irq]=0;
+ generic_handle_irq(irq);
+ }
set_irq_regs(old_regs);
/*