diff options
Diffstat (limited to 'arch/powerpc/platforms/ps3')
-rw-r--r-- | arch/powerpc/platforms/ps3/device-init.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/interrupt.c | 23 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/platform.h | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/repository.c | 32 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/smp.c | 62 |
5 files changed, 72 insertions, 48 deletions
diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index 6c4b5837fc8..3f175e8aedb 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c @@ -825,7 +825,7 @@ static int ps3_probe_thread(void *data) spin_lock_init(&dev.lock); - res = request_irq(irq, ps3_notification_interrupt, IRQF_DISABLED, + res = request_irq(irq, ps3_notification_interrupt, 0, "ps3_notification", &dev); if (res) { pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__, diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 404bc52b780..1d6f4f478fe 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -88,6 +88,7 @@ struct ps3_private { struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN))); u64 ppe_id; u64 thread_id; + unsigned long ipi_mask; }; static DEFINE_PER_CPU(struct ps3_private, ps3_private); @@ -144,7 +145,11 @@ static void ps3_chip_unmask(struct irq_data *d) static void ps3_chip_eoi(struct irq_data *d) { const struct ps3_private *pd = irq_data_get_irq_chip_data(d); - lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq); + + /* non-IPIs are EOIed here. */ + + if (!test_bit(63 - d->irq, &pd->ipi_mask)) + lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, d->irq); } /** @@ -691,6 +696,16 @@ void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq) cpu, virq, pd->bmp.ipi_debug_brk_mask); } +void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq) +{ + struct ps3_private *pd = &per_cpu(ps3_private, cpu); + + set_bit(63 - virq, &pd->ipi_mask); + + DBG("%s:%d: cpu %u, virq %u, ipi_mask %lxh\n", __func__, __LINE__, + cpu, virq, pd->ipi_mask); +} + static unsigned int ps3_get_irq(void) { struct ps3_private *pd = &__get_cpu_var(ps3_private); @@ -720,6 +735,12 @@ static unsigned int ps3_get_irq(void) BUG(); } #endif + + /* IPIs are EOIed here. */ + + if (test_bit(63 - plug, &pd->ipi_mask)) + lv1_end_of_interrupt_ext(pd->ppe_id, pd->thread_id, plug); + return plug; } diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h index 9a196a88eda..1a633ed0fe9 100644 --- a/arch/powerpc/platforms/ps3/platform.h +++ b/arch/powerpc/platforms/ps3/platform.h @@ -43,6 +43,7 @@ void ps3_mm_shutdown(void); void ps3_init_IRQ(void); void ps3_shutdown_IRQ(int cpu); void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq); +void __init ps3_register_ipi_irq(unsigned int cpu, unsigned int virq); /* smp */ diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index 5e304c292f6..ca40f6afd35 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c @@ -184,7 +184,7 @@ int ps3_repository_read_bus_type(unsigned int bus_index, enum ps3_bus_type *bus_type) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -199,7 +199,7 @@ int ps3_repository_read_bus_num_dev(unsigned int bus_index, unsigned int *num_dev) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -239,7 +239,7 @@ int ps3_repository_read_dev_type(unsigned int bus_index, unsigned int dev_index, enum ps3_dev_type *dev_type) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -256,8 +256,8 @@ int ps3_repository_read_dev_intr(unsigned int bus_index, enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id) { int result; - u64 v1; - u64 v2; + u64 v1 = 0; + u64 v2 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -275,7 +275,7 @@ int ps3_repository_read_dev_reg_type(unsigned int bus_index, enum ps3_reg_type *reg_type) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -615,7 +615,7 @@ int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index, unsigned int dev_index, unsigned int *num_regions) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -631,7 +631,7 @@ int ps3_repository_read_stor_dev_region_id(unsigned int bus_index, unsigned int *region_id) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("bus", bus_index), @@ -786,7 +786,7 @@ int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total) int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_CURRENT, make_first_field("bi", 0), @@ -805,7 +805,7 @@ int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved) int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_CURRENT, make_first_field("bi", 0), @@ -827,8 +827,8 @@ int ps3_repository_read_spu_resource_id(unsigned int res_index, enum ps3_spu_resource_type *resource_type, unsigned int *resource_id) { int result; - u64 v1; - u64 v2; + u64 v1 = 0; + u64 v2 = 0; result = read_node(PS3_LPAR_ID_CURRENT, make_first_field("bi", 0), @@ -854,7 +854,7 @@ static int ps3_repository_read_boot_dat_address(u64 *address) int ps3_repository_read_boot_dat_size(unsigned int *size) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_CURRENT, make_first_field("bi", 0), @@ -869,7 +869,7 @@ int ps3_repository_read_boot_dat_size(unsigned int *size) int ps3_repository_read_vuart_av_port(unsigned int *port) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_CURRENT, make_first_field("bi", 0), @@ -884,7 +884,7 @@ int ps3_repository_read_vuart_av_port(unsigned int *port) int ps3_repository_read_vuart_sysmgr_port(unsigned int *port) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_CURRENT, make_first_field("bi", 0), @@ -919,7 +919,7 @@ int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size) int ps3_repository_read_num_be(unsigned int *num_be) { int result; - u64 v1; + u64 v1 = 0; result = read_node(PS3_LPAR_ID_PME, make_first_field("ben", 0), diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c index 4c44794faac..efc1cd8c034 100644 --- a/arch/powerpc/platforms/ps3/smp.c +++ b/arch/powerpc/platforms/ps3/smp.c @@ -59,46 +59,49 @@ static void ps3_smp_message_pass(int cpu, int msg) static int ps3_smp_probe(void) { - return 2; -} + int cpu; -static void __init ps3_smp_setup_cpu(int cpu) -{ - int result; - unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu); - int i; + for (cpu = 0; cpu < 2; cpu++) { + int result; + unsigned int *virqs = per_cpu(ps3_ipi_virqs, cpu); + int i; - DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); + DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); - /* - * Check assumptions on ps3_ipi_virqs[] indexing. If this - * check fails, then a different mapping of PPC_MSG_ - * to index needs to be setup. - */ + /* + * Check assumptions on ps3_ipi_virqs[] indexing. If this + * check fails, then a different mapping of PPC_MSG_ + * to index needs to be setup. + */ - BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION != 0); - BUILD_BUG_ON(PPC_MSG_RESCHEDULE != 1); - BUILD_BUG_ON(PPC_MSG_CALL_FUNC_SINGLE != 2); - BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3); + BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION != 0); + BUILD_BUG_ON(PPC_MSG_RESCHEDULE != 1); + BUILD_BUG_ON(PPC_MSG_CALL_FUNC_SINGLE != 2); + BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3); - for (i = 0; i < MSG_COUNT; i++) { - result = ps3_event_receive_port_setup(cpu, &virqs[i]); + for (i = 0; i < MSG_COUNT; i++) { + result = ps3_event_receive_port_setup(cpu, &virqs[i]); - if (result) - continue; + if (result) + continue; - DBG("%s:%d: (%d, %d) => virq %u\n", - __func__, __LINE__, cpu, i, virqs[i]); + DBG("%s:%d: (%d, %d) => virq %u\n", + __func__, __LINE__, cpu, i, virqs[i]); - result = smp_request_message_ipi(virqs[i], i); + result = smp_request_message_ipi(virqs[i], i); - if (result) - virqs[i] = NO_IRQ; - } + if (result) + virqs[i] = NO_IRQ; + else + ps3_register_ipi_irq(cpu, virqs[i]); + } - ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]); + ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]); - DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu); + DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu); + } + + return 2; } void ps3_smp_cleanup_cpu(int cpu) @@ -121,7 +124,6 @@ static struct smp_ops_t ps3_smp_ops = { .probe = ps3_smp_probe, .message_pass = ps3_smp_message_pass, .kick_cpu = smp_generic_kick_cpu, - .setup_cpu = ps3_smp_setup_cpu, }; void smp_init_ps3(void) |