static int ps3_destroy_spu(struct spu *spu) { int result; pr_debug("%s:%d spu_%d\n", __func__, __LINE__, spu->number); result = lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0); BUG_ON(result); ps3_spe_irq_destroy(spu->irqs[2]); ps3_spe_irq_destroy(spu->irqs[1]); ps3_spe_irq_destroy(spu->irqs[0]); spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ; spu_unmap(spu); result = lv1_destruct_logical_spe(spu_pdata(spu)->spe_id); BUG_ON(result); kfree(spu->pdata); spu->pdata = NULL; return 0; }
static int __init enable_spu(struct spu *spu) { int result; result = lv1_enable_logical_spe(spu_pdata(spu)->spe_id, spu_pdata(spu)->resource_id); if (result) { pr_debug("%s:%d: lv1_enable_logical_spe failed: %s\n", __func__, __LINE__, ps3_result(result)); goto fail_enable; } result = setup_areas(spu); if (result) goto fail_areas; result = setup_interrupts(spu); if (result) goto fail_interrupts; return 0; fail_interrupts: spu_unmap(spu); fail_areas: lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0); fail_enable: return result; }
static int __init of_create_spu(struct spu *spu, void *data) { int ret; struct device_node *spe = (struct device_node *)data; static int legacy_map = 0, legacy_irq = 0; spu->devnode = of_node_get(spe); spu->spe_id = find_spu_unit_number(spe); spu->node = of_node_to_nid(spe); if (spu->node >= MAX_NUMNODES) { printk(KERN_WARNING "SPE %s on node %d ignored," " node number too big\n", spe->full_name, spu->node); printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); ret = -ENODEV; goto out; } ret = spu_map_device(spu); if (ret) { if (!legacy_map) { legacy_map = 1; printk(KERN_WARNING "%s: Legacy device tree found, " "trying to map old style\n", __FUNCTION__); } ret = spu_map_device_old(spu); if (ret) { printk(KERN_ERR "Unable to map %s\n", spu->name); goto out; } } ret = spu_map_interrupts(spu, spe); if (ret) { if (!legacy_irq) { legacy_irq = 1; printk(KERN_WARNING "%s: Legacy device tree found, " "trying old style irq\n", __FUNCTION__); } ret = spu_map_interrupts_old(spu, spe); if (ret) { printk(KERN_ERR "%s: could not map interrupts", spu->name); goto out_unmap; } } pr_debug("Using SPE %s %p %p %p %p %d\n", spu->name, spu->local_store, spu->problem, spu->priv1, spu->priv2, spu->number); goto out; out_unmap: spu_unmap(spu); out: return ret; }
static int __init spu_map_device(struct spu *spu) { struct device_node *np = spu->devnode; int ret = -ENODEV; spu->name = get_property(np, "name", NULL); if (!spu->name) goto out; ret = spu_map_resource(spu, 0, (void __iomem**)&spu->local_store, &spu->local_store_phys); if (ret) { pr_debug("spu_new: failed to map %s resource 0\n", np->full_name); goto out; } ret = spu_map_resource(spu, 1, (void __iomem**)&spu->problem, &spu->problem_phys); if (ret) { pr_debug("spu_new: failed to map %s resource 1\n", np->full_name); goto out_unmap; } ret = spu_map_resource(spu, 2, (void __iomem**)&spu->priv2, NULL); if (ret) { pr_debug("spu_new: failed to map %s resource 2\n", np->full_name); goto out_unmap; } if (!firmware_has_feature(FW_FEATURE_LPAR)) ret = spu_map_resource(spu, 3, (void __iomem**)&spu->priv1, NULL); if (ret) { pr_debug("spu_new: failed to map %s resource 3\n", np->full_name); goto out_unmap; } pr_debug("spu_new: %s maps:\n", np->full_name); pr_debug(" local store : 0x%016lx -> 0x%p\n", spu->local_store_phys, spu->local_store); pr_debug(" problem state : 0x%016lx -> 0x%p\n", spu->problem_phys, spu->problem); pr_debug(" priv2 : 0x%p\n", spu->priv2); pr_debug(" priv1 : 0x%p\n", spu->priv1); return 0; out_unmap: spu_unmap(spu); out: pr_debug("failed to map spe %s: %d\n", spu->name, ret); return ret; }
static int __init setup_areas(struct spu *spu) { struct table {char* name; unsigned long addr; unsigned long size;}; static const unsigned long shadow_flags = _PAGE_NO_CACHE | 3; spu_pdata(spu)->shadow = __ioremap(spu_pdata(spu)->shadow_addr, sizeof(struct spe_shadow), shadow_flags); if (!spu_pdata(spu)->shadow) { pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__); goto fail_ioremap; } spu->local_store = (__force void *)ioremap_flags(spu->local_store_phys, LS_SIZE, _PAGE_NO_CACHE); if (!spu->local_store) { pr_debug("%s:%d: ioremap local_store failed\n", __func__, __LINE__); goto fail_ioremap; } spu->problem = ioremap(spu->problem_phys, sizeof(struct spu_problem)); if (!spu->problem) { pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__); goto fail_ioremap; } spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr, sizeof(struct spu_priv2)); if (!spu->priv2) { pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__); goto fail_ioremap; } dump_areas(spu_pdata(spu)->spe_id, spu_pdata(spu)->priv2_addr, spu->problem_phys, spu->local_store_phys, spu_pdata(spu)->shadow_addr); dump_areas(spu_pdata(spu)->spe_id, (unsigned long)spu->priv2, (unsigned long)spu->problem, (unsigned long)spu->local_store, (unsigned long)spu_pdata(spu)->shadow); return 0; fail_ioremap: spu_unmap(spu); return -ENOMEM; }
static int __init spu_map_device_old(struct spu *spu) { struct device_node *node = spu->devnode; const char *prop; int ret; ret = -ENODEV; spu->name = get_property(node, "name", NULL); if (!spu->name) goto out; prop = get_property(node, "local-store", NULL); if (!prop) goto out; spu->local_store_phys = *(unsigned long *)prop; /* we use local store as ram, not io memory */ spu->local_store = (void __force *) map_spe_prop(spu, node, "local-store"); if (!spu->local_store) goto out; prop = get_property(node, "problem", NULL); if (!prop) goto out_unmap; spu->problem_phys = *(unsigned long *)prop; spu->problem = map_spe_prop(spu, node, "problem"); if (!spu->problem) goto out_unmap; spu->priv2 = map_spe_prop(spu, node, "priv2"); if (!spu->priv2) goto out_unmap; if (!firmware_has_feature(FW_FEATURE_LPAR)) { spu->priv1 = map_spe_prop(spu, node, "priv1"); if (!spu->priv1) goto out_unmap; } ret = 0; goto out; out_unmap: spu_unmap(spu); out: return ret; }
static int of_destroy_spu(struct spu *spu) { spu_unmap(spu); of_node_put(spu->devnode); return 0; }