diff options
Diffstat (limited to 'arch/powerpc/platforms')
21 files changed, 111 insertions, 34 deletions
diff --git a/arch/powerpc/platforms/83xx/usb.c b/arch/powerpc/platforms/83xx/usb.c index e7fdf013cd3..eafe7605cda 100644 --- a/arch/powerpc/platforms/83xx/usb.c +++ b/arch/powerpc/platforms/83xx/usb.c @@ -76,14 +76,14 @@ int mpc834x_usb_cfg(void) if (port0_is_dr) printk(KERN_WARNING "834x USB port0 can't be used by both DR and MPH!\n"); - sicrl |= MPC834X_SICRL_USB0; + sicrl &= ~MPC834X_SICRL_USB0; } prop = of_get_property(np, "port1", NULL); if (prop) { if (port1_is_dr) printk(KERN_WARNING "834x USB port1 can't be used by both DR and MPH!\n"); - sicrl |= MPC834X_SICRL_USB1; + sicrl &= ~MPC834X_SICRL_USB1; } of_node_put(np); } diff --git a/arch/powerpc/platforms/85xx/mpc8544_ds.c b/arch/powerpc/platforms/85xx/mpc8544_ds.c index 0f834d8be44..48983bc56d4 100644 --- a/arch/powerpc/platforms/85xx/mpc8544_ds.c +++ b/arch/powerpc/platforms/85xx/mpc8544_ds.c @@ -178,7 +178,9 @@ define_machine(mpc8544_ds) { .probe = mpc8544_ds_probe, .setup_arch = mpc8544_ds_setup_arch, .init_IRQ = mpc8544_ds_pic_init, +#ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, +#endif .get_irq = mpic_get_irq, .restart = mpc85xx_restart, .calibrate_decr = generic_calibrate_decr, diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c index 6a171e9abf7..2d4cb784760 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -351,10 +351,10 @@ define_machine(mpc85xx_cds) { .get_irq = mpic_get_irq, #ifdef CONFIG_PCI .restart = mpc85xx_cds_restart, + .pcibios_fixup_bus = fsl_pcibios_fixup_bus, #else .restart = mpc85xx_restart, #endif .calibrate_decr = generic_calibrate_decr, .progress = udbg_progress, - .pcibios_fixup_bus = fsl_pcibios_fixup_bus, }; diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index be25ecd911b..7ca7e676f1c 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -207,5 +207,7 @@ define_machine(mpc85xx_mds) { .restart = mpc85xx_restart, .calibrate_decr = generic_calibrate_decr, .progress = udbg_progress, +#ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, +#endif }; diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 56b27caf7a2..47aafa76c93 100644 --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -250,5 +250,7 @@ define_machine(mpc86xx_hpcn) { .time_init = mpc86xx_time_init, .calibrate_decr = generic_calibrate_decr, .progress = udbg_progress, +#ifdef CONFIG_PCI .pcibios_fixup_bus = fsl_pcibios_fixup_bus, +#endif }; diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index cfc24974159..19d4628edf7 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -285,6 +285,7 @@ config AXON_RAM config FSL_ULI1575 bool default n + select GENERIC_ISA_DMA help Supports for the ULI1575 PCIe south bridge that exists on some Freescale reference boards. The boards all use the ULI in pretty diff --git a/arch/powerpc/platforms/cell/cbe_regs.h b/arch/powerpc/platforms/cell/cbe_regs.h index 17d59714487..b24025f2ac7 100644 --- a/arch/powerpc/platforms/cell/cbe_regs.h +++ b/arch/powerpc/platforms/cell/cbe_regs.h @@ -113,10 +113,14 @@ struct cbe_pmd_regs { u64 checkstop_fir; /* 0x0c00 */ u64 recoverable_fir; /* 0x0c08 */ u64 spec_att_mchk_fir; /* 0x0c10 */ - u64 fir_mode_reg; /* 0x0c18 */ + u32 fir_mode_reg; /* 0x0c18 */ + u8 pad_0x0c1c_0x0c20 [4]; /* 0x0c1c */ +#define CBE_PMD_FIR_MODE_M8 0x00800 u64 fir_enable_mask; /* 0x0c20 */ - u8 pad_0x0c28_0x1000 [0x1000 - 0x0c28]; /* 0x0c28 */ + u8 pad_0x0c28_0x0ca8 [0x0ca8 - 0x0c28]; /* 0x0c28 */ + u64 ras_esc_0; /* 0x0ca8 */ + u8 pad_0x0cb0_0x1000 [0x1000 - 0x0cb0]; /* 0x0cb0 */ }; extern struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np); diff --git a/arch/powerpc/platforms/cell/cbe_thermal.c b/arch/powerpc/platforms/cell/cbe_thermal.c index e4132f8f51b..fb5eda48467 100644 --- a/arch/powerpc/platforms/cell/cbe_thermal.c +++ b/arch/powerpc/platforms/cell/cbe_thermal.c @@ -88,17 +88,13 @@ static struct cbe_pmd_regs __iomem *get_pmd_regs(struct sys_device *sysdev) /* returns the value for a given spu in a given register */ static u8 spu_read_register_value(struct sys_device *sysdev, union spe_reg __iomem *reg) { - const unsigned int *id; union spe_reg value; struct spu *spu; - /* getting the id from the reg attribute will not work on future device-tree layouts - * in future we should store the id to the spu struct and use it here */ spu = container_of(sysdev, struct spu, sysdev); - id = of_get_property(spu_devnode(spu), "reg", NULL); value.val = in_be64(®->val); - return value.spe[*id]; + return value.spe[spu->spe_id]; } static ssize_t spu_show_temp(struct sys_device *sysdev, char *buf) diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c index 812bf563ed6..4ede22d363f 100644 --- a/arch/powerpc/platforms/cell/pervasive.c +++ b/arch/powerpc/platforms/cell/pervasive.c @@ -38,6 +38,8 @@ #include "pervasive.h" #include "cbe_regs.h" +static int sysreset_hack; + static void cbe_power_save(void) { unsigned long ctrl, thread_switch_control; @@ -85,6 +87,9 @@ static void cbe_power_save(void) static int cbe_system_reset_exception(struct pt_regs *regs) { + int cpu; + struct cbe_pmd_regs __iomem *pmd; + switch (regs->msr & SRR1_WAKEMASK) { case SRR1_WAKEEE: do_IRQ(regs); @@ -93,6 +98,18 @@ static int cbe_system_reset_exception(struct pt_regs *regs) timer_interrupt(regs); break; case SRR1_WAKEMT: + /* + * The BMC can inject user triggered system reset exceptions, + * but cannot set the system reset reason in srr1, + * so check an extra register here. + */ + if (sysreset_hack && (cpu = smp_processor_id()) == 0) { + pmd = cbe_get_cpu_pmd_regs(cpu); + if (in_be64(&pmd->ras_esc_0) & 0xffff) { + out_be64(&pmd->ras_esc_0, 0); + return 0; + } + } break; #ifdef CONFIG_CBE_RAS case SRR1_WAKESYSERR: @@ -113,9 +130,12 @@ static int cbe_system_reset_exception(struct pt_regs *regs) void __init cbe_pervasive_init(void) { int cpu; + if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) return; + sysreset_hack = machine_is_compatible("IBM,CBPLUS-1.0"); + for_each_possible_cpu(cpu) { struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu); if (!regs) @@ -124,6 +144,12 @@ void __init cbe_pervasive_init(void) /* Enable Pause(0) control bit */ out_be64(®s->pmcr, in_be64(®s->pmcr) | CBE_PMD_PAUSE_ZERO_CONTROL); + + /* Enable JTAG system-reset hack */ + if (sysreset_hack) + out_be32(®s->fir_mode_reg, + in_be32(®s->fir_mode_reg) | + CBE_PMD_FIR_MODE_M8); } ppc_md.power_save = cbe_power_save; diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 095a30304c5..106d2921e2d 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -236,27 +236,34 @@ static irqreturn_t spu_irq_class_0(int irq, void *data) { struct spu *spu; + unsigned long stat, mask; spu = data; - spu->class_0_pending = 1; + + mask = spu_int_mask_get(spu, 0); + stat = spu_int_stat_get(spu, 0); + stat &= mask; + + spin_lock(&spu->register_lock); + spu->class_0_pending |= stat; + spin_unlock(&spu->register_lock); + spu->stop_callback(spu); + spu_int_stat_clear(spu, 0, stat); + return IRQ_HANDLED; } int spu_irq_class_0_bottom(struct spu *spu) { - unsigned long stat, mask; unsigned long flags; - - spu->class_0_pending = 0; + unsigned long stat; spin_lock_irqsave(&spu->register_lock, flags); - mask = spu_int_mask_get(spu, 0); - stat = spu_int_stat_get(spu, 0); - - stat &= mask; + stat = spu->class_0_pending; + spu->class_0_pending = 0; if (stat & 1) /* invalid DMA alignment */ __spu_trap_dma_align(spu); @@ -267,7 +274,6 @@ spu_irq_class_0_bottom(struct spu *spu) if (stat & 4) /* error on SPU */ __spu_trap_error(spu); - spu_int_stat_clear(spu, 0, stat); spin_unlock_irqrestore(&spu->register_lock, flags); return (stat & 0x7) ? -EIO : 0; diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c index 5eb88346181..0e14f532500 100644 --- a/arch/powerpc/platforms/cell/spu_manage.c +++ b/arch/powerpc/platforms/cell/spu_manage.c @@ -48,10 +48,18 @@ static u64 __init find_spu_unit_number(struct device_node *spe) { const unsigned int *prop; int proplen; + + /* new device trees should provide the physical-id attribute */ + prop = of_get_property(spe, "physical-id", &proplen); + if (proplen == 4) + return (u64)*prop; + + /* celleb device tree provides the unit-id */ prop = of_get_property(spe, "unit-id", &proplen); if (proplen == 4) return (u64)*prop; + /* legacy device trees provide the id in the reg attribute */ prop = of_get_property(spe, "reg", &proplen); if (proplen == 4) return (u64)*prop; diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c index 07a0e815abf..ec01214e51e 100644 --- a/arch/powerpc/platforms/cell/spufs/backing_ops.c +++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c @@ -162,7 +162,8 @@ static int spu_backing_wbox_write(struct spu_context *ctx, u32 data) BUG_ON(avail != (4 - slot)); ctx->csa.spu_mailbox_data[slot] = data; ctx->csa.spu_chnlcnt_RW[29] = ++slot; - ctx->csa.prob.mb_stat_R = (((4 - slot) & 0xff) << 8); + ctx->csa.prob.mb_stat_R &= ~(0x00ff00); + ctx->csa.prob.mb_stat_R |= (((4 - slot) & 0xff) << 8); gen_spu_event(ctx, MFC_SPU_MAILBOX_WRITTEN_EVENT); ret = 4; } else { diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 4100ddc52f0..7de4e919687 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -2177,8 +2177,8 @@ struct tree_descr spufs_dir_contents[] = { { "mbox_stat", &spufs_mbox_stat_fops, 0444, }, { "ibox_stat", &spufs_ibox_stat_fops, 0444, }, { "wbox_stat", &spufs_wbox_stat_fops, 0444, }, - { "signal1", &spufs_signal1_nosched_fops, 0222, }, - { "signal2", &spufs_signal2_nosched_fops, 0222, }, + { "signal1", &spufs_signal1_fops, 0666, }, + { "signal2", &spufs_signal2_fops, 0666, }, { "signal1_type", &spufs_signal1_type, 0666, }, { "signal2_type", &spufs_signal2_type, 0666, }, { "cntl", &spufs_cntl_fops, 0666, }, diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index 6abdd8fe209..958f10e90fd 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -193,11 +193,7 @@ static int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc, if (ret) return ret; - ret = spu_run_init(ctx, npc); - if (ret) { - spu_release(ctx); - return ret; - } + spuctx_switch_state(ctx, SPU_UTIL_USER); return 0; } diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index c784edd40ea..5bebe7fbe05 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -579,7 +579,7 @@ static struct spu *find_victim(struct spu_context *ctx) list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { struct spu_context *tmp = spu->ctx; - if (tmp->prio > ctx->prio && + if (tmp && tmp->prio > ctx->prio && (!victim || tmp->prio > victim->prio)) victim = spu->ctx; } @@ -611,9 +611,9 @@ static struct spu *find_victim(struct spu_context *ctx) mutex_lock(&cbe_spu_info[node].list_mutex); cbe_spu_info[node].nr_active--; + spu_unbind_context(spu, victim); mutex_unlock(&cbe_spu_info[node].list_mutex); - spu_unbind_context(spu, victim); victim->stats.invol_ctx_switch++; spu->stats.invol_ctx_switch++; mutex_unlock(&victim->state_mutex); diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c index f33b21b9f5d..9014d55c717 100644 --- a/arch/powerpc/platforms/pasemi/iommu.c +++ b/arch/powerpc/platforms/pasemi/iommu.c @@ -93,7 +93,7 @@ static void iobmap_build(struct iommu_table *tbl, long index, pr_debug("iobmap: build at: %lx, %lx, addr: %lx\n", index, npages, uaddr); - bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; + bus_addr = (tbl->it_offset + index) << IOBMAP_PAGE_SHIFT; ip = ((u32 *)tbl->it_base) + index; @@ -118,7 +118,7 @@ static void iobmap_free(struct iommu_table *tbl, long index, pr_debug("iobmap: free at: %lx, %lx\n", index, npages); - bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; + bus_addr = (tbl->it_offset + index) << IOBMAP_PAGE_SHIFT; ip = ((u32 *)tbl->it_base) + index; @@ -137,7 +137,7 @@ static void iommu_table_iobmap_setup(void) iommu_table_iobmap.it_busno = 0; iommu_table_iobmap.it_offset = 0; /* it_size is in number of entries */ - iommu_table_iobmap.it_size = 0x80000000 >> PAGE_SHIFT; + iommu_table_iobmap.it_size = 0x80000000 >> IOBMAP_PAGE_SHIFT; /* Initialize the common IOMMU code */ iommu_table_iobmap.it_base = (unsigned long)iob_l2_base; diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h index 87d52060fec..2eb8f92704b 100644 --- a/arch/powerpc/platforms/ps3/platform.h +++ b/arch/powerpc/platforms/ps3/platform.h @@ -83,6 +83,7 @@ enum ps3_dev_type { PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */ PS3_DEV_TYPE_SB_GPIO = 6, PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */ + PS3_DEV_TYPE_STOR_DUMMY = 32, PS3_DEV_TYPE_NOACCESS = 255, }; diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index 8cc37cfea0f..1c94824f7b6 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c @@ -349,6 +349,35 @@ int ps3_repository_find_device(struct ps3_repository_device *repo) return result; } + if (tmp.bus_type == PS3_BUS_TYPE_STORAGE) { + /* + * A storage device may show up in the repository before the + * hypervisor has finished probing its type and regions + */ + unsigned int num_regions; + + if (tmp.dev_type == PS3_DEV_TYPE_STOR_DUMMY) { + pr_debug("%s:%u storage device not ready\n", __func__, + __LINE__); + return -ENODEV; + } + + result = ps3_repository_read_stor_dev_num_regions(tmp.bus_index, + tmp.dev_index, + &num_regions); + if (result) { + pr_debug("%s:%d read_stor_dev_num_regions failed\n", + __func__, __LINE__); + return result; + } + + if (!num_regions) { + pr_debug("%s:%u storage device has no regions yet\n", + __func__, __LINE__); + return -ENODEV; + } + } + result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index, &tmp.dev_id); diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c index 2952b22f1c8..609945dbe39 100644 --- a/arch/powerpc/platforms/ps3/setup.c +++ b/arch/powerpc/platforms/ps3/setup.c @@ -63,7 +63,8 @@ int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev) x.minor = minor; x.rev = rev; - return (ps3_firmware_version.raw - x.raw); + return (ps3_firmware_version.raw > x.raw) - + (ps3_firmware_version.raw < x.raw); } EXPORT_SYMBOL_GPL(ps3_compare_firmware_version); diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c index ac2a4b8a4c1..d1630a074ac 100644 --- a/arch/powerpc/platforms/ps3/spu.c +++ b/arch/powerpc/platforms/ps3/spu.c @@ -505,6 +505,8 @@ static void mfc_sr1_set(struct spu *spu, u64 sr1) static const u64 allowed = ~(MFC_STATE1_LOCAL_STORAGE_DECODE_MASK | MFC_STATE1_PROBLEM_STATE_MASK); + sr1 |= MFC_STATE1_MASTER_RUN_CONTROL_MASK; + BUG_ON((sr1 & allowed) != (spu_pdata(spu)->cache.sr1 & allowed)); spu_pdata(spu)->cache.sr1 = sr1; diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 5bd90a7eb76..f0b5ff17d86 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c @@ -419,7 +419,7 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask) * For the moment only implement delivery to all cpus or one cpu. * Get current irq_server for the given irq */ - irq_server = get_irq_server(irq, 1); + irq_server = get_irq_server(virq, 1); if (irq_server == -1) { char cpulist[128]; cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask); |