|
@@ -496,13 +496,18 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
|
|
|
static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi)
|
|
|
{
|
|
|
unsigned int src = mpic_irq_to_hw(irq);
|
|
|
+ struct mpic *mpic;
|
|
|
|
|
|
if (irq < NUM_ISA_INTERRUPTS)
|
|
|
return NULL;
|
|
|
+
|
|
|
+ mpic = irq_desc[irq].chip_data;
|
|
|
+
|
|
|
if (is_ipi)
|
|
|
- *is_ipi = (src >= MPIC_VEC_IPI_0 && src <= MPIC_VEC_IPI_3);
|
|
|
+ *is_ipi = (src >= mpic->ipi_vecs[0] &&
|
|
|
+ src <= mpic->ipi_vecs[3]);
|
|
|
|
|
|
- return irq_desc[irq].chip_data;
|
|
|
+ return mpic;
|
|
|
}
|
|
|
|
|
|
/* Convert a cpu mask from logical to physical cpu numbers. */
|
|
@@ -540,7 +545,11 @@ static inline void mpic_eoi(struct mpic *mpic)
|
|
|
#ifdef CONFIG_SMP
|
|
|
static irqreturn_t mpic_ipi_action(int irq, void *dev_id)
|
|
|
{
|
|
|
- smp_message_recv(mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0);
|
|
|
+ struct mpic *mpic;
|
|
|
+
|
|
|
+ mpic = mpic_find(irq, NULL);
|
|
|
+ smp_message_recv(mpic_irq_to_hw(irq) - mpic->ipi_vecs[0]);
|
|
|
+
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
#endif /* CONFIG_SMP */
|
|
@@ -663,7 +672,7 @@ static void mpic_end_ht_irq(unsigned int irq)
|
|
|
static void mpic_unmask_ipi(unsigned int irq)
|
|
|
{
|
|
|
struct mpic *mpic = mpic_from_ipi(irq);
|
|
|
- unsigned int src = mpic_irq_to_hw(irq) - MPIC_VEC_IPI_0;
|
|
|
+ unsigned int src = mpic_irq_to_hw(irq) - mpic->ipi_vecs[0];
|
|
|
|
|
|
DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, irq, src);
|
|
|
mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
|
|
@@ -807,11 +816,11 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
|
|
|
|
|
|
DBG("mpic: map virq %d, hwirq 0x%lx\n", virq, hw);
|
|
|
|
|
|
- if (hw == MPIC_VEC_SPURRIOUS)
|
|
|
+ if (hw == mpic->spurious_vec)
|
|
|
return -EINVAL;
|
|
|
|
|
|
#ifdef CONFIG_SMP
|
|
|
- else if (hw >= MPIC_VEC_IPI_0) {
|
|
|
+ else if (hw >= mpic->ipi_vecs[0]) {
|
|
|
WARN_ON(!(mpic->flags & MPIC_PRIMARY));
|
|
|
|
|
|
DBG("mpic: mapping as IPI\n");
|
|
@@ -904,6 +913,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
|
|
|
u32 reg;
|
|
|
const char *vers;
|
|
|
int i;
|
|
|
+ int intvec_top;
|
|
|
u64 paddr = phys_addr;
|
|
|
|
|
|
mpic = alloc_bootmem(sizeof(struct mpic));
|
|
@@ -914,9 +924,9 @@ struct mpic * __init mpic_alloc(struct device_node *node,
|
|
|
mpic->name = name;
|
|
|
mpic->of_node = of_node_get(node);
|
|
|
|
|
|
- mpic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, 256,
|
|
|
+ mpic->irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, isu_size,
|
|
|
&mpic_host_ops,
|
|
|
- MPIC_VEC_SPURRIOUS);
|
|
|
+ flags & MPIC_LARGE_VECTORS ? 2048 : 256);
|
|
|
if (mpic->irqhost == NULL) {
|
|
|
of_node_put(node);
|
|
|
return NULL;
|
|
@@ -944,6 +954,21 @@ struct mpic * __init mpic_alloc(struct device_node *node,
|
|
|
mpic->irq_count = irq_count;
|
|
|
mpic->num_sources = 0; /* so far */
|
|
|
|
|
|
+ if (flags & MPIC_LARGE_VECTORS)
|
|
|
+ intvec_top = 2047;
|
|
|
+ else
|
|
|
+ intvec_top = 255;
|
|
|
+
|
|
|
+ mpic->timer_vecs[0] = intvec_top - 8;
|
|
|
+ mpic->timer_vecs[1] = intvec_top - 7;
|
|
|
+ mpic->timer_vecs[2] = intvec_top - 6;
|
|
|
+ mpic->timer_vecs[3] = intvec_top - 5;
|
|
|
+ mpic->ipi_vecs[0] = intvec_top - 4;
|
|
|
+ mpic->ipi_vecs[1] = intvec_top - 3;
|
|
|
+ mpic->ipi_vecs[2] = intvec_top - 2;
|
|
|
+ mpic->ipi_vecs[3] = intvec_top - 1;
|
|
|
+ mpic->spurious_vec = intvec_top;
|
|
|
+
|
|
|
/* Check for "big-endian" in device-tree */
|
|
|
if (node && get_property(node, "big-endian", NULL) != NULL)
|
|
|
mpic->flags |= MPIC_BIG_ENDIAN;
|
|
@@ -1084,11 +1109,6 @@ void __init mpic_init(struct mpic *mpic)
|
|
|
int i;
|
|
|
|
|
|
BUG_ON(mpic->num_sources == 0);
|
|
|
- WARN_ON(mpic->num_sources > MPIC_VEC_IPI_0);
|
|
|
-
|
|
|
- /* Sanitize source count */
|
|
|
- if (mpic->num_sources > MPIC_VEC_IPI_0)
|
|
|
- mpic->num_sources = MPIC_VEC_IPI_0;
|
|
|
|
|
|
printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources);
|
|
|
|
|
@@ -1104,7 +1124,7 @@ void __init mpic_init(struct mpic *mpic)
|
|
|
i * MPIC_INFO(TIMER_STRIDE) +
|
|
|
MPIC_INFO(TIMER_VECTOR_PRI),
|
|
|
MPIC_VECPRI_MASK |
|
|
|
- (MPIC_VEC_TIMER_0 + i));
|
|
|
+ (mpic->timer_vecs[0] + i));
|
|
|
}
|
|
|
|
|
|
/* Initialize IPIs to our reserved vectors and mark them disabled for now */
|
|
@@ -1113,7 +1133,7 @@ void __init mpic_init(struct mpic *mpic)
|
|
|
mpic_ipi_write(i,
|
|
|
MPIC_VECPRI_MASK |
|
|
|
(10 << MPIC_VECPRI_PRIORITY_SHIFT) |
|
|
|
- (MPIC_VEC_IPI_0 + i));
|
|
|
+ (mpic->ipi_vecs[0] + i));
|
|
|
}
|
|
|
|
|
|
/* Initialize interrupt sources */
|
|
@@ -1136,8 +1156,8 @@ void __init mpic_init(struct mpic *mpic)
|
|
|
1 << hard_smp_processor_id());
|
|
|
}
|
|
|
|
|
|
- /* Init spurrious vector */
|
|
|
- mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), MPIC_VEC_SPURRIOUS);
|
|
|
+ /* Init spurious vector */
|
|
|
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), mpic->spurious_vec);
|
|
|
|
|
|
/* Disable 8259 passthrough, if supported */
|
|
|
if (!(mpic->flags & MPIC_NO_PTHROU_DIS))
|
|
@@ -1184,9 +1204,9 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
|
|
|
|
|
|
spin_lock_irqsave(&mpic_lock, flags);
|
|
|
if (is_ipi) {
|
|
|
- reg = mpic_ipi_read(src - MPIC_VEC_IPI_0) &
|
|
|
+ reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) &
|
|
|
~MPIC_VECPRI_PRIORITY_MASK;
|
|
|
- mpic_ipi_write(src - MPIC_VEC_IPI_0,
|
|
|
+ mpic_ipi_write(src - mpic->ipi_vecs[0],
|
|
|
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
|
|
|
} else {
|
|
|
reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI))
|
|
@@ -1207,7 +1227,7 @@ unsigned int mpic_irq_get_priority(unsigned int irq)
|
|
|
|
|
|
spin_lock_irqsave(&mpic_lock, flags);
|
|
|
if (is_ipi)
|
|
|
- reg = mpic_ipi_read(src = MPIC_VEC_IPI_0);
|
|
|
+ reg = mpic_ipi_read(src = mpic->ipi_vecs[0]);
|
|
|
else
|
|
|
reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
|
|
|
spin_unlock_irqrestore(&mpic_lock, flags);
|
|
@@ -1313,7 +1333,7 @@ unsigned int mpic_get_one_irq(struct mpic *mpic)
|
|
|
#ifdef DEBUG_LOW
|
|
|
DBG("%s: get_one_irq(): %d\n", mpic->name, src);
|
|
|
#endif
|
|
|
- if (unlikely(src == MPIC_VEC_SPURRIOUS))
|
|
|
+ if (unlikely(src == mpic->spurious_vec))
|
|
|
return NO_IRQ;
|
|
|
return irq_linear_revmap(mpic->irqhost, src);
|
|
|
}
|
|
@@ -1345,7 +1365,7 @@ void mpic_request_ipis(void)
|
|
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
unsigned int vipi = irq_create_mapping(mpic->irqhost,
|
|
|
- MPIC_VEC_IPI_0 + i);
|
|
|
+ mpic->ipi_vecs[0] + i);
|
|
|
if (vipi == NO_IRQ) {
|
|
|
printk(KERN_ERR "Failed to map IPI %d\n", i);
|
|
|
break;
|