nouveau: Allow creation of gpuobjs before any other init has taken place.
authorBen Skeggs <skeggsb@gmail.com>
Fri, 10 Aug 2007 03:53:10 +0000 (13:53 +1000)
committerBen Skeggs <skeggsb@gmail.com>
Fri, 10 Aug 2007 03:53:10 +0000 (13:53 +1000)
shared-core/nouveau_drv.h
shared-core/nouveau_object.c
shared-core/nouveau_state.c

index 572df46..4d5c7f7 100644 (file)
@@ -370,8 +370,10 @@ extern int  nouveau_fifo_alloc(struct drm_device *dev,
 extern void nouveau_fifo_free(struct nouveau_channel *);
 
 /* nouveau_object.c */
+extern int  nouveau_gpuobj_early_init(struct drm_device *);
 extern int  nouveau_gpuobj_init(struct drm_device *);
 extern void nouveau_gpuobj_takedown(struct drm_device *);
+extern void nouveau_gpuobj_late_takedown(struct drm_device *);
 extern int nouveau_gpuobj_channel_init(struct nouveau_channel *,
                                       uint32_t vram_h, uint32_t tt_h);
 extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *);
index bb09653..d4142e4 100644 (file)
@@ -265,11 +265,25 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
 }
 
 int
+nouveau_gpuobj_early_init(struct drm_device *dev)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+       DRM_DEBUG("\n");
+
+       INIT_LIST_HEAD(&dev_priv->gpuobj_list);
+
+       return 0;
+}
+
+int
 nouveau_gpuobj_init(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        int ret;
 
+       DRM_DEBUG("\n");
+
        if (dev_priv->card_type < NV_50) {
                if ((ret = nouveau_gpuobj_new_fake(dev, dev_priv->ramht_offset,
                                                   dev_priv->ramht_size,
@@ -286,12 +300,20 @@ void
 nouveau_gpuobj_takedown(struct drm_device *dev)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
-       struct nouveau_gpuobj *gpuobj = NULL;
-       struct list_head *entry, *tmp;
 
        DRM_DEBUG("\n");
 
        nouveau_gpuobj_del(dev, &dev_priv->ramht);
+}
+
+void
+nouveau_gpuobj_late_takedown(struct drm_device *dev)
+{
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_gpuobj *gpuobj = NULL;
+       struct list_head *entry, *tmp;
+
+       DRM_DEBUG("\n");
 
        list_for_each_safe(entry, tmp, &dev_priv->gpuobj_list) {
                gpuobj = list_entry(entry, struct nouveau_gpuobj, list);
index e80e77a..eac3806 100644 (file)
@@ -296,7 +296,8 @@ nouveau_card_init(struct drm_device *dev)
        engine = &dev_priv->Engine;
        dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
 
-       INIT_LIST_HEAD(&dev_priv->gpuobj_list);
+       ret = nouveau_gpuobj_early_init(dev);
+       if (ret) return ret;
 
        /* Initialise instance memory, must happen before mem_init so we
         * know exactly how much VRAM we're able to use for "normal"
@@ -375,6 +376,8 @@ static void nouveau_card_takedown(struct drm_device *dev)
 
                drm_irq_uninstall(dev);
 
+               nouveau_gpuobj_late_takedown(dev);
+
                dev_priv->init_state = NOUVEAU_CARD_INIT_DOWN;
        }
 }