unsigned long unused_1[3];
unsigned long mask;
unsigned long unused_2[3];
- } __attribute__ ((packed));
+ } __attribute__ ((aligned (64)));
+
spinlock_t lock;
unsigned long ipi_debug_brk_mask;
};
/**
* struct ps3_private - a per cpu data structure
- * @node: HV node id
- * @cpu: HV thread id
- * @bmp: an HV ps3_bmp structure
+ * @bmp: ps3_bmp structure
+ * @node: HV logical_ppe_id
+ * @cpu: HV thread_id
*/
struct ps3_private {
+ struct ps3_bmp bmp;
unsigned long node;
unsigned int cpu;
- struct ps3_bmp bmp;
};
#if defined(DEBUG)
spin_lock_irqsave(&pd->bmp.lock, flags);
pd->bmp.mask &= ~(0x8000000000000000UL >> virq);
- spin_unlock_irqrestore(&pd->bmp.lock, flags);
-
lv1_did_update_interrupt_mask(pd->node, pd->cpu);
+ spin_unlock_irqrestore(&pd->bmp.lock, flags);
}
static void ps3_chip_unmask(unsigned int virq)
spin_lock_irqsave(&pd->bmp.lock, flags);
pd->bmp.mask |= (0x8000000000000000UL >> virq);
- spin_unlock_irqrestore(&pd->bmp.lock, flags);
-
lv1_did_update_interrupt_mask(pd->node, pd->cpu);
+ spin_unlock_irqrestore(&pd->bmp.lock, flags);
}
static void ps3_chip_eoi(unsigned int virq)
{
- lv1_end_of_interrupt(virq);
+ const struct ps3_private *pd = get_irq_chip_data(virq);
+ lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
}
static struct irq_chip irq_chip = {
static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
{
int result;
+ const struct ps3_private *pd = get_irq_chip_data(virq);
- pr_debug("%s:%d: virq %d\n", __func__, __LINE__, virq);
+ pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
+ pd->node, pd->cpu, virq);
- lv1_disconnect_irq_plug(virq);
+ lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
result = set_irq_chip_data(virq, NULL);
BUG_ON(result);
irq_hw_number_t hwirq)
{
int result;
- unsigned int cpu;
+ struct ps3_private *pd = &__get_cpu_var(ps3_private);
- pr_debug(" -> %s:%d\n", __func__, __LINE__);
- pr_debug("%s:%d: hwirq %lu => virq %u\n", __func__, __LINE__, hwirq,
- virq);
+ pr_debug("%s:%d: node %lu, cpu %d, hwirq %lu => virq %u\n", __func__,
+ __LINE__, pd->node, pd->cpu, hwirq, virq);
- /* bind this virq to a cpu */
+ /* Binds this virq to pd->cpu (current cpu) */
- preempt_disable();
- cpu = smp_processor_id();
- result = lv1_connect_irq_plug(virq, hwirq);
- preempt_enable();
+ result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, virq, hwirq, 0);
if (result) {
- pr_info("%s:%d: lv1_connect_irq_plug failed:"
+ pr_info("%s:%d: lv1_connect_irq_plug_ext failed:"
" %s\n", __func__, __LINE__, ps3_result(result));
return -EPERM;
}
- result = set_irq_chip_data(virq, &per_cpu(ps3_private, cpu));
+ result = set_irq_chip_data(virq, pd);
BUG_ON(result);
set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq);
- pr_debug(" <- %s:%d\n", __func__, __LINE__);
return result;
}
void __init ps3_init_IRQ(void)
{
int result;
- unsigned long node;
unsigned cpu;
struct irq_host *host;
- lv1_get_logical_ppe_id(&node);
-
host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops,
PS3_INVALID_OUTLET);
irq_set_default_host(host);
for_each_possible_cpu(cpu) {
struct ps3_private *pd = &per_cpu(ps3_private, cpu);
- pd->node = node;
- pd->cpu = cpu;
+ lv1_get_logical_ppe_id(&pd->node);
+ pd->cpu = get_hard_smp_processor_id(cpu);
spin_lock_init(&pd->bmp.lock);
- result = lv1_configure_irq_state_bitmap(node, cpu,
- ps3_mm_phys_to_lpar(__pa(&pd->bmp.status)));
+ pr_debug("%s:%d: node %lu, cpu %d, bmp %lxh\n", __func__,
+ __LINE__, pd->node, pd->cpu,
+ ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
+
+ result = lv1_configure_irq_state_bitmap(pd->node, pd->cpu,
+ ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
if (result)
pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:"