base.c revision 586491e6fc27f1783081955fd26d70789ddb3a07
1/* 2 * Copyright 2012 Red Hat Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: Ben Skeggs 23 */ 24 25#include <core/object.h> 26#include <core/device.h> 27#include <core/client.h> 28#include <core/option.h> 29#include <nvif/unpack.h> 30#include <nvif/class.h> 31#include <core/class.h> 32 33#include <subdev/fb.h> 34#include <subdev/instmem.h> 35 36#include "priv.h" 37#include "acpi.h" 38 39static DEFINE_MUTEX(nv_devices_mutex); 40static LIST_HEAD(nv_devices); 41 42struct nouveau_device * 43nouveau_device_find(u64 name) 44{ 45 struct nouveau_device *device, *match = NULL; 46 mutex_lock(&nv_devices_mutex); 47 list_for_each_entry(device, &nv_devices, head) { 48 if (device->handle == name) { 49 match = device; 50 break; 51 } 52 } 53 mutex_unlock(&nv_devices_mutex); 54 return match; 55} 56 57int 58nouveau_device_list(u64 *name, int size) 59{ 60 struct nouveau_device *device; 61 int nr = 0; 62 mutex_lock(&nv_devices_mutex); 63 list_for_each_entry(device, &nv_devices, head) { 64 if (nr++ < size) 65 name[nr - 1] = device->handle; 66 } 67 mutex_unlock(&nv_devices_mutex); 68 return nr; 69} 70 71/****************************************************************************** 72 * nouveau_devobj (0x0080): class implementation 73 *****************************************************************************/ 74 75struct nouveau_devobj { 76 struct nouveau_parent base; 77 struct nouveau_object *subdev[NVDEV_SUBDEV_NR]; 78}; 79 80static int 81nouveau_devobj_info(struct nouveau_object *object, void *data, u32 size) 82{ 83 struct nouveau_device *device = nv_device(object); 84 struct nouveau_fb *pfb = nouveau_fb(device); 85 struct nouveau_instmem *imem = nouveau_instmem(device); 86 union { 87 struct nv_device_info_v0 v0; 88 } *args = data; 89 int ret; 90 91 nv_ioctl(object, "device info size %d\n", size); 92 if (nvif_unpack(args->v0, 0, 0, false)) { 93 nv_ioctl(object, "device info vers %d\n", args->v0.version); 94 } else 95 return ret; 96 97 switch (device->chipset) { 98 case 0x01a: 99 case 0x01f: 100 case 0x04c: 101 case 0x04e: 102 case 0x063: 103 case 0x067: 104 case 0x068: 105 case 0x0aa: 106 case 0x0ac: 107 case 0x0af: 108 args->v0.platform = NV_DEVICE_INFO_V0_IGP; 109 break; 110 default: 111 if (device->pdev) { 112 if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP)) 113 args->v0.platform = NV_DEVICE_INFO_V0_AGP; 114 else 115 if (pci_is_pcie(device->pdev)) 116 args->v0.platform = NV_DEVICE_INFO_V0_PCIE; 117 else 118 args->v0.platform = NV_DEVICE_INFO_V0_PCI; 119 } else { 120 args->v0.platform = NV_DEVICE_INFO_V0_SOC; 121 } 122 break; 123 } 124 125 switch (device->card_type) { 126 case NV_04: args->v0.family = NV_DEVICE_INFO_V0_TNT; break; 127 case NV_10: 128 case NV_11: args->v0.family = NV_DEVICE_INFO_V0_CELSIUS; break; 129 case NV_20: args->v0.family = NV_DEVICE_INFO_V0_KELVIN; break; 130 case NV_30: args->v0.family = NV_DEVICE_INFO_V0_RANKINE; break; 131 case NV_40: args->v0.family = NV_DEVICE_INFO_V0_CURIE; break; 132 case NV_50: args->v0.family = NV_DEVICE_INFO_V0_TESLA; break; 133 case NV_C0: args->v0.family = NV_DEVICE_INFO_V0_FERMI; break; 134 case NV_E0: args->v0.family = NV_DEVICE_INFO_V0_KEPLER; break; 135 case GM100: args->v0.family = NV_DEVICE_INFO_V0_MAXWELL; break; 136 default: 137 args->v0.family = 0; 138 break; 139 } 140 141 args->v0.chipset = device->chipset; 142 args->v0.revision = device->chipset >= 0x10 ? nv_rd32(device, 0) : 0x00; 143 if (pfb) args->v0.ram_size = args->v0.ram_user = pfb->ram->size; 144 else args->v0.ram_size = args->v0.ram_user = 0; 145 if (imem) args->v0.ram_user = args->v0.ram_user - imem->reserved; 146 return 0; 147} 148 149static int 150nouveau_devobj_mthd(struct nouveau_object *object, u32 mthd, 151 void *data, u32 size) 152{ 153 switch (mthd) { 154 case NV_DEVICE_V0_INFO: 155 return nouveau_devobj_info(object, data, size); 156 default: 157 break; 158 } 159 return -EINVAL; 160} 161 162static u8 163nouveau_devobj_rd08(struct nouveau_object *object, u64 addr) 164{ 165 return nv_rd08(object->engine, addr); 166} 167 168static u16 169nouveau_devobj_rd16(struct nouveau_object *object, u64 addr) 170{ 171 return nv_rd16(object->engine, addr); 172} 173 174static u32 175nouveau_devobj_rd32(struct nouveau_object *object, u64 addr) 176{ 177 return nv_rd32(object->engine, addr); 178} 179 180static void 181nouveau_devobj_wr08(struct nouveau_object *object, u64 addr, u8 data) 182{ 183 nv_wr08(object->engine, addr, data); 184} 185 186static void 187nouveau_devobj_wr16(struct nouveau_object *object, u64 addr, u16 data) 188{ 189 nv_wr16(object->engine, addr, data); 190} 191 192static void 193nouveau_devobj_wr32(struct nouveau_object *object, u64 addr, u32 data) 194{ 195 nv_wr32(object->engine, addr, data); 196} 197 198static int 199nouveau_devobj_map(struct nouveau_object *object, u64 *addr, u32 *size) 200{ 201 struct nouveau_device *device = nv_device(object); 202 *addr = nv_device_resource_start(device, 0); 203 *size = nv_device_resource_len(device, 0); 204 return 0; 205} 206 207static const u64 disable_map[] = { 208 [NVDEV_SUBDEV_VBIOS] = NV_DEVICE_V0_DISABLE_VBIOS, 209 [NVDEV_SUBDEV_DEVINIT] = NV_DEVICE_V0_DISABLE_CORE, 210 [NVDEV_SUBDEV_GPIO] = NV_DEVICE_V0_DISABLE_CORE, 211 [NVDEV_SUBDEV_I2C] = NV_DEVICE_V0_DISABLE_CORE, 212 [NVDEV_SUBDEV_CLOCK] = NV_DEVICE_V0_DISABLE_CORE, 213 [NVDEV_SUBDEV_MXM] = NV_DEVICE_V0_DISABLE_CORE, 214 [NVDEV_SUBDEV_MC] = NV_DEVICE_V0_DISABLE_CORE, 215 [NVDEV_SUBDEV_BUS] = NV_DEVICE_V0_DISABLE_CORE, 216 [NVDEV_SUBDEV_TIMER] = NV_DEVICE_V0_DISABLE_CORE, 217 [NVDEV_SUBDEV_FB] = NV_DEVICE_V0_DISABLE_CORE, 218 [NVDEV_SUBDEV_LTCG] = NV_DEVICE_V0_DISABLE_CORE, 219 [NVDEV_SUBDEV_IBUS] = NV_DEVICE_V0_DISABLE_CORE, 220 [NVDEV_SUBDEV_INSTMEM] = NV_DEVICE_V0_DISABLE_CORE, 221 [NVDEV_SUBDEV_VM] = NV_DEVICE_V0_DISABLE_CORE, 222 [NVDEV_SUBDEV_BAR] = NV_DEVICE_V0_DISABLE_CORE, 223 [NVDEV_SUBDEV_VOLT] = NV_DEVICE_V0_DISABLE_CORE, 224 [NVDEV_SUBDEV_THERM] = NV_DEVICE_V0_DISABLE_CORE, 225 [NVDEV_SUBDEV_PWR] = NV_DEVICE_V0_DISABLE_CORE, 226 [NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_V0_DISABLE_CORE, 227 [NVDEV_ENGINE_PERFMON] = NV_DEVICE_V0_DISABLE_CORE, 228 [NVDEV_ENGINE_FIFO] = NV_DEVICE_V0_DISABLE_FIFO, 229 [NVDEV_ENGINE_SW] = NV_DEVICE_V0_DISABLE_FIFO, 230 [NVDEV_ENGINE_GR] = NV_DEVICE_V0_DISABLE_GRAPH, 231 [NVDEV_ENGINE_MPEG] = NV_DEVICE_V0_DISABLE_MPEG, 232 [NVDEV_ENGINE_ME] = NV_DEVICE_V0_DISABLE_ME, 233 [NVDEV_ENGINE_VP] = NV_DEVICE_V0_DISABLE_VP, 234 [NVDEV_ENGINE_CRYPT] = NV_DEVICE_V0_DISABLE_CRYPT, 235 [NVDEV_ENGINE_BSP] = NV_DEVICE_V0_DISABLE_BSP, 236 [NVDEV_ENGINE_PPP] = NV_DEVICE_V0_DISABLE_PPP, 237 [NVDEV_ENGINE_COPY0] = NV_DEVICE_V0_DISABLE_COPY0, 238 [NVDEV_ENGINE_COPY1] = NV_DEVICE_V0_DISABLE_COPY1, 239 [NVDEV_ENGINE_VIC] = NV_DEVICE_V0_DISABLE_VIC, 240 [NVDEV_ENGINE_VENC] = NV_DEVICE_V0_DISABLE_VENC, 241 [NVDEV_ENGINE_DISP] = NV_DEVICE_V0_DISABLE_DISP, 242 [NVDEV_SUBDEV_NR] = 0, 243}; 244 245static void 246nouveau_devobj_dtor(struct nouveau_object *object) 247{ 248 struct nouveau_devobj *devobj = (void *)object; 249 int i; 250 251 for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) 252 nouveau_object_ref(NULL, &devobj->subdev[i]); 253 254 nouveau_parent_destroy(&devobj->base); 255} 256 257static struct nouveau_oclass 258nouveau_devobj_oclass_super = { 259 .handle = NV_DEVICE, 260 .ofuncs = &(struct nouveau_ofuncs) { 261 .dtor = nouveau_devobj_dtor, 262 .init = _nouveau_parent_init, 263 .fini = _nouveau_parent_fini, 264 .mthd = nouveau_devobj_mthd, 265 .map = nouveau_devobj_map, 266 .rd08 = nouveau_devobj_rd08, 267 .rd16 = nouveau_devobj_rd16, 268 .rd32 = nouveau_devobj_rd32, 269 .wr08 = nouveau_devobj_wr08, 270 .wr16 = nouveau_devobj_wr16, 271 .wr32 = nouveau_devobj_wr32, 272 } 273}; 274 275static int 276nouveau_devobj_ctor(struct nouveau_object *parent, 277 struct nouveau_object *engine, 278 struct nouveau_oclass *oclass, void *data, u32 size, 279 struct nouveau_object **pobject) 280{ 281 union { 282 struct nv_device_v0 v0; 283 } *args = data; 284 struct nouveau_client *client = nv_client(parent); 285 struct nouveau_device *device; 286 struct nouveau_devobj *devobj; 287 u32 boot0, strap; 288 u64 disable, mmio_base, mmio_size; 289 void __iomem *map; 290 int ret, i, c; 291 292 nv_ioctl(parent, "create device size %d\n", size); 293 if (nvif_unpack(args->v0, 0, 0, false)) { 294 nv_ioctl(parent, "create device v%d device %016llx " 295 "disable %016llx debug0 %016llx\n", 296 args->v0.version, args->v0.device, 297 args->v0.disable, args->v0.debug0); 298 } else 299 return ret; 300 301 /* give priviledged clients register access */ 302 if (client->super) 303 oclass = &nouveau_devobj_oclass_super; 304 305 /* find the device subdev that matches what the client requested */ 306 device = nv_device(client->device); 307 if (args->v0.device != ~0) { 308 device = nouveau_device_find(args->v0.device); 309 if (!device) 310 return -ENODEV; 311 } 312 313 ret = nouveau_parent_create(parent, nv_object(device), oclass, 0, 314 nouveau_control_oclass, 315 (1ULL << NVDEV_ENGINE_DMAOBJ) | 316 (1ULL << NVDEV_ENGINE_FIFO) | 317 (1ULL << NVDEV_ENGINE_DISP) | 318 (1ULL << NVDEV_ENGINE_PERFMON), &devobj); 319 *pobject = nv_object(devobj); 320 if (ret) 321 return ret; 322 323 mmio_base = nv_device_resource_start(device, 0); 324 mmio_size = nv_device_resource_len(device, 0); 325 326 /* translate api disable mask into internal mapping */ 327 disable = args->v0.debug0; 328 for (i = 0; i < NVDEV_SUBDEV_NR; i++) { 329 if (args->v0.disable & disable_map[i]) 330 disable |= (1ULL << i); 331 } 332 333 /* identify the chipset, and determine classes of subdev/engines */ 334 if (!(args->v0.disable & NV_DEVICE_V0_DISABLE_IDENTIFY) && 335 !device->card_type) { 336 map = ioremap(mmio_base, 0x102000); 337 if (map == NULL) 338 return -ENOMEM; 339 340 /* switch mmio to cpu's native endianness */ 341#ifndef __BIG_ENDIAN 342 if (ioread32_native(map + 0x000004) != 0x00000000) 343#else 344 if (ioread32_native(map + 0x000004) == 0x00000000) 345#endif 346 iowrite32_native(0x01000001, map + 0x000004); 347 348 /* read boot0 and strapping information */ 349 boot0 = ioread32_native(map + 0x000000); 350 strap = ioread32_native(map + 0x101000); 351 iounmap(map); 352 353 /* determine chipset and derive architecture from it */ 354 if ((boot0 & 0x1f000000) > 0) { 355 device->chipset = (boot0 & 0x1ff00000) >> 20; 356 switch (device->chipset & 0x1f0) { 357 case 0x010: { 358 if (0x461 & (1 << (device->chipset & 0xf))) 359 device->card_type = NV_10; 360 else 361 device->card_type = NV_11; 362 break; 363 } 364 case 0x020: device->card_type = NV_20; break; 365 case 0x030: device->card_type = NV_30; break; 366 case 0x040: 367 case 0x060: device->card_type = NV_40; break; 368 case 0x050: 369 case 0x080: 370 case 0x090: 371 case 0x0a0: device->card_type = NV_50; break; 372 case 0x0c0: 373 case 0x0d0: device->card_type = NV_C0; break; 374 case 0x0e0: 375 case 0x0f0: 376 case 0x100: device->card_type = NV_E0; break; 377 case 0x110: device->card_type = GM100; break; 378 default: 379 break; 380 } 381 } else 382 if ((boot0 & 0xff00fff0) == 0x20004000) { 383 if (boot0 & 0x00f00000) 384 device->chipset = 0x05; 385 else 386 device->chipset = 0x04; 387 device->card_type = NV_04; 388 } 389 390 switch (device->card_type) { 391 case NV_04: ret = nv04_identify(device); break; 392 case NV_10: 393 case NV_11: ret = nv10_identify(device); break; 394 case NV_20: ret = nv20_identify(device); break; 395 case NV_30: ret = nv30_identify(device); break; 396 case NV_40: ret = nv40_identify(device); break; 397 case NV_50: ret = nv50_identify(device); break; 398 case NV_C0: ret = nvc0_identify(device); break; 399 case NV_E0: ret = nve0_identify(device); break; 400 case GM100: ret = gm100_identify(device); break; 401 default: 402 ret = -EINVAL; 403 break; 404 } 405 406 if (ret) { 407 nv_error(device, "unknown chipset, 0x%08x\n", boot0); 408 return ret; 409 } 410 411 nv_info(device, "BOOT0 : 0x%08x\n", boot0); 412 nv_info(device, "Chipset: %s (NV%02X)\n", 413 device->cname, device->chipset); 414 nv_info(device, "Family : NV%02X\n", device->card_type); 415 416 /* determine frequency of timing crystal */ 417 if ( device->card_type <= NV_10 || device->chipset < 0x17 || 418 (device->chipset >= 0x20 && device->chipset < 0x25)) 419 strap &= 0x00000040; 420 else 421 strap &= 0x00400040; 422 423 switch (strap) { 424 case 0x00000000: device->crystal = 13500; break; 425 case 0x00000040: device->crystal = 14318; break; 426 case 0x00400000: device->crystal = 27000; break; 427 case 0x00400040: device->crystal = 25000; break; 428 } 429 430 nv_debug(device, "crystal freq: %dKHz\n", device->crystal); 431 } 432 433 if (!(args->v0.disable & NV_DEVICE_V0_DISABLE_MMIO) && 434 !nv_subdev(device)->mmio) { 435 nv_subdev(device)->mmio = ioremap(mmio_base, mmio_size); 436 if (!nv_subdev(device)->mmio) { 437 nv_error(device, "unable to map device registers\n"); 438 return -ENOMEM; 439 } 440 } 441 442 /* ensure requested subsystems are available for use */ 443 for (i = 1, c = 1; i < NVDEV_SUBDEV_NR; i++) { 444 if (!(oclass = device->oclass[i]) || (disable & (1ULL << i))) 445 continue; 446 447 if (device->subdev[i]) { 448 nouveau_object_ref(device->subdev[i], 449 &devobj->subdev[i]); 450 continue; 451 } 452 453 ret = nouveau_object_ctor(nv_object(device), NULL, 454 oclass, NULL, i, 455 &devobj->subdev[i]); 456 if (ret == -ENODEV) 457 continue; 458 if (ret) 459 return ret; 460 461 device->subdev[i] = devobj->subdev[i]; 462 463 /* note: can't init *any* subdevs until devinit has been run 464 * due to not knowing exactly what the vbios init tables will 465 * mess with. devinit also can't be run until all of its 466 * dependencies have been created. 467 * 468 * this code delays init of any subdev until all of devinit's 469 * dependencies have been created, and then initialises each 470 * subdev in turn as they're created. 471 */ 472 while (i >= NVDEV_SUBDEV_DEVINIT_LAST && c <= i) { 473 struct nouveau_object *subdev = devobj->subdev[c++]; 474 if (subdev && !nv_iclass(subdev, NV_ENGINE_CLASS)) { 475 ret = nouveau_object_inc(subdev); 476 if (ret) 477 return ret; 478 atomic_dec(&nv_object(device)->usecount); 479 } else 480 if (subdev) { 481 nouveau_subdev_reset(subdev); 482 } 483 } 484 } 485 486 return 0; 487} 488 489static struct nouveau_ofuncs 490nouveau_devobj_ofuncs = { 491 .ctor = nouveau_devobj_ctor, 492 .dtor = nouveau_devobj_dtor, 493 .init = _nouveau_parent_init, 494 .fini = _nouveau_parent_fini, 495 .mthd = nouveau_devobj_mthd, 496}; 497 498/****************************************************************************** 499 * nouveau_device: engine functions 500 *****************************************************************************/ 501 502static struct nouveau_oclass 503nouveau_device_sclass[] = { 504 { 0x0080, &nouveau_devobj_ofuncs }, 505 {} 506}; 507 508static int 509nouveau_device_event_ctor(void *data, u32 size, struct nvkm_notify *notify) 510{ 511 if (!WARN_ON(size != 0)) { 512 notify->size = 0; 513 notify->types = 1; 514 notify->index = 0; 515 return 0; 516 } 517 return -EINVAL; 518} 519 520static const struct nvkm_event_func 521nouveau_device_event_func = { 522 .ctor = nouveau_device_event_ctor, 523}; 524 525static int 526nouveau_device_fini(struct nouveau_object *object, bool suspend) 527{ 528 struct nouveau_device *device = (void *)object; 529 struct nouveau_object *subdev; 530 int ret, i; 531 532 for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) { 533 if ((subdev = device->subdev[i])) { 534 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) { 535 ret = nouveau_object_dec(subdev, suspend); 536 if (ret && suspend) 537 goto fail; 538 } 539 } 540 } 541 542 ret = nvkm_acpi_fini(device, suspend); 543fail: 544 for (; ret && i < NVDEV_SUBDEV_NR; i++) { 545 if ((subdev = device->subdev[i])) { 546 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) { 547 ret = nouveau_object_inc(subdev); 548 if (ret) { 549 /* XXX */ 550 } 551 } 552 } 553 } 554 555 return ret; 556} 557 558static int 559nouveau_device_init(struct nouveau_object *object) 560{ 561 struct nouveau_device *device = (void *)object; 562 struct nouveau_object *subdev; 563 int ret, i = 0; 564 565 ret = nvkm_acpi_init(device); 566 if (ret) 567 goto fail; 568 569 for (i = 0; i < NVDEV_SUBDEV_NR; i++) { 570 if ((subdev = device->subdev[i])) { 571 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) { 572 ret = nouveau_object_inc(subdev); 573 if (ret) 574 goto fail; 575 } else { 576 nouveau_subdev_reset(subdev); 577 } 578 } 579 } 580 581 ret = 0; 582fail: 583 for (--i; ret && i >= 0; i--) { 584 if ((subdev = device->subdev[i])) { 585 if (!nv_iclass(subdev, NV_ENGINE_CLASS)) 586 nouveau_object_dec(subdev, false); 587 } 588 } 589 590 if (ret) 591 nvkm_acpi_fini(device, false); 592 return ret; 593} 594 595static void 596nouveau_device_dtor(struct nouveau_object *object) 597{ 598 struct nouveau_device *device = (void *)object; 599 600 nvkm_event_fini(&device->event); 601 602 mutex_lock(&nv_devices_mutex); 603 list_del(&device->head); 604 mutex_unlock(&nv_devices_mutex); 605 606 if (nv_subdev(device)->mmio) 607 iounmap(nv_subdev(device)->mmio); 608 609 nouveau_engine_destroy(&device->base); 610} 611 612resource_size_t 613nv_device_resource_start(struct nouveau_device *device, unsigned int bar) 614{ 615 if (nv_device_is_pci(device)) { 616 return pci_resource_start(device->pdev, bar); 617 } else { 618 struct resource *res; 619 res = platform_get_resource(device->platformdev, 620 IORESOURCE_MEM, bar); 621 if (!res) 622 return 0; 623 return res->start; 624 } 625} 626 627resource_size_t 628nv_device_resource_len(struct nouveau_device *device, unsigned int bar) 629{ 630 if (nv_device_is_pci(device)) { 631 return pci_resource_len(device->pdev, bar); 632 } else { 633 struct resource *res; 634 res = platform_get_resource(device->platformdev, 635 IORESOURCE_MEM, bar); 636 if (!res) 637 return 0; 638 return resource_size(res); 639 } 640} 641 642int 643nv_device_get_irq(struct nouveau_device *device, bool stall) 644{ 645 if (nv_device_is_pci(device)) { 646 return device->pdev->irq; 647 } else { 648 return platform_get_irq_byname(device->platformdev, 649 stall ? "stall" : "nonstall"); 650 } 651} 652 653static struct nouveau_oclass 654nouveau_device_oclass = { 655 .handle = NV_ENGINE(DEVICE, 0x00), 656 .ofuncs = &(struct nouveau_ofuncs) { 657 .dtor = nouveau_device_dtor, 658 .init = nouveau_device_init, 659 .fini = nouveau_device_fini, 660 }, 661}; 662 663int 664nouveau_device_create_(void *dev, enum nv_bus_type type, u64 name, 665 const char *sname, const char *cfg, const char *dbg, 666 int length, void **pobject) 667{ 668 struct nouveau_device *device; 669 int ret = -EEXIST; 670 671 mutex_lock(&nv_devices_mutex); 672 list_for_each_entry(device, &nv_devices, head) { 673 if (device->handle == name) 674 goto done; 675 } 676 677 ret = nouveau_engine_create_(NULL, NULL, &nouveau_device_oclass, true, 678 "DEVICE", "device", length, pobject); 679 device = *pobject; 680 if (ret) 681 goto done; 682 683 switch (type) { 684 case NOUVEAU_BUS_PCI: 685 device->pdev = dev; 686 break; 687 case NOUVEAU_BUS_PLATFORM: 688 device->platformdev = dev; 689 break; 690 } 691 device->handle = name; 692 device->cfgopt = cfg; 693 device->dbgopt = dbg; 694 device->name = sname; 695 696 nv_subdev(device)->debug = nouveau_dbgopt(device->dbgopt, "DEVICE"); 697 nv_engine(device)->sclass = nouveau_device_sclass; 698 list_add(&device->head, &nv_devices); 699 700 ret = nvkm_event_init(&nouveau_device_event_func, 1, 1, 701 &device->event); 702done: 703 mutex_unlock(&nv_devices_mutex); 704 return ret; 705} 706