Skip to content

Commit

Permalink
[POWERPC] ps3: smp interrupt fixes
Browse files Browse the repository at this point in the history
PS3 fixups for interrups on SMP.

Fixes the alignment of the interrupt status bitmap, changes the hypervisor
interrupt calls to the '_ext' versions that take an explicit processor
thread ID.

Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Paul Mackerras <paulus@samba.org>
  • Loading branch information
Geoff Levand authored and Paul Mackerras committed Feb 7, 2007
1 parent 9633ac8 commit 407e24a
Showing 1 changed file with 29 additions and 31 deletions.
60 changes: 29 additions & 31 deletions arch/powerpc/platforms/ps3/interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,22 +317,23 @@ struct ps3_bmp {
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)
Expand Down Expand Up @@ -389,9 +390,8 @@ static void ps3_chip_mask(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_unmask(unsigned int virq)
Expand All @@ -406,14 +406,14 @@ 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 = {
Expand All @@ -426,10 +426,12 @@ 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);
Expand All @@ -441,31 +443,26 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq,
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;
}

Expand Down Expand Up @@ -544,12 +541,9 @@ unsigned int ps3_get_irq(void)
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);
Expand All @@ -558,12 +552,16 @@ void __init ps3_init_IRQ(void)
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:"
Expand Down

0 comments on commit 407e24a

Please sign in to comment.