Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[POWERPC] Celleb: consolidate spu management ops

Spu management ops in arch/platforms/cell/spu_priv1_mmio.h can be used
commonly in of based platform. This patch separates spu management ops
from native cell code and uses on celleb platform.

Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Signed-off-by: Paul Mackerras <paulus@samba.org>

authored by

Ishizaki Kou and committed by
Paul Mackerras
c9868fe0 3cdc20e5

+463 -401
+6 -1
arch/powerpc/platforms/cell/Makefile
··· 14 14 spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o 15 15 spu-priv1-$(CONFIG_PPC_CELL_NATIVE) += spu_priv1_mmio.o 16 16 17 + spu-manage-$(CONFIG_PPC_CELLEB) += spu_manage.o 18 + spu-manage-$(CONFIG_PPC_CELL_NATIVE) += spu_manage.o 19 + 17 20 obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \ 18 21 spu_coredump.o \ 19 22 $(spufs-modular-m) \ 20 - $(spu-priv1-y) spufs/ 23 + $(spu-priv1-y) \ 24 + $(spu-manage-y) \ 25 + spufs/
+420
arch/powerpc/platforms/cell/spu_manage.c
··· 1 + /* 2 + * spu management operations for of based platforms 3 + * 4 + * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 5 + * Copyright 2006 Sony Corp. 6 + * (C) Copyright 2007 TOSHIBA CORPORATION 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License as published by 10 + * the Free Software Foundation; version 2 of the License. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License along 18 + * with this program; if not, write to the Free Software Foundation, Inc., 19 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 + */ 21 + 22 + #include <linux/interrupt.h> 23 + #include <linux/list.h> 24 + #include <linux/module.h> 25 + #include <linux/ptrace.h> 26 + #include <linux/slab.h> 27 + #include <linux/wait.h> 28 + #include <linux/mm.h> 29 + #include <linux/io.h> 30 + #include <linux/mutex.h> 31 + #include <linux/device.h> 32 + 33 + #include <asm/spu.h> 34 + #include <asm/spu_priv1.h> 35 + #include <asm/firmware.h> 36 + #include <asm/prom.h> 37 + 38 + #include "interrupt.h" 39 + 40 + struct device_node *spu_devnode(struct spu *spu) 41 + { 42 + return spu->devnode; 43 + } 44 + 45 + EXPORT_SYMBOL_GPL(spu_devnode); 46 + 47 + static u64 __init find_spu_unit_number(struct device_node *spe) 48 + { 49 + const unsigned int *prop; 50 + int proplen; 51 + prop = get_property(spe, "unit-id", &proplen); 52 + if (proplen == 4) 53 + return (u64)*prop; 54 + 55 + prop = get_property(spe, "reg", &proplen); 56 + if (proplen == 4) 57 + return (u64)*prop; 58 + 59 + return 0; 60 + } 61 + 62 + static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe, 63 + const char *prop) 64 + { 65 + const struct address_prop { 66 + unsigned long address; 67 + unsigned int len; 68 + } __attribute__((packed)) *p; 69 + int proplen; 70 + 71 + unsigned long start_pfn, nr_pages; 72 + struct pglist_data *pgdata; 73 + struct zone *zone; 74 + int ret; 75 + 76 + p = get_property(spe, prop, &proplen); 77 + WARN_ON(proplen != sizeof (*p)); 78 + 79 + start_pfn = p->address >> PAGE_SHIFT; 80 + nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT; 81 + 82 + pgdata = NODE_DATA(spu->node); 83 + zone = pgdata->node_zones; 84 + 85 + ret = __add_pages(zone, start_pfn, nr_pages); 86 + 87 + return ret; 88 + } 89 + 90 + static void __iomem * __init map_spe_prop(struct spu *spu, 91 + struct device_node *n, const char *name) 92 + { 93 + const struct address_prop { 94 + unsigned long address; 95 + unsigned int len; 96 + } __attribute__((packed)) *prop; 97 + 98 + const void *p; 99 + int proplen; 100 + void __iomem *ret = NULL; 101 + int err = 0; 102 + 103 + p = get_property(n, name, &proplen); 104 + if (proplen != sizeof (struct address_prop)) 105 + return NULL; 106 + 107 + prop = p; 108 + 109 + err = cell_spuprop_present(spu, n, name); 110 + if (err && (err != -EEXIST)) 111 + goto out; 112 + 113 + ret = ioremap(prop->address, prop->len); 114 + 115 + out: 116 + return ret; 117 + } 118 + 119 + static void spu_unmap(struct spu *spu) 120 + { 121 + if (!firmware_has_feature(FW_FEATURE_LPAR)) 122 + iounmap(spu->priv1); 123 + iounmap(spu->priv2); 124 + iounmap(spu->problem); 125 + iounmap((__force u8 __iomem *)spu->local_store); 126 + } 127 + 128 + static int __init spu_map_interrupts_old(struct spu *spu, 129 + struct device_node *np) 130 + { 131 + unsigned int isrc; 132 + const u32 *tmp; 133 + int nid; 134 + 135 + /* Get the interrupt source unit from the device-tree */ 136 + tmp = get_property(np, "isrc", NULL); 137 + if (!tmp) 138 + return -ENODEV; 139 + isrc = tmp[0]; 140 + 141 + tmp = get_property(np->parent->parent, "node-id", NULL); 142 + if (!tmp) { 143 + printk(KERN_WARNING "%s: can't find node-id\n", __FUNCTION__); 144 + nid = spu->node; 145 + } else 146 + nid = tmp[0]; 147 + 148 + /* Add the node number */ 149 + isrc |= nid << IIC_IRQ_NODE_SHIFT; 150 + 151 + /* Now map interrupts of all 3 classes */ 152 + spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc); 153 + spu->irqs[1] = irq_create_mapping(NULL, IIC_IRQ_CLASS_1 | isrc); 154 + spu->irqs[2] = irq_create_mapping(NULL, IIC_IRQ_CLASS_2 | isrc); 155 + 156 + /* Right now, we only fail if class 2 failed */ 157 + return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; 158 + } 159 + 160 + static int __init spu_map_device_old(struct spu *spu) 161 + { 162 + struct device_node *node = spu->devnode; 163 + const char *prop; 164 + int ret; 165 + 166 + ret = -ENODEV; 167 + spu->name = get_property(node, "name", NULL); 168 + if (!spu->name) 169 + goto out; 170 + 171 + prop = get_property(node, "local-store", NULL); 172 + if (!prop) 173 + goto out; 174 + spu->local_store_phys = *(unsigned long *)prop; 175 + 176 + /* we use local store as ram, not io memory */ 177 + spu->local_store = (void __force *) 178 + map_spe_prop(spu, node, "local-store"); 179 + if (!spu->local_store) 180 + goto out; 181 + 182 + prop = get_property(node, "problem", NULL); 183 + if (!prop) 184 + goto out_unmap; 185 + spu->problem_phys = *(unsigned long *)prop; 186 + 187 + spu->problem = map_spe_prop(spu, node, "problem"); 188 + if (!spu->problem) 189 + goto out_unmap; 190 + 191 + spu->priv2 = map_spe_prop(spu, node, "priv2"); 192 + if (!spu->priv2) 193 + goto out_unmap; 194 + 195 + if (!firmware_has_feature(FW_FEATURE_LPAR)) { 196 + spu->priv1 = map_spe_prop(spu, node, "priv1"); 197 + if (!spu->priv1) 198 + goto out_unmap; 199 + } 200 + 201 + ret = 0; 202 + goto out; 203 + 204 + out_unmap: 205 + spu_unmap(spu); 206 + out: 207 + return ret; 208 + } 209 + 210 + static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) 211 + { 212 + struct of_irq oirq; 213 + int ret; 214 + int i; 215 + 216 + for (i=0; i < 3; i++) { 217 + ret = of_irq_map_one(np, i, &oirq); 218 + if (ret) { 219 + pr_debug("spu_new: failed to get irq %d\n", i); 220 + goto err; 221 + } 222 + ret = -EINVAL; 223 + pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0], 224 + oirq.controller->full_name); 225 + spu->irqs[i] = irq_create_of_mapping(oirq.controller, 226 + oirq.specifier, oirq.size); 227 + if (spu->irqs[i] == NO_IRQ) { 228 + pr_debug("spu_new: failed to map it !\n"); 229 + goto err; 230 + } 231 + } 232 + return 0; 233 + 234 + err: 235 + pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier, 236 + spu->name); 237 + for (; i >= 0; i--) { 238 + if (spu->irqs[i] != NO_IRQ) 239 + irq_dispose_mapping(spu->irqs[i]); 240 + } 241 + return ret; 242 + } 243 + 244 + static int spu_map_resource(struct spu *spu, int nr, 245 + void __iomem** virt, unsigned long *phys) 246 + { 247 + struct device_node *np = spu->devnode; 248 + unsigned long start_pfn, nr_pages; 249 + struct pglist_data *pgdata; 250 + struct zone *zone; 251 + struct resource resource = { }; 252 + unsigned long len; 253 + int ret; 254 + 255 + ret = of_address_to_resource(np, nr, &resource); 256 + if (ret) 257 + goto out; 258 + 259 + if (phys) 260 + *phys = resource.start; 261 + len = resource.end - resource.start + 1; 262 + *virt = ioremap(resource.start, len); 263 + if (!*virt) 264 + ret = -EINVAL; 265 + 266 + start_pfn = resource.start >> PAGE_SHIFT; 267 + nr_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 268 + 269 + pgdata = NODE_DATA(spu->node); 270 + zone = pgdata->node_zones; 271 + 272 + ret = __add_pages(zone, start_pfn, nr_pages); 273 + 274 + out: 275 + return ret; 276 + } 277 + 278 + static int __init spu_map_device(struct spu *spu) 279 + { 280 + struct device_node *np = spu->devnode; 281 + int ret = -ENODEV; 282 + 283 + spu->name = get_property(np, "name", NULL); 284 + if (!spu->name) 285 + goto out; 286 + 287 + ret = spu_map_resource(spu, 0, (void __iomem**)&spu->local_store, 288 + &spu->local_store_phys); 289 + if (ret) { 290 + pr_debug("spu_new: failed to map %s resource 0\n", 291 + np->full_name); 292 + goto out; 293 + } 294 + ret = spu_map_resource(spu, 1, (void __iomem**)&spu->problem, 295 + &spu->problem_phys); 296 + if (ret) { 297 + pr_debug("spu_new: failed to map %s resource 1\n", 298 + np->full_name); 299 + goto out_unmap; 300 + } 301 + ret = spu_map_resource(spu, 2, (void __iomem**)&spu->priv2, NULL); 302 + if (ret) { 303 + pr_debug("spu_new: failed to map %s resource 2\n", 304 + np->full_name); 305 + goto out_unmap; 306 + } 307 + if (!firmware_has_feature(FW_FEATURE_LPAR)) 308 + ret = spu_map_resource(spu, 3, 309 + (void __iomem**)&spu->priv1, NULL); 310 + if (ret) { 311 + pr_debug("spu_new: failed to map %s resource 3\n", 312 + np->full_name); 313 + goto out_unmap; 314 + } 315 + pr_debug("spu_new: %s maps:\n", np->full_name); 316 + pr_debug(" local store : 0x%016lx -> 0x%p\n", 317 + spu->local_store_phys, spu->local_store); 318 + pr_debug(" problem state : 0x%016lx -> 0x%p\n", 319 + spu->problem_phys, spu->problem); 320 + pr_debug(" priv2 : 0x%p\n", spu->priv2); 321 + pr_debug(" priv1 : 0x%p\n", spu->priv1); 322 + 323 + return 0; 324 + 325 + out_unmap: 326 + spu_unmap(spu); 327 + out: 328 + pr_debug("failed to map spe %s: %d\n", spu->name, ret); 329 + return ret; 330 + } 331 + 332 + static int __init of_enumerate_spus(int (*fn)(void *data)) 333 + { 334 + int ret; 335 + struct device_node *node; 336 + 337 + ret = -ENODEV; 338 + for (node = of_find_node_by_type(NULL, "spe"); 339 + node; node = of_find_node_by_type(node, "spe")) { 340 + ret = fn(node); 341 + if (ret) { 342 + printk(KERN_WARNING "%s: Error initializing %s\n", 343 + __FUNCTION__, node->name); 344 + break; 345 + } 346 + } 347 + return ret; 348 + } 349 + 350 + static int __init of_create_spu(struct spu *spu, void *data) 351 + { 352 + int ret; 353 + struct device_node *spe = (struct device_node *)data; 354 + static int legacy_map = 0, legacy_irq = 0; 355 + 356 + spu->devnode = of_node_get(spe); 357 + spu->spe_id = find_spu_unit_number(spe); 358 + 359 + spu->node = of_node_to_nid(spe); 360 + if (spu->node >= MAX_NUMNODES) { 361 + printk(KERN_WARNING "SPE %s on node %d ignored," 362 + " node number too big\n", spe->full_name, spu->node); 363 + printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); 364 + ret = -ENODEV; 365 + goto out; 366 + } 367 + 368 + ret = spu_map_device(spu); 369 + if (ret) { 370 + if (!legacy_map) { 371 + legacy_map = 1; 372 + printk(KERN_WARNING "%s: Legacy device tree found, " 373 + "trying to map old style\n", __FUNCTION__); 374 + } 375 + ret = spu_map_device_old(spu); 376 + if (ret) { 377 + printk(KERN_ERR "Unable to map %s\n", 378 + spu->name); 379 + goto out; 380 + } 381 + } 382 + 383 + ret = spu_map_interrupts(spu, spe); 384 + if (ret) { 385 + if (!legacy_irq) { 386 + legacy_irq = 1; 387 + printk(KERN_WARNING "%s: Legacy device tree found, " 388 + "trying old style irq\n", __FUNCTION__); 389 + } 390 + ret = spu_map_interrupts_old(spu, spe); 391 + if (ret) { 392 + printk(KERN_ERR "%s: could not map interrupts", 393 + spu->name); 394 + goto out_unmap; 395 + } 396 + } 397 + 398 + pr_debug("Using SPE %s %p %p %p %p %d\n", spu->name, 399 + spu->local_store, spu->problem, spu->priv1, 400 + spu->priv2, spu->number); 401 + goto out; 402 + 403 + out_unmap: 404 + spu_unmap(spu); 405 + out: 406 + return ret; 407 + } 408 + 409 + static int of_destroy_spu(struct spu *spu) 410 + { 411 + spu_unmap(spu); 412 + of_node_put(spu->devnode); 413 + return 0; 414 + } 415 + 416 + const struct spu_management_ops spu_management_of_ops = { 417 + .enumerate_spus = of_enumerate_spus, 418 + .create_spu = of_create_spu, 419 + .destroy_spu = of_destroy_spu, 420 + };
+22 -400
arch/powerpc/platforms/cell/spu_priv1_mmio.c
··· 37 37 #include "interrupt.h" 38 38 #include "spu_priv1_mmio.h" 39 39 40 - static DEFINE_MUTEX(add_spumem_mutex); 41 - 42 - struct spu_pdata { 43 - struct device_node *devnode; 44 - struct spu_priv1 __iomem *priv1; 45 - }; 46 - 47 - static struct spu_pdata *spu_get_pdata(struct spu *spu) 48 - { 49 - BUG_ON(!spu->pdata); 50 - return spu->pdata; 51 - } 52 - 53 - struct device_node *spu_devnode(struct spu *spu) 54 - { 55 - return spu_get_pdata(spu)->devnode; 56 - } 57 - 58 - EXPORT_SYMBOL_GPL(spu_devnode); 59 - 60 - static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe, 61 - const char *prop) 62 - { 63 - const struct address_prop { 64 - unsigned long address; 65 - unsigned int len; 66 - } __attribute__((packed)) *p; 67 - int proplen; 68 - 69 - unsigned long start_pfn, nr_pages; 70 - struct pglist_data *pgdata; 71 - struct zone *zone; 72 - int ret; 73 - 74 - p = get_property(spe, prop, &proplen); 75 - WARN_ON(proplen != sizeof (*p)); 76 - 77 - start_pfn = p->address >> PAGE_SHIFT; 78 - nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT; 79 - 80 - pgdata = NODE_DATA(spu->node); 81 - zone = pgdata->node_zones; 82 - 83 - /* XXX rethink locking here */ 84 - mutex_lock(&add_spumem_mutex); 85 - ret = __add_pages(zone, start_pfn, nr_pages); 86 - mutex_unlock(&add_spumem_mutex); 87 - 88 - return ret; 89 - } 90 - 91 - static void __iomem * __init map_spe_prop(struct spu *spu, 92 - struct device_node *n, const char *name) 93 - { 94 - const struct address_prop { 95 - unsigned long address; 96 - unsigned int len; 97 - } __attribute__((packed)) *prop; 98 - 99 - const void *p; 100 - int proplen; 101 - void __iomem *ret = NULL; 102 - int err = 0; 103 - 104 - p = get_property(n, name, &proplen); 105 - if (proplen != sizeof (struct address_prop)) 106 - return NULL; 107 - 108 - prop = p; 109 - 110 - err = cell_spuprop_present(spu, n, name); 111 - if (err && (err != -EEXIST)) 112 - goto out; 113 - 114 - ret = ioremap(prop->address, prop->len); 115 - 116 - out: 117 - return ret; 118 - } 119 - 120 - static void spu_unmap(struct spu *spu) 121 - { 122 - iounmap(spu->priv2); 123 - iounmap(spu_get_pdata(spu)->priv1); 124 - iounmap(spu->problem); 125 - iounmap((__force u8 __iomem *)spu->local_store); 126 - } 127 - 128 - static int __init spu_map_interrupts_old(struct spu *spu, 129 - struct device_node *np) 130 - { 131 - unsigned int isrc; 132 - const u32 *tmp; 133 - int nid; 134 - 135 - /* Get the interrupt source unit from the device-tree */ 136 - tmp = get_property(np, "isrc", NULL); 137 - if (!tmp) 138 - return -ENODEV; 139 - isrc = tmp[0]; 140 - 141 - tmp = get_property(np->parent->parent, "node-id", NULL); 142 - if (!tmp) { 143 - printk(KERN_WARNING "%s: can't find node-id\n", __FUNCTION__); 144 - nid = spu->node; 145 - } else 146 - nid = tmp[0]; 147 - 148 - /* Add the node number */ 149 - isrc |= nid << IIC_IRQ_NODE_SHIFT; 150 - 151 - /* Now map interrupts of all 3 classes */ 152 - spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc); 153 - spu->irqs[1] = irq_create_mapping(NULL, IIC_IRQ_CLASS_1 | isrc); 154 - spu->irqs[2] = irq_create_mapping(NULL, IIC_IRQ_CLASS_2 | isrc); 155 - 156 - /* Right now, we only fail if class 2 failed */ 157 - return spu->irqs[2] == NO_IRQ ? -EINVAL : 0; 158 - } 159 - 160 - static int __init spu_map_device_old(struct spu *spu, struct device_node *node) 161 - { 162 - const char *prop; 163 - int ret; 164 - 165 - ret = -ENODEV; 166 - spu->name = get_property(node, "name", NULL); 167 - if (!spu->name) 168 - goto out; 169 - 170 - prop = get_property(node, "local-store", NULL); 171 - if (!prop) 172 - goto out; 173 - spu->local_store_phys = *(unsigned long *)prop; 174 - 175 - /* we use local store as ram, not io memory */ 176 - spu->local_store = (void __force *) 177 - map_spe_prop(spu, node, "local-store"); 178 - if (!spu->local_store) 179 - goto out; 180 - 181 - prop = get_property(node, "problem", NULL); 182 - if (!prop) 183 - goto out_unmap; 184 - spu->problem_phys = *(unsigned long *)prop; 185 - 186 - spu->problem= map_spe_prop(spu, node, "problem"); 187 - if (!spu->problem) 188 - goto out_unmap; 189 - 190 - spu_get_pdata(spu)->priv1= map_spe_prop(spu, node, "priv1"); 191 - 192 - spu->priv2= map_spe_prop(spu, node, "priv2"); 193 - if (!spu->priv2) 194 - goto out_unmap; 195 - ret = 0; 196 - goto out; 197 - 198 - out_unmap: 199 - spu_unmap(spu); 200 - out: 201 - return ret; 202 - } 203 - 204 - static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) 205 - { 206 - struct of_irq oirq; 207 - int ret; 208 - int i; 209 - 210 - for (i=0; i < 3; i++) { 211 - ret = of_irq_map_one(np, i, &oirq); 212 - if (ret) { 213 - pr_debug("spu_new: failed to get irq %d\n", i); 214 - goto err; 215 - } 216 - ret = -EINVAL; 217 - pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0], 218 - oirq.controller->full_name); 219 - spu->irqs[i] = irq_create_of_mapping(oirq.controller, 220 - oirq.specifier, oirq.size); 221 - if (spu->irqs[i] == NO_IRQ) { 222 - pr_debug("spu_new: failed to map it !\n"); 223 - goto err; 224 - } 225 - } 226 - return 0; 227 - 228 - err: 229 - pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier, 230 - spu->name); 231 - for (; i >= 0; i--) { 232 - if (spu->irqs[i] != NO_IRQ) 233 - irq_dispose_mapping(spu->irqs[i]); 234 - } 235 - return ret; 236 - } 237 - 238 - static int spu_map_resource(struct spu *spu, int nr, 239 - void __iomem** virt, unsigned long *phys) 240 - { 241 - struct device_node *np = spu_get_pdata(spu)->devnode; 242 - unsigned long start_pfn, nr_pages; 243 - struct pglist_data *pgdata; 244 - struct zone *zone; 245 - struct resource resource = { }; 246 - unsigned long len; 247 - int ret; 248 - 249 - ret = of_address_to_resource(np, nr, &resource); 250 - if (ret) 251 - goto out; 252 - 253 - if (phys) 254 - *phys = resource.start; 255 - len = resource.end - resource.start + 1; 256 - *virt = ioremap(resource.start, len); 257 - if (!*virt) 258 - ret = -EINVAL; 259 - 260 - start_pfn = resource.start >> PAGE_SHIFT; 261 - nr_pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; 262 - 263 - pgdata = NODE_DATA(spu->node); 264 - zone = pgdata->node_zones; 265 - 266 - /* XXX rethink locking here */ 267 - mutex_lock(&add_spumem_mutex); 268 - ret = __add_pages(zone, start_pfn, nr_pages); 269 - mutex_unlock(&add_spumem_mutex); 270 - 271 - out: 272 - return ret; 273 - } 274 - 275 - static int __init spu_map_device(struct spu *spu) 276 - { 277 - struct device_node *np = spu_get_pdata(spu)->devnode; 278 - int ret = -ENODEV; 279 - 280 - spu->name = get_property(np, "name", NULL); 281 - if (!spu->name) 282 - goto out; 283 - 284 - ret = spu_map_resource(spu, 0, (void __iomem**)&spu->local_store, 285 - &spu->local_store_phys); 286 - if (ret) { 287 - pr_debug("spu_new: failed to map %s resource 0\n", 288 - np->full_name); 289 - goto out; 290 - } 291 - ret = spu_map_resource(spu, 1, (void __iomem**)&spu->problem, 292 - &spu->problem_phys); 293 - if (ret) { 294 - pr_debug("spu_new: failed to map %s resource 1\n", 295 - np->full_name); 296 - goto out_unmap; 297 - } 298 - ret = spu_map_resource(spu, 2, (void __iomem**)&spu->priv2, NULL); 299 - if (ret) { 300 - pr_debug("spu_new: failed to map %s resource 2\n", 301 - np->full_name); 302 - goto out_unmap; 303 - } 304 - if (!firmware_has_feature(FW_FEATURE_LPAR)) 305 - ret = spu_map_resource(spu, 3, 306 - (void __iomem**)&spu_get_pdata(spu)->priv1, NULL); 307 - if (ret) { 308 - pr_debug("spu_new: failed to map %s resource 3\n", 309 - np->full_name); 310 - goto out_unmap; 311 - } 312 - pr_debug("spu_new: %s maps:\n", np->full_name); 313 - pr_debug(" local store : 0x%016lx -> 0x%p\n", 314 - spu->local_store_phys, spu->local_store); 315 - pr_debug(" problem state : 0x%016lx -> 0x%p\n", 316 - spu->problem_phys, spu->problem); 317 - pr_debug(" priv2 : 0x%p\n", spu->priv2); 318 - pr_debug(" priv1 : 0x%p\n", 319 - spu_get_pdata(spu)->priv1); 320 - 321 - return 0; 322 - 323 - out_unmap: 324 - spu_unmap(spu); 325 - out: 326 - pr_debug("failed to map spe %s: %d\n", spu->name, ret); 327 - return ret; 328 - } 329 - 330 - static int __init of_enumerate_spus(int (*fn)(void *data)) 331 - { 332 - int ret; 333 - struct device_node *node; 334 - 335 - ret = -ENODEV; 336 - for (node = of_find_node_by_type(NULL, "spe"); 337 - node; node = of_find_node_by_type(node, "spe")) { 338 - ret = fn(node); 339 - if (ret) { 340 - printk(KERN_WARNING "%s: Error initializing %s\n", 341 - __FUNCTION__, node->name); 342 - break; 343 - } 344 - } 345 - return ret; 346 - } 347 - 348 - static int __init of_create_spu(struct spu *spu, void *data) 349 - { 350 - int ret; 351 - struct device_node *spe = (struct device_node *)data; 352 - 353 - spu->pdata = kzalloc(sizeof(struct spu_pdata), 354 - GFP_KERNEL); 355 - if (!spu->pdata) { 356 - ret = -ENOMEM; 357 - goto out; 358 - } 359 - spu_get_pdata(spu)->devnode = of_node_get(spe); 360 - 361 - spu->node = of_node_to_nid(spe); 362 - if (spu->node >= MAX_NUMNODES) { 363 - printk(KERN_WARNING "SPE %s on node %d ignored," 364 - " node number too big\n", spe->full_name, spu->node); 365 - printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); 366 - ret = -ENODEV; 367 - goto out_free; 368 - } 369 - 370 - ret = spu_map_device(spu); 371 - /* try old method */ 372 - if (ret) 373 - ret = spu_map_device_old(spu, spe); 374 - if (ret) 375 - goto out_free; 376 - 377 - ret = spu_map_interrupts(spu, spe); 378 - if (ret) 379 - ret = spu_map_interrupts_old(spu, spe); 380 - if (ret) 381 - goto out_unmap; 382 - 383 - pr_debug(KERN_DEBUG "Using SPE %s %p %p %p %p %d\n", spu->name, 384 - spu->local_store, spu->problem, spu_get_pdata(spu)->priv1, 385 - spu->priv2, spu->number); 386 - goto out; 387 - 388 - out_unmap: 389 - spu_unmap(spu); 390 - out_free: 391 - kfree(spu->pdata); 392 - spu->pdata = NULL; 393 - out: 394 - return ret; 395 - } 396 - 397 - static int of_destroy_spu(struct spu *spu) 398 - { 399 - spu_unmap(spu); 400 - of_node_put(spu_get_pdata(spu)->devnode); 401 - kfree(spu->pdata); 402 - spu->pdata = NULL; 403 - return 0; 404 - } 405 - 406 - const struct spu_management_ops spu_management_of_ops = { 407 - .enumerate_spus = of_enumerate_spus, 408 - .create_spu = of_create_spu, 409 - .destroy_spu = of_destroy_spu, 410 - }; 411 - 412 40 static void int_mask_and(struct spu *spu, int class, u64 mask) 413 41 { 414 42 u64 old_mask; 415 43 416 - old_mask = in_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class]); 417 - out_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class], 418 - old_mask & mask); 44 + old_mask = in_be64(&spu->priv1->int_mask_RW[class]); 45 + out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask); 419 46 } 420 47 421 48 static void int_mask_or(struct spu *spu, int class, u64 mask) 422 49 { 423 50 u64 old_mask; 424 51 425 - old_mask = in_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class]); 426 - out_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class], 427 - old_mask | mask); 52 + old_mask = in_be64(&spu->priv1->int_mask_RW[class]); 53 + out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask); 428 54 } 429 55 430 56 static void int_mask_set(struct spu *spu, int class, u64 mask) 431 57 { 432 - out_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class], mask); 58 + out_be64(&spu->priv1->int_mask_RW[class], mask); 433 59 } 434 60 435 61 static u64 int_mask_get(struct spu *spu, int class) 436 62 { 437 - return in_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class]); 63 + return in_be64(&spu->priv1->int_mask_RW[class]); 438 64 } 439 65 440 66 static void int_stat_clear(struct spu *spu, int class, u64 stat) 441 67 { 442 - out_be64(&spu_get_pdata(spu)->priv1->int_stat_RW[class], stat); 68 + out_be64(&spu->priv1->int_stat_RW[class], stat); 443 69 } 444 70 445 71 static u64 int_stat_get(struct spu *spu, int class) 446 72 { 447 - return in_be64(&spu_get_pdata(spu)->priv1->int_stat_RW[class]); 73 + return in_be64(&spu->priv1->int_stat_RW[class]); 448 74 } 449 75 450 76 static void cpu_affinity_set(struct spu *spu, int cpu) 451 77 { 452 78 u64 target = iic_get_target_id(cpu); 453 79 u64 route = target << 48 | target << 32 | target << 16; 454 - out_be64(&spu_get_pdata(spu)->priv1->int_route_RW, route); 80 + out_be64(&spu->priv1->int_route_RW, route); 455 81 } 456 82 457 83 static u64 mfc_dar_get(struct spu *spu) 458 84 { 459 - return in_be64(&spu_get_pdata(spu)->priv1->mfc_dar_RW); 85 + return in_be64(&spu->priv1->mfc_dar_RW); 460 86 } 461 87 462 88 static u64 mfc_dsisr_get(struct spu *spu) 463 89 { 464 - return in_be64(&spu_get_pdata(spu)->priv1->mfc_dsisr_RW); 90 + return in_be64(&spu->priv1->mfc_dsisr_RW); 465 91 } 466 92 467 93 static void mfc_dsisr_set(struct spu *spu, u64 dsisr) 468 94 { 469 - out_be64(&spu_get_pdata(spu)->priv1->mfc_dsisr_RW, dsisr); 95 + out_be64(&spu->priv1->mfc_dsisr_RW, dsisr); 470 96 } 471 97 472 98 static void mfc_sdr_setup(struct spu *spu) 473 99 { 474 - out_be64(&spu_get_pdata(spu)->priv1->mfc_sdr_RW, mfspr(SPRN_SDR1)); 100 + out_be64(&spu->priv1->mfc_sdr_RW, mfspr(SPRN_SDR1)); 475 101 } 476 102 477 103 static void mfc_sr1_set(struct spu *spu, u64 sr1) 478 104 { 479 - out_be64(&spu_get_pdata(spu)->priv1->mfc_sr1_RW, sr1); 105 + out_be64(&spu->priv1->mfc_sr1_RW, sr1); 480 106 } 481 107 482 108 static u64 mfc_sr1_get(struct spu *spu) 483 109 { 484 - return in_be64(&spu_get_pdata(spu)->priv1->mfc_sr1_RW); 110 + return in_be64(&spu->priv1->mfc_sr1_RW); 485 111 } 486 112 487 113 static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id) 488 114 { 489 - out_be64(&spu_get_pdata(spu)->priv1->mfc_tclass_id_RW, tclass_id); 115 + out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id); 490 116 } 491 117 492 118 static u64 mfc_tclass_id_get(struct spu *spu) 493 119 { 494 - return in_be64(&spu_get_pdata(spu)->priv1->mfc_tclass_id_RW); 120 + return in_be64(&spu->priv1->mfc_tclass_id_RW); 495 121 } 496 122 497 123 static void tlb_invalidate(struct spu *spu) 498 124 { 499 - out_be64(&spu_get_pdata(spu)->priv1->tlb_invalidate_entry_W, 0ul); 125 + out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul); 500 126 } 501 127 502 128 static void resource_allocation_groupID_set(struct spu *spu, u64 id) 503 129 { 504 - out_be64(&spu_get_pdata(spu)->priv1->resource_allocation_groupID_RW, 505 - id); 130 + out_be64(&spu->priv1->resource_allocation_groupID_RW, id); 506 131 } 507 132 508 133 static u64 resource_allocation_groupID_get(struct spu *spu) 509 134 { 510 - return in_be64( 511 - &spu_get_pdata(spu)->priv1->resource_allocation_groupID_RW); 135 + return in_be64(&spu->priv1->resource_allocation_groupID_RW); 512 136 } 513 137 514 138 static void resource_allocation_enable_set(struct spu *spu, u64 enable) 515 139 { 516 - out_be64(&spu_get_pdata(spu)->priv1->resource_allocation_enable_RW, 517 - enable); 140 + out_be64(&spu->priv1->resource_allocation_enable_RW, enable); 518 141 } 519 142 520 143 static u64 resource_allocation_enable_get(struct spu *spu) 521 144 { 522 - return in_be64( 523 - &spu_get_pdata(spu)->priv1->resource_allocation_enable_RW); 145 + return in_be64(&spu->priv1->resource_allocation_enable_RW); 524 146 } 525 147 526 148 const struct spu_priv1_ops spu_priv1_mmio_ops =
+13
include/asm-powerpc/spu.h
··· 104 104 105 105 struct spu_context; 106 106 struct spu_runqueue; 107 + struct device_node; 107 108 108 109 struct spu { 109 110 const char *name; ··· 143 142 char irq_c1[8]; 144 143 char irq_c2[8]; 145 144 145 + u64 spe_id; 146 + 146 147 void* pdata; /* platform private data */ 148 + 149 + /* of based platforms only */ 150 + struct device_node *devnode; 151 + 152 + /* native only */ 153 + struct spu_priv1 __iomem *priv1; 154 + 155 + /* beat only */ 156 + u64 shadow_int_mask_RW[3]; 157 + 147 158 struct sys_device sysdev; 148 159 }; 149 160
+2
include/asm-powerpc/spu_priv1.h
··· 206 206 */ 207 207 208 208 extern const struct spu_priv1_ops spu_priv1_mmio_ops; 209 + extern const struct spu_priv1_ops spu_priv1_beat_ops; 210 + 209 211 extern const struct spu_management_ops spu_management_of_ops; 210 212 211 213 #endif /* __KERNEL__ */