int (*identify)(struct nouveau_i2c *, int index,
                        const char *what, struct nouveau_i2c_board_info *,
                        bool (*match)(struct nouveau_i2c_port *,
-                                     struct i2c_board_info *));
+                                     struct i2c_board_info *, void *), void *);
        struct list_head ports;
 };
 
 
 static inline struct nouveau_instmem *
 nouveau_instmem(void *obj)
 {
+       /* nv04/nv40 impls need to create objects in their constructor,
+        * which is before the subdev pointer is valid
+        */
+       if (nv_iclass(obj, NV_SUBDEV_CLASS) &&
+           nv_subidx(obj) == NVDEV_SUBDEV_INSTMEM)
+               return obj;
+
        return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_INSTMEM];
 }
 
 
 nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what,
                     struct nouveau_i2c_board_info *info,
                     bool (*match)(struct nouveau_i2c_port *,
-                                  struct i2c_board_info *))
+                                  struct i2c_board_info *, void *), void *data)
 {
        struct nouveau_i2c_port *port = nouveau_i2c_find(i2c, index);
        int i;
                }
 
                if (nv_probe_i2c(port, info[i].dev.addr) &&
-                   (!match || match(port, &info[i].dev))) {
+                   (!match || match(port, &info[i].dev, data))) {
                        nv_info(i2c, "detected %s: %s\n", what,
                                info[i].dev.type);
                        return i;
 
 
 static bool
 probe_monitoring_device(struct nouveau_i2c_port *i2c,
-                       struct i2c_board_info *info)
+                       struct i2c_board_info *info, void *data)
 {
-       struct nouveau_therm_priv *priv = (void *)nouveau_therm(i2c);
+       struct nouveau_therm_priv *priv = data;
        struct nvbios_therm_sensor *sensor = &priv->bios_sensor;
        struct i2c_client *client;
 
                };
 
                i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device",
-                                 board, probe_monitoring_device);
+                             board, probe_monitoring_device, therm);
                if (priv->ic)
                        return;
        }
                };
 
                i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device",
-                                 board, probe_monitoring_device);
+                             board, probe_monitoring_device, therm);
                if (priv->ic)
                        return;
        }
           device. Let's try our static list.
         */
        i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device",
-                     nv_board_infos, probe_monitoring_device);
+                     nv_board_infos, probe_monitoring_device, therm);
 }
 
            get_tmds_slave(encoder))
                return;
 
-       type = i2c->identify(i2c, 2, "TMDS transmitter", info, NULL);
+       type = i2c->identify(i2c, 2, "TMDS transmitter", info, NULL, NULL);
        if (type < 0)
                return;
 
 
        struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
 
        return i2c->identify(i2c, i2c_index, "TV encoder",
-                            nv04_tv_encoder_info, NULL);
+                            nv04_tv_encoder_info, NULL, NULL);
 }