#ifndef __NVKM_FUSE_H__
 #define __NVKM_FUSE_H__
 #include <core/subdev.h>
-#include <core/device.h>
 
 struct nvkm_fuse {
-       struct nvkm_subdev subdev;
        const struct nvkm_fuse_func *func;
+       struct nvkm_subdev subdev;
+       spinlock_t lock;
 };
 
-struct nvkm_fuse_func {
-       u32 (*read)(struct nvkm_fuse *, u32 addr);
-};
-
-static inline struct nvkm_fuse *
-nvkm_fuse(void *obj)
-{
-       return (void *)nvkm_subdev(obj, NVDEV_SUBDEV_FUSE);
-}
-
-#define nvkm_fuse_create(p, e, o, d)                                        \
-       nvkm_fuse_create_((p), (e), (o), sizeof(**d), (void **)d)
-
-int  nvkm_fuse_create_(struct nvkm_object *, struct nvkm_object *,
-                         struct nvkm_oclass *, int, void **);
-void _nvkm_fuse_dtor(struct nvkm_object *);
-int  _nvkm_fuse_init(struct nvkm_object *);
-#define _nvkm_fuse_fini _nvkm_subdev_fini
+u32 nvkm_fuse_read(struct nvkm_fuse *, u32 addr);
 
-extern struct nvkm_oclass nv50_fuse_oclass;
-extern struct nvkm_oclass gf100_fuse_oclass;
-extern struct nvkm_oclass gm107_fuse_oclass;
+int nv50_fuse_new(struct nvkm_device *, int, struct nvkm_fuse **);
+int gf100_fuse_new(struct nvkm_device *, int, struct nvkm_fuse **);
+int gm107_fuse_new(struct nvkm_device *, int, struct nvkm_fuse **);
 #endif
 
        .clk = nv50_clk_new,
        .devinit = nv50_devinit_new,
        .fb = nv50_fb_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
 //     .gpio = nv50_gpio_new,
 //     .i2c = nv50_i2c_new,
 //     .imem = nv50_instmem_new,
        .clk = g84_clk_new,
        .devinit = g84_devinit_new,
        .fb = g84_fb_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
 //     .gpio = nv50_gpio_new,
 //     .i2c = nv50_i2c_new,
 //     .imem = nv50_instmem_new,
        .clk = g84_clk_new,
        .devinit = g84_devinit_new,
        .fb = g84_fb_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
 //     .gpio = nv50_gpio_new,
 //     .i2c = nv50_i2c_new,
 //     .imem = nv50_instmem_new,
        .clk = g84_clk_new,
        .devinit = g84_devinit_new,
        .fb = g84_fb_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
 //     .gpio = nv50_gpio_new,
 //     .i2c = nv50_i2c_new,
 //     .imem = nv50_instmem_new,
        .clk = g84_clk_new,
        .devinit = g84_devinit_new,
        .fb = g84_fb_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .imem = nv50_instmem_new,
        .bios = nvkm_bios_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
        .clk = g84_clk_new,
 //     .therm = g84_therm_new,
 //     .mxm = nv50_mxm_new,
        .bios = nvkm_bios_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
        .clk = g84_clk_new,
 //     .therm = g84_therm_new,
 //     .mxm = nv50_mxm_new,
        .clk = g84_clk_new,
        .devinit = g84_devinit_new,
        .fb = g84_fb_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = nv50_i2c_new,
 //     .imem = nv50_instmem_new,
        .clk = gt215_clk_new,
        .devinit = gt215_devinit_new,
        .fb = gt215_fb_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .imem = nv50_instmem_new,
        .clk = gt215_clk_new,
        .devinit = gt215_devinit_new,
        .fb = gt215_fb_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .imem = nv50_instmem_new,
        .clk = gt215_clk_new,
        .devinit = gt215_devinit_new,
        .fb = gt215_fb_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .imem = nv50_instmem_new,
        .clk = mcp77_clk_new,
        .devinit = g98_devinit_new,
        .fb = mcp77_fb_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .imem = nv50_instmem_new,
        .clk = mcp77_clk_new,
        .devinit = g98_devinit_new,
        .fb = mcp77_fb_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .imem = nv50_instmem_new,
        .clk = gt215_clk_new,
        .devinit = mcp89_devinit_new,
        .fb = mcp89_fb_new,
-//     .fuse = nv50_fuse_new,
+       .fuse = nv50_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .imem = nv50_instmem_new,
        .clk = gf100_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gf100_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .ibus = gf100_ibus_new,
        .clk = gf100_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gf100_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .ibus = gf100_ibus_new,
        .clk = gf100_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gf100_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .ibus = gf100_ibus_new,
        .clk = gf100_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gf100_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .ibus = gf100_ibus_new,
        .clk = gf100_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gf100_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .ibus = gf100_ibus_new,
        .clk = gf100_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gf100_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .ibus = gf100_ibus_new,
        .clk = gf100_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gf100_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = g94_gpio_new,
 //     .i2c = g94_i2c_new,
 //     .ibus = gf100_ibus_new,
        .clk = gf100_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gf100_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = gf110_gpio_new,
 //     .i2c = gf117_i2c_new,
 //     .ibus = gf100_ibus_new,
        .clk = gf100_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gf100_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = gf110_gpio_new,
 //     .i2c = gf110_i2c_new,
 //     .ibus = gf100_ibus_new,
        .clk = gk104_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gk104_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = gk104_gpio_new,
 //     .i2c = gk104_i2c_new,
 //     .ibus = gk104_ibus_new,
        .clk = gk104_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gk104_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = gk104_gpio_new,
 //     .i2c = gk104_i2c_new,
 //     .ibus = gk104_ibus_new,
        .clk = gk104_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gk104_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = gk104_gpio_new,
 //     .i2c = gk104_i2c_new,
 //     .ibus = gk104_ibus_new,
        .bus = gf100_bus_new,
        .clk = gk20a_clk_new,
        .fb = gk20a_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .ibus = gk20a_ibus_new,
 //     .imem = gk20a_instmem_new,
 //     .ltc = gk104_ltc_new,
        .clk = gk104_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gk104_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = gk104_gpio_new,
 //     .i2c = gk104_i2c_new,
 //     .ibus = gk104_ibus_new,
        .clk = gk104_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gk104_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = gk104_gpio_new,
 //     .i2c = gf110_i2c_new,
 //     .ibus = gk104_ibus_new,
        .clk = gk104_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gk104_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = gk104_gpio_new,
 //     .i2c = gk104_i2c_new,
 //     .ibus = gk104_ibus_new,
        .clk = gk104_clk_new,
        .devinit = gf100_devinit_new,
        .fb = gk104_fb_new,
-//     .fuse = gf100_fuse_new,
+       .fuse = gf100_fuse_new,
 //     .gpio = gk104_gpio_new,
 //     .i2c = gk104_i2c_new,
 //     .ibus = gk104_ibus_new,
        .clk = gk104_clk_new,
        .devinit = gm107_devinit_new,
        .fb = gm107_fb_new,
-//     .fuse = gm107_fuse_new,
+       .fuse = gm107_fuse_new,
 //     .gpio = gk104_gpio_new,
 //     .i2c = gf110_i2c_new,
 //     .ibus = gk104_ibus_new,
        .bus = gf100_bus_new,
        .devinit = gm204_devinit_new,
        .fb = gm107_fb_new,
-//     .fuse = gm107_fuse_new,
+       .fuse = gm107_fuse_new,
 //     .gpio = gk104_gpio_new,
 //     .i2c = gm204_i2c_new,
 //     .ibus = gk104_ibus_new,
        .bus = gf100_bus_new,
        .devinit = gm204_devinit_new,
        .fb = gm107_fb_new,
-//     .fuse = gm107_fuse_new,
+       .fuse = gm107_fuse_new,
 //     .gpio = gk104_gpio_new,
 //     .i2c = gm204_i2c_new,
 //     .ibus = gk104_ibus_new,
        .bar = gk20a_bar_new,
        .bus = gf100_bus_new,
        .fb = gk20a_fb_new,
-//     .fuse = gm107_fuse_new,
+       .fuse = gm107_fuse_new,
 //     .ibus = gk20a_ibus_new,
 //     .imem = gk20a_instmem_new,
 //     .ltc = gm107_ltc_new,
 
        case 0xc0:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = >215_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf100_mc_oclass;
        case 0xc4:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = >215_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf100_mc_oclass;
        case 0xc3:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = >215_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
        case 0xce:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = >215_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf100_mc_oclass;
        case 0xcf:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = >215_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
        case 0xc1:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = >215_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
        case 0xc8:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = >215_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf100_mc_oclass;
        case 0xd9:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  gf110_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  gf110_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &gf110_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
        case 0xd7:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  gf110_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  gf117_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &gf110_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
 
        case 0xe4:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  gk104_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  gk104_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &gf110_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
        case 0xe7:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  gk104_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  gk104_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &gf110_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
        case 0xe6:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  gk104_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  gk104_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &gf110_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
                break;
        case 0xea:
                device->oclass[NVDEV_SUBDEV_MC     ] =  gk20a_mc_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &gk20a_timer_oclass;
                device->oclass[NVDEV_SUBDEV_LTC    ] =  gk104_ltc_oclass;
                device->oclass[NVDEV_SUBDEV_IBUS   ] = &gk20a_ibus_oclass;
        case 0xf0:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  gk104_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  gk104_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &gf110_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
        case 0xf1:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  gk104_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  gf110_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &gf110_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gf106_mc_oclass;
        case 0x106:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  gk104_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  gk104_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &gf110_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gk20a_mc_oclass;
        case 0x108:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  gk104_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  gk104_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gf100_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &gf110_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gk20a_mc_oclass;
 
        case 0x117:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  gk104_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  gf110_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gm107_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &gm107_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  gk20a_mc_oclass;
        case 0x124:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  gk104_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  gm204_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gm107_fuse_oclass;
 #if 0
                /* looks to be some non-trivial changes */
                /* priv ring says no to 0x10eb14 writes */
        case 0x126:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  gk104_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  gm204_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gm107_fuse_oclass;
 #if 0
                /* looks to be some non-trivial changes */
                /* priv ring says no to 0x10eb14 writes */
 
                device->oclass[NVDEV_SUBDEV_MC     ] =  gk20a_mc_oclass;
                device->oclass[NVDEV_SUBDEV_MMU    ] = &gf100_mmu_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] = &gm107_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_TIMER  ] = &gk20a_timer_oclass;
                device->oclass[NVDEV_SUBDEV_LTC    ] =  gm107_ltc_oclass;
                device->oclass[NVDEV_SUBDEV_IBUS   ] = &gk20a_ibus_oclass;
 
        case 0x50:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  nv50_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  nv50_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &nv50_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  nv50_mc_oclass;
        case 0x84:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  nv50_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  nv50_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &g84_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  nv50_mc_oclass;
        case 0x86:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  nv50_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  nv50_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &g84_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  nv50_mc_oclass;
        case 0x92:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  nv50_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  nv50_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &g84_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  nv50_mc_oclass;
        case 0x94:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &g84_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  g94_mc_oclass;
        case 0x96:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &g84_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  g94_mc_oclass;
        case 0x98:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &g84_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
        case 0xa0:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  nv50_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &g84_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
        case 0xaa:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &g84_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
        case 0xac:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = &g84_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
        case 0xa3:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = >215_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
        case 0xa5:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = >215_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
        case 0xa8:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = >215_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
        case 0xaf:
                device->oclass[NVDEV_SUBDEV_GPIO   ] =  g94_gpio_oclass;
                device->oclass[NVDEV_SUBDEV_I2C    ] =  g94_i2c_oclass;
-               device->oclass[NVDEV_SUBDEV_FUSE   ] =  &nv50_fuse_oclass;
                device->oclass[NVDEV_SUBDEV_THERM  ] = >215_therm_oclass;
                device->oclass[NVDEV_SUBDEV_MXM    ] = &nv50_mxm_oclass;
                device->oclass[NVDEV_SUBDEV_MC     ] =  g98_mc_oclass;
 
  *
  * Authors: Martin Peres
  */
-#include <subdev/fuse.h>
+#include "priv.h"
 
-int
-_nvkm_fuse_init(struct nvkm_object *object)
+u32
+nvkm_fuse_read(struct nvkm_fuse *fuse, u32 addr)
 {
-       struct nvkm_fuse *fuse = (void *)object;
-       return nvkm_subdev_init_old(&fuse->subdev);
+       return fuse->func->read(fuse, addr);
 }
 
-void
-_nvkm_fuse_dtor(struct nvkm_object *object)
+static void *
+nvkm_fuse_dtor(struct nvkm_subdev *subdev)
 {
-       struct nvkm_fuse *fuse = (void *)object;
-       nvkm_subdev_destroy(&fuse->subdev);
+       return nvkm_fuse(subdev);
 }
 
+static const struct nvkm_subdev_func
+nvkm_fuse = {
+       .dtor = nvkm_fuse_dtor,
+};
+
 int
-nvkm_fuse_create_(struct nvkm_object *parent, struct nvkm_object *engine,
-                 struct nvkm_oclass *oclass, int length, void **pobject)
+nvkm_fuse_new_(const struct nvkm_fuse_func *func, struct nvkm_device *device,
+              int index, struct nvkm_fuse **pfuse)
 {
-       return nvkm_subdev_create_(parent, engine, oclass, 0, "FUSE",
-                                  "fuse", length, pobject);
+       struct nvkm_fuse *fuse;
+       if (!(fuse = *pfuse = kzalloc(sizeof(*fuse), GFP_KERNEL)))
+               return -ENOMEM;
+       nvkm_subdev_ctor(&nvkm_fuse, device, index, 0, &fuse->subdev);
+       fuse->func = func;
+       spin_lock_init(&fuse->lock);
+       return 0;
 }
 
  */
 #include "priv.h"
 
-struct gf100_fuse {
-       struct nvkm_fuse base;
-
-       spinlock_t fuse_enable_lock;
-};
-
 static u32
-gf100_fuse_read(struct nvkm_fuse *obj, u32 addr)
+gf100_fuse_read(struct nvkm_fuse *fuse, u32 addr)
 {
-       struct gf100_fuse *fuse = container_of(obj, typeof(*fuse), base);
-       struct nvkm_device *device = fuse->base.subdev.device;
+       struct nvkm_device *device = fuse->subdev.device;
        unsigned long flags;
        u32 fuse_enable, unk, val;
 
        /* racy if another part of nvkm start writing to these regs */
-       spin_lock_irqsave(&fuse->fuse_enable_lock, flags);
-       fuse_enable = nvkm_mask(device, 0x22400, 0x800, 0x800);
-       unk = nvkm_mask(device, 0x21000, 0x1, 0x1);
-       val = nvkm_rd32(device, 0x21100 + addr);
-       nvkm_wr32(device, 0x21000, unk);
-       nvkm_wr32(device, 0x22400, fuse_enable);
-       spin_unlock_irqrestore(&fuse->fuse_enable_lock, flags);
+       spin_lock_irqsave(&fuse->lock, flags);
+       fuse_enable = nvkm_mask(device, 0x022400, 0x800, 0x800);
+       unk = nvkm_mask(device, 0x021000, 0x1, 0x1);
+       val = nvkm_rd32(device, 0x021100 + addr);
+       nvkm_wr32(device, 0x021000, unk);
+       nvkm_wr32(device, 0x022400, fuse_enable);
+       spin_unlock_irqrestore(&fuse->lock, flags);
        return val;
 }
 
 static const struct nvkm_fuse_func
-gf100_fuse_func = {
+gf100_fuse = {
        .read = gf100_fuse_read,
 };
 
-static int
-gf100_fuse_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-               struct nvkm_oclass *oclass, void *data, u32 size,
-               struct nvkm_object **pobject)
+int
+gf100_fuse_new(struct nvkm_device *device, int index, struct nvkm_fuse **pfuse)
 {
-       struct gf100_fuse *fuse;
-       int ret;
-
-       ret = nvkm_fuse_create(parent, engine, oclass, &fuse);
-       *pobject = nv_object(fuse);
-       if (ret)
-               return ret;
-
-       spin_lock_init(&fuse->fuse_enable_lock);
-       fuse->base.func = &gf100_fuse_func;
-       return 0;
+       return nvkm_fuse_new_(&gf100_fuse, device, index, pfuse);
 }
-
-struct nvkm_oclass
-gf100_fuse_oclass = {
-       .handle = NV_SUBDEV(FUSE, 0xC0),
-       .ofuncs = &(struct nvkm_ofuncs) {
-               .ctor = gf100_fuse_ctor,
-               .dtor = _nvkm_fuse_dtor,
-               .init = _nvkm_fuse_init,
-               .fini = _nvkm_fuse_fini,
-       },
-};
 
 gm107_fuse_read(struct nvkm_fuse *fuse, u32 addr)
 {
        struct nvkm_device *device = fuse->subdev.device;
-       return nvkm_rd32(device, 0x21100 + addr);
+       return nvkm_rd32(device, 0x021100 + addr);
 }
 
 static const struct nvkm_fuse_func
-gm107_fuse_func = {
+gm107_fuse = {
        .read = gm107_fuse_read,
 };
 
-static int
-gm107_fuse_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-               struct nvkm_oclass *oclass, void *data, u32 size,
-               struct nvkm_object **pobject)
+int
+gm107_fuse_new(struct nvkm_device *device, int index, struct nvkm_fuse **pfuse)
 {
-       struct nvkm_fuse *fuse;
-       int ret;
-
-       ret = nvkm_fuse_create(parent, engine, oclass, &fuse);
-       *pobject = nv_object(fuse);
-
-       fuse->func = &gm107_fuse_func;
-       return ret;
+       return nvkm_fuse_new_(&gm107_fuse, device, index, pfuse);
 }
-
-struct nvkm_oclass
-gm107_fuse_oclass = {
-       .handle = NV_SUBDEV(FUSE, 0x117),
-       .ofuncs = &(struct nvkm_ofuncs) {
-               .ctor = gm107_fuse_ctor,
-               .dtor = _nvkm_fuse_dtor,
-               .init = _nvkm_fuse_init,
-               .fini = _nvkm_fuse_fini,
-       },
-};
 
  */
 #include "priv.h"
 
-struct nv50_fuse {
-       struct nvkm_fuse base;
-
-       spinlock_t fuse_enable_lock;
-};
-
 static u32
-nv50_fuse_read(struct nvkm_fuse *obj, u32 addr)
+nv50_fuse_read(struct nvkm_fuse *fuse, u32 addr)
 {
-       struct nv50_fuse *fuse = container_of(obj, typeof(*fuse), base);
-       struct nvkm_device *device = fuse->base.subdev.device;
+       struct nvkm_device *device = fuse->subdev.device;
        unsigned long flags;
        u32 fuse_enable, val;
 
        /* racy if another part of nvkm start writing to this reg */
-       spin_lock_irqsave(&fuse->fuse_enable_lock, flags);
-       fuse_enable = nvkm_mask(device, 0x1084, 0x800, 0x800);
-       val = nvkm_rd32(device, 0x21000 + addr);
-       nvkm_wr32(device, 0x1084, fuse_enable);
-       spin_unlock_irqrestore(&fuse->fuse_enable_lock, flags);
+       spin_lock_irqsave(&fuse->lock, flags);
+       fuse_enable = nvkm_mask(device, 0x001084, 0x800, 0x800);
+       val = nvkm_rd32(device, 0x021000 + addr);
+       nvkm_wr32(device, 0x001084, fuse_enable);
+       spin_unlock_irqrestore(&fuse->lock, flags);
        return val;
 }
 
 static const struct nvkm_fuse_func
-nv50_fuse_func = {
+nv50_fuse = {
        .read = &nv50_fuse_read,
 };
 
-static int
-nv50_fuse_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
-              struct nvkm_oclass *oclass, void *data, u32 size,
-              struct nvkm_object **pobject)
+int
+nv50_fuse_new(struct nvkm_device *device, int index, struct nvkm_fuse **pfuse)
 {
-       struct nv50_fuse *fuse;
-       int ret;
-
-       ret = nvkm_fuse_create(parent, engine, oclass, &fuse);
-       *pobject = nv_object(fuse);
-       if (ret)
-               return ret;
-
-       spin_lock_init(&fuse->fuse_enable_lock);
-       fuse->base.func = &nv50_fuse_func;
-       return 0;
+       return nvkm_fuse_new_(&nv50_fuse, device, index, pfuse);
 }
-
-struct nvkm_oclass
-nv50_fuse_oclass = {
-       .handle = NV_SUBDEV(FUSE, 0x50),
-       .ofuncs = &(struct nvkm_ofuncs) {
-               .ctor = nv50_fuse_ctor,
-               .dtor = _nvkm_fuse_dtor,
-               .init = _nvkm_fuse_init,
-               .fini = _nvkm_fuse_fini,
-       },
-};
 
 #ifndef __NVKM_FUSE_PRIV_H__
 #define __NVKM_FUSE_PRIV_H__
+#define nvkm_fuse(p) container_of((p), struct nvkm_fuse, subdev)
 #include <subdev/fuse.h>
 
-int _nvkm_fuse_init(struct nvkm_object *object);
-void _nvkm_fuse_dtor(struct nvkm_object *object);
+struct nvkm_fuse_func {
+       u32 (*read)(struct nvkm_fuse *, u32 addr);
+};
+
+int nvkm_fuse_new_(const struct nvkm_fuse_func *, struct nvkm_device *,
+                  int index, struct nvkm_fuse **);
 #endif
 
 g84_temp_get(struct nvkm_therm *therm)
 {
        struct nvkm_device *device = therm->subdev.device;
-       struct nvkm_fuse *fuse = nvkm_fuse(therm);
 
-       if (fuse->func->read(fuse, 0x1a8) == 1)
+       if (nvkm_fuse_read(device->fuse, 0x1a8) == 1)
                return nvkm_rd32(device, 0x20400);
        else
                return -ENODEV;
 g84_sensor_setup(struct nvkm_therm *therm)
 {
        struct nvkm_device *device = therm->subdev.device;
-       struct nvkm_fuse *fuse = nvkm_fuse(therm);
 
        /* enable temperature reading for cards with insane defaults */
-       if (fuse->func->read(fuse, 0x1a8) == 1) {
+       if (nvkm_fuse_read(device->fuse, 0x1a8) == 1) {
                nvkm_mask(device, 0x20008, 0x80008000, 0x80000000);
                nvkm_mask(device, 0x2000c, 0x80000003, 0x00000000);
                mdelay(20); /* wait for the temperature to stabilize */