diff options
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r-- | arch/powerpc/platforms/52xx/lite5200_pm.c | 14 | ||||
-rw-r--r-- | arch/powerpc/platforms/52xx/mpc52xx_gpio.c | 14 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/celleb_scc_pciex.c | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spu_base.c | 44 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/run.c | 21 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/sched.c | 19 | ||||
-rw-r--r-- | arch/powerpc/platforms/ps3/mm.c | 3 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/eeh_driver.c | 11 | ||||
-rw-r--r-- | arch/powerpc/platforms/pseries/nvram.c | 4 |
10 files changed, 91 insertions, 45 deletions
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c index 41c7fd91e99..fe92e65103e 100644 --- a/arch/powerpc/platforms/52xx/lite5200_pm.c +++ b/arch/powerpc/platforms/52xx/lite5200_pm.c @@ -14,6 +14,7 @@ static struct mpc52xx_sdma __iomem *bes; static struct mpc52xx_xlb __iomem *xlb; static struct mpc52xx_gpio __iomem *gps; static struct mpc52xx_gpio_wkup __iomem *gpw; +static void __iomem *pci; static void __iomem *sram; static const int sram_size = 0x4000; /* 16 kBytes */ static void __iomem *mbar; @@ -50,6 +51,8 @@ static int lite5200_pm_prepare(void) { .type = "builtin", .compatible = "mpc5200", }, /* efika */ {} }; + u64 regaddr64 = 0; + const u32 *regaddr_p; /* deep sleep? let mpc52xx code handle that */ if (lite5200_pm_target_state == PM_SUSPEND_STANDBY) @@ -60,8 +63,12 @@ static int lite5200_pm_prepare(void) /* map registers */ np = of_find_matching_node(NULL, immr_ids); - mbar = of_iomap(np, 0); + regaddr_p = of_get_address(np, 0, NULL, NULL); + if (regaddr_p) + regaddr64 = of_translate_address(np, regaddr_p); of_node_put(np); + + mbar = ioremap((u32) regaddr64, 0xC000); if (!mbar) { printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__); return -ENOSYS; @@ -71,6 +78,7 @@ static int lite5200_pm_prepare(void) pic = mbar + 0x500; gps = mbar + 0xb00; gpw = mbar + 0xc00; + pci = mbar + 0xd00; bes = mbar + 0x1200; xlb = mbar + 0x1f00; sram = mbar + 0x8000; @@ -85,6 +93,7 @@ static struct mpc52xx_sdma sbes; static struct mpc52xx_xlb sxlb; static struct mpc52xx_gpio sgps; static struct mpc52xx_gpio_wkup sgpw; +static char spci[0x200]; static void lite5200_save_regs(void) { @@ -94,6 +103,7 @@ static void lite5200_save_regs(void) _memcpy_fromio(&sxlb, xlb, sizeof(*xlb)); _memcpy_fromio(&sgps, gps, sizeof(*gps)); _memcpy_fromio(&sgpw, gpw, sizeof(*gpw)); + _memcpy_fromio(spci, pci, 0x200); _memcpy_fromio(saved_sram, sram, sram_size); } @@ -103,6 +113,8 @@ static void lite5200_restore_regs(void) int i; _memcpy_toio(sram, saved_sram, sram_size); + /* PCI Configuration */ + _memcpy_toio(pci, spci, 0x200); /* * GPIOs. Interrupt Master Enable has higher address then other diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index 48da5dfe485..8a455ebce98 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -100,7 +100,7 @@ static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct mpc52xx_gpiochip *chip = container_of(mm_gc, struct mpc52xx_gpiochip, mmchip); - struct mpc52xx_gpio_wkup *regs = mm_gc->regs; + struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; unsigned long flags; spin_lock_irqsave(&gpio_lock, flags); @@ -122,7 +122,7 @@ static int mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) { struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct mpc52xx_gpio_wkup *regs = mm_gc->regs; + struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; struct mpc52xx_gpiochip *chip = container_of(mm_gc, struct mpc52xx_gpiochip, mmchip); unsigned long flags; @@ -150,7 +150,7 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, const struct of_device_id *match) { struct mpc52xx_gpiochip *chip; - struct mpc52xx_gpio_wkup *regs; + struct mpc52xx_gpio_wkup __iomem *regs; struct of_gpio_chip *ofchip; int ret; @@ -260,7 +260,7 @@ static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct mpc52xx_gpiochip *chip = container_of(mm_gc, struct mpc52xx_gpiochip, mmchip); - struct mpc52xx_gpio *regs = mm_gc->regs; + struct mpc52xx_gpio __iomem *regs = mm_gc->regs; unsigned long flags; spin_lock_irqsave(&gpio_lock, flags); @@ -284,7 +284,7 @@ mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct mpc52xx_gpiochip *chip = container_of(mm_gc, struct mpc52xx_gpiochip, mmchip); - struct mpc52xx_gpio *regs = mm_gc->regs; + struct mpc52xx_gpio __iomem *regs = mm_gc->regs; unsigned long flags; spin_lock_irqsave(&gpio_lock, flags); @@ -312,7 +312,7 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, { struct mpc52xx_gpiochip *chip; struct of_gpio_chip *ofchip; - struct mpc52xx_gpio *regs; + struct mpc52xx_gpio __iomem *regs; int ret; chip = kzalloc(sizeof(*chip), GFP_KERNEL); @@ -387,7 +387,7 @@ mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) { struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct mpc52xx_gpt *regs = mm_gc->regs; + struct mpc52xx_gpt __iomem *regs = mm_gc->regs; out_be32(®s->mode, 0x04); diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 7ff29d53dc2..ecbe580c3f3 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -34,6 +34,7 @@ config MPC85xx_MDS bool "Freescale MPC85xx MDS" select DEFAULT_UIMAGE select QUICC_ENGINE + select PHYLIB help This option enables support for the MPC85xx MDS board diff --git a/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/arch/powerpc/platforms/cell/celleb_scc_pciex.c index 31da84c458d..0e04f8fb152 100644 --- a/arch/powerpc/platforms/cell/celleb_scc_pciex.c +++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c @@ -217,7 +217,7 @@ static u##size scc_pciex_in##name(unsigned long port) \ static void scc_pciex_ins##name(unsigned long p, void *b, unsigned long c) \ { \ struct iowa_bus *bus = iowa_pio_find_bus(p); \ - u##size *dst = b; \ + __le##size *dst = b; \ for (; c != 0; c--, dst++) \ *dst = cpu_to_le##size(__scc_pciex_in##name(bus->phb, p)); \ scc_pciex_io_flush(bus); \ @@ -231,10 +231,11 @@ static void scc_pciex_outs##name(unsigned long p, const void *b, \ unsigned long c) \ { \ struct iowa_bus *bus = iowa_pio_find_bus(p); \ - const u##size *src = b; \ + const __le##size *src = b; \ for (; c != 0; c--, src++) \ __scc_pciex_out##name(bus->phb, le##size##_to_cpu(*src), p); \ } +#define __le8 u8 #define cpu_to_le8(x) (x) #define le8_to_cpu(x) (x) PCIEX_PIO_FUNC(8, b) diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 70c660121ec..78f905bc6a4 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -219,15 +219,25 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) { + int ret; + pr_debug("%s, %lx, %lx\n", __func__, dsisr, ea); - /* Handle kernel space hash faults immediately. - User hash faults need to be deferred to process context. */ - if ((dsisr & MFC_DSISR_PTE_NOT_FOUND) - && REGION_ID(ea) != USER_REGION_ID - && hash_page(ea, _PAGE_PRESENT, 0x300) == 0) { - spu_restart_dma(spu); - return 0; + /* + * Handle kernel space hash faults immediately. User hash + * faults need to be deferred to process context. + */ + if ((dsisr & MFC_DSISR_PTE_NOT_FOUND) && + (REGION_ID(ea) != USER_REGION_ID)) { + + spin_unlock(&spu->register_lock); + ret = hash_page(ea, _PAGE_PRESENT, 0x300); + spin_lock(&spu->register_lock); + + if (!ret) { + spu_restart_dma(spu); + return 0; + } } spu->class_1_dar = ea; @@ -324,17 +334,13 @@ spu_irq_class_0(int irq, void *data) stat = spu_int_stat_get(spu, 0) & mask; spu->class_0_pending |= stat; - spu->class_0_dsisr = spu_mfc_dsisr_get(spu); spu->class_0_dar = spu_mfc_dar_get(spu); - spin_unlock(&spu->register_lock); - spu->stop_callback(spu, 0); - spu->class_0_pending = 0; - spu->class_0_dsisr = 0; spu->class_0_dar = 0; spu_int_stat_clear(spu, 0, stat); + spin_unlock(&spu->register_lock); return IRQ_HANDLED; } @@ -357,13 +363,12 @@ spu_irq_class_1(int irq, void *data) spu_mfc_dsisr_set(spu, 0ul); spu_int_stat_clear(spu, 1, stat); - if (stat & CLASS1_SEGMENT_FAULT_INTR) - __spu_trap_data_seg(spu, dar); - - spin_unlock(&spu->register_lock); pr_debug("%s: %lx %lx %lx %lx\n", __func__, mask, stat, dar, dsisr); + if (stat & CLASS1_SEGMENT_FAULT_INTR) + __spu_trap_data_seg(spu, dar); + if (stat & CLASS1_STORAGE_FAULT_INTR) __spu_trap_data_map(spu, dar, dsisr); @@ -376,6 +381,8 @@ spu_irq_class_1(int irq, void *data) spu->class_1_dsisr = 0; spu->class_1_dar = 0; + spin_unlock(&spu->register_lock); + return stat ? IRQ_HANDLED : IRQ_NONE; } @@ -394,14 +401,12 @@ spu_irq_class_2(int irq, void *data) mask = spu_int_mask_get(spu, 2); /* ignore interrupts we're not waiting for */ stat &= mask; - /* mailbox interrupts are level triggered. mask them now before * acknowledging */ if (stat & mailbox_intrs) spu_int_mask_and(spu, 2, ~(stat & mailbox_intrs)); /* acknowledge all interrupts before the callbacks */ spu_int_stat_clear(spu, 2, stat); - spin_unlock(&spu->register_lock); pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask); @@ -421,6 +426,9 @@ spu_irq_class_2(int irq, void *data) spu->wbox_callback(spu); spu->stats.class2_intr++; + + spin_unlock(&spu->register_lock); + return stat ? IRQ_HANDLED : IRQ_NONE; } diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index b7493b86581..f7edba6cb79 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -27,7 +27,6 @@ void spufs_stop_callback(struct spu *spu, int irq) switch(irq) { case 0 : ctx->csa.class_0_pending = spu->class_0_pending; - ctx->csa.class_0_dsisr = spu->class_0_dsisr; ctx->csa.class_0_dar = spu->class_0_dar; break; case 1 : @@ -51,18 +50,22 @@ int spu_stopped(struct spu_context *ctx, u32 *stat) u64 dsisr; u32 stopped; - *stat = ctx->ops->status_read(ctx); - - if (test_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags)) - return 1; - stopped = SPU_STATUS_INVALID_INSTR | SPU_STATUS_SINGLE_STEP | SPU_STATUS_STOPPED_BY_HALT | SPU_STATUS_STOPPED_BY_STOP; - if (!(*stat & SPU_STATUS_RUNNING) && (*stat & stopped)) + +top: + *stat = ctx->ops->status_read(ctx); + if (*stat & stopped) { + /* + * If the spu hasn't finished stopping, we need to + * re-read the register to get the stopped value. + */ + if (*stat & SPU_STATUS_RUNNING) + goto top; return 1; + } - dsisr = ctx->csa.class_0_dsisr; - if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) + if (test_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags)) return 1; dsisr = ctx->csa.class_1_dsisr; diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 745dd51ec37..e929e70a84e 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -230,19 +230,23 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx) ctx->stats.slb_flt_base = spu->stats.slb_flt; ctx->stats.class2_intr_base = spu->stats.class2_intr; + spu_associate_mm(spu, ctx->owner); + + spin_lock_irq(&spu->register_lock); spu->ctx = ctx; spu->flags = 0; ctx->spu = spu; ctx->ops = &spu_hw_ops; spu->pid = current->pid; spu->tgid = current->tgid; - spu_associate_mm(spu, ctx->owner); spu->ibox_callback = spufs_ibox_callback; spu->wbox_callback = spufs_wbox_callback; spu->stop_callback = spufs_stop_callback; spu->mfc_callback = spufs_mfc_callback; - mb(); + spin_unlock_irq(&spu->register_lock); + spu_unmap_mappings(ctx); + spu_switch_log_notify(spu, ctx, SWITCH_LOG_START, 0); spu_restore(&ctx->csa, spu); spu->timestamp = jiffies; @@ -403,6 +407,8 @@ static int has_affinity(struct spu_context *ctx) */ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) { + u32 status; + spu_context_trace(spu_unbind_context__enter, ctx, spu); spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); @@ -423,18 +429,22 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) spu_unmap_mappings(ctx); spu_save(&ctx->csa, spu); spu_switch_log_notify(spu, ctx, SWITCH_LOG_STOP, 0); + + spin_lock_irq(&spu->register_lock); spu->timestamp = jiffies; ctx->state = SPU_STATE_SAVED; spu->ibox_callback = NULL; spu->wbox_callback = NULL; spu->stop_callback = NULL; spu->mfc_callback = NULL; - spu_associate_mm(spu, NULL); spu->pid = 0; spu->tgid = 0; ctx->ops = &spu_backing_ops; spu->flags = 0; spu->ctx = NULL; + spin_unlock_irq(&spu->register_lock); + + spu_associate_mm(spu, NULL); ctx->stats.slb_flt += (spu->stats.slb_flt - ctx->stats.slb_flt_base); @@ -444,6 +454,9 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) /* This maps the underlying spu state to idle */ spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); ctx->spu = NULL; + + if (spu_stopped(ctx, &status)) + wake_up_all(&ctx->stop_wq); } /** diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index 5b3fb2b321a..3a58ffabccd 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -317,6 +317,9 @@ static int __init ps3_mm_add_memory(void) return result; } + lmb_add(start_addr, map.r1.size); + lmb_analyze(); + result = online_pages(start_pfn, nr_pages); if (result) diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c index 68ea5eee39a..8c1ca477c52 100644 --- a/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/arch/powerpc/platforms/pseries/eeh_driver.c @@ -42,17 +42,20 @@ static inline const char * pcid_name (struct pci_dev *pdev) } #ifdef DEBUG -static void print_device_node_tree (struct pci_dn *pdn, int dent) +static void print_device_node_tree(struct pci_dn *pdn, int dent) { int i; - if (!pdn) return; - for (i=0;i<dent; i++) + struct device_node *pc; + + if (!pdn) + return; + for (i = 0; i < dent; i++) printk(" "); printk("dn=%s mode=%x \tcfg_addr=%x pe_addr=%x \tfull=%s\n", pdn->node->name, pdn->eeh_mode, pdn->eeh_config_addr, pdn->eeh_pe_config_addr, pdn->node->full_name); dent += 3; - struct device_node *pc = pdn->node->child; + pc = pdn->node->child; while (pc) { print_device_node_tree(PCI_DN(pc), dent); pc = pc->sibling; diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index f68903e15bd..42f7e384e6c 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -131,8 +131,10 @@ int __init pSeries_nvram_init(void) return -ENODEV; nbytes_p = of_get_property(nvram, "#bytes", &proplen); - if (nbytes_p == NULL || proplen != sizeof(unsigned int)) + if (nbytes_p == NULL || proplen != sizeof(unsigned int)) { + of_node_put(nvram); return -EIO; + } nvram_size = *nbytes_p; |