struct nouveau_devobj {
        struct nouveau_parent base;
        struct nouveau_object *subdev[NVDEV_SUBDEV_NR];
-       bool created;
 };
 
 static const u64 disable_map[] = {
        }
 
        /* ensure requested subsystems are available for use */
-       for (i = 0, c = 0; i < NVDEV_SUBDEV_NR; i++) {
+       for (i = 1, c = 1; i < NVDEV_SUBDEV_NR; i++) {
                if (!(oclass = device->oclass[i]) || (disable & (1ULL << i)))
                        continue;
 
-               if (!device->subdev[i]) {
-                       ret = nouveau_object_ctor(nv_object(device), NULL,
-                                                 oclass, NULL, i,
-                                                 &devobj->subdev[i]);
-                       if (ret == -ENODEV)
-                               continue;
-                       if (ret)
-                               return ret;
-
-                       if (nv_iclass(devobj->subdev[i], NV_ENGINE_CLASS))
-                               nouveau_subdev_reset(devobj->subdev[i]);
-               } else {
+               if (device->subdev[i]) {
                        nouveau_object_ref(device->subdev[i],
                                          &devobj->subdev[i]);
+                       continue;
                }
 
+               ret = nouveau_object_ctor(nv_object(device), NULL,
+                                         oclass, NULL, i,
+                                         &devobj->subdev[i]);
+               if (ret == -ENODEV)
+                       continue;
+               if (ret)
+                       return ret;
+
                /* note: can't init *any* subdevs until devinit has been run
                 * due to not knowing exactly what the vbios init tables will
                 * mess with.  devinit also can't be run until all of its
                                ret = nouveau_object_inc(subdev);
                                if (ret)
                                        return ret;
+                               atomic_dec(&nv_object(device)->usecount);
+                       } else
+                       if (subdev) {
+                               nouveau_subdev_reset(subdev);
                        }
                }
        }
        nouveau_parent_destroy(&devobj->base);
 }
 
-static int
-nouveau_devobj_init(struct nouveau_object *object)
-{
-       struct nouveau_devobj *devobj = (void *)object;
-       struct nouveau_object *subdev;
-       int ret, i;
-
-       ret = nouveau_parent_init(&devobj->base);
-       if (ret)
-               return ret;
-
-       for (i = 0; devobj->created && i < NVDEV_SUBDEV_NR; i++) {
-               if ((subdev = devobj->subdev[i])) {
-                       if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
-                               ret = nouveau_object_inc(subdev);
-                               if (ret)
-                                       goto fail;
-                       }
-               }
-       }
-
-       devobj->created = true;
-       return 0;
-
-fail:
-       for (--i; i >= 0; i--) {
-               if ((subdev = devobj->subdev[i])) {
-                       if (!nv_iclass(subdev, NV_ENGINE_CLASS))
-                               nouveau_object_dec(subdev, false);
-               }
-       }
-
-       return ret;
-}
-
-static int
-nouveau_devobj_fini(struct nouveau_object *object, bool suspend)
-{
-       struct nouveau_devobj *devobj = (void *)object;
-       struct nouveau_object *subdev;
-       int ret, i;
-
-       for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) {
-               if ((subdev = devobj->subdev[i])) {
-                       if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
-                               ret = nouveau_object_dec(subdev, suspend);
-                               if (ret && suspend)
-                                       goto fail;
-                       }
-               }
-       }
-
-       ret = nouveau_parent_fini(&devobj->base, suspend);
-fail:
-       for (; ret && suspend && i < NVDEV_SUBDEV_NR; i++) {
-               if ((subdev = devobj->subdev[i])) {
-                       if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
-                               ret = nouveau_object_inc(subdev);
-                               if (ret) {
-                                       /* XXX */
-                               }
-                       }
-               }
-       }
-
-       return ret;
-}
-
 static u8
 nouveau_devobj_rd08(struct nouveau_object *object, u64 addr)
 {
 nouveau_devobj_ofuncs = {
        .ctor = nouveau_devobj_ctor,
        .dtor = nouveau_devobj_dtor,
-       .init = nouveau_devobj_init,
-       .fini = nouveau_devobj_fini,
+       .init = _nouveau_parent_init,
+       .fini = _nouveau_parent_fini,
        .rd08 = nouveau_devobj_rd08,
        .rd16 = nouveau_devobj_rd16,
        .rd32 = nouveau_devobj_rd32,
 nouveau_device_fini(struct nouveau_object *object, bool suspend)
 {
        struct nouveau_device *device = (void *)object;
-       return nouveau_subdev_fini(&device->base, suspend);
+       struct nouveau_object *subdev;
+       int ret, i;
+
+       for (i = NVDEV_SUBDEV_NR - 1; i >= 0; i--) {
+               if ((subdev = device->subdev[i])) {
+                       if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
+                               ret = nouveau_object_dec(subdev, suspend);
+                               if (ret && suspend)
+                                       goto fail;
+                       }
+               }
+       }
+
+       ret = 0;
+fail:
+       for (; ret && i < NVDEV_SUBDEV_NR; i++) {
+               if ((subdev = device->subdev[i])) {
+                       if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
+                               ret = nouveau_object_inc(subdev);
+                               if (ret) {
+                                       /* XXX */
+                               }
+                       }
+               }
+       }
+
+       return ret;
 }
 
 static int
 nouveau_device_init(struct nouveau_object *object)
 {
        struct nouveau_device *device = (void *)object;
-       return nouveau_subdev_init(&device->base);
+       struct nouveau_object *subdev;
+       int ret, i;
+
+       for (i = 0; i < NVDEV_SUBDEV_NR; i++) {
+               if ((subdev = device->subdev[i])) {
+                       if (!nv_iclass(subdev, NV_ENGINE_CLASS)) {
+                               ret = nouveau_object_inc(subdev);
+                               if (ret)
+                                       goto fail;
+                       } else {
+                               nouveau_subdev_reset(subdev);
+                       }
+               }
+       }
+
+       ret = 0;
+fail:
+       for (--i; ret && i >= 0; i--) {
+               if ((subdev = device->subdev[i])) {
+                       if (!nv_iclass(subdev, NV_ENGINE_CLASS))
+                               nouveau_object_dec(subdev, false);
+               }
+       }
+
+       return ret;
 }
 
 static void