* [PATCH 7/16] ps3: smp interrupt fixes
@ 2007-01-27 3:08 Geoff Levand
0 siblings, 0 replies; only message in thread
From: Geoff Levand @ 2007-01-27 3:08 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
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>
---
arch/powerpc/platforms/ps3/interrupt.c | 64 +++++++++++++++------------------
1 files changed, 31 insertions(+), 33 deletions(-)
--- ps3-linux-dev.orig/arch/powerpc/platforms/ps3/interrupt.c
+++ ps3-linux-dev/arch/powerpc/platforms/ps3/interrupt.c
@@ -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)
@@ -389,9 +390,8 @@ static void ps3_chip_mask(unsigned int v
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)
@@ -406,14 +406,14 @@ static void ps3_chip_unmask(unsigned int
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 = {
@@ -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);
@@ -441,31 +443,26 @@ static int ps3_host_map(struct irq_host
irq_hw_number_t hwirq)
{
int result;
- unsigned int cpu;
+ struct ps3_private *pd = &__get_cpu_var(ps3_private);
+
+ pr_debug("%s:%d: node %lu, cpu %d, hwirq %lu => virq %u\n", __func__,
+ __LINE__, pd->node, pd->cpu, hwirq, virq);
- pr_debug(" -> %s:%d\n", __func__, __LINE__);
- pr_debug("%s:%d: hwirq %lu => virq %u\n", __func__, __LINE__, hwirq,
- virq);
-
- /* bind this virq to a cpu */
-
- preempt_disable();
- cpu = smp_processor_id();
- result = lv1_connect_irq_plug(virq, hwirq);
- preempt_enable();
+ /* Binds this virq to pd->cpu (current cpu) */
+
+ 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;
}
@@ -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);
@@ -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:"
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2007-01-27 3:08 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-27 3:08 [PATCH 7/16] ps3: smp interrupt fixes Geoff Levand
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.