Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c5804be0 authored by Marcin Kościelnicki's avatar Marcin Kościelnicki Committed by Ben Skeggs
Browse files

drm/nouveau: Add proper error handling to nouveau_card_init

parent 13c5443b
Loading
Loading
Loading
Loading
+48 −25
Original line number Original line Diff line number Diff line
@@ -317,7 +317,7 @@ nouveau_card_init(struct drm_device *dev)
	/* Initialise internal driver API hooks */
	/* Initialise internal driver API hooks */
	ret = nouveau_init_engine_ptrs(dev);
	ret = nouveau_init_engine_ptrs(dev);
	if (ret)
	if (ret)
		return ret;
		goto out;
	engine = &dev_priv->engine;
	engine = &dev_priv->engine;
	dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;
	dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED;


@@ -325,12 +325,12 @@ nouveau_card_init(struct drm_device *dev)
	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
		ret = nouveau_bios_init(dev);
		ret = nouveau_bios_init(dev);
		if (ret)
		if (ret)
			return ret;
			goto out;
	}
	}


	ret = nouveau_gpuobj_early_init(dev);
	ret = nouveau_gpuobj_early_init(dev);
	if (ret)
	if (ret)
		return ret;
		goto out_bios;


	/* Initialise instance memory, must happen before mem_init so we
	/* Initialise instance memory, must happen before mem_init so we
	 * know exactly how much VRAM we're able to use for "normal"
	 * know exactly how much VRAM we're able to use for "normal"
@@ -338,52 +338,52 @@ nouveau_card_init(struct drm_device *dev)
	 */
	 */
	ret = engine->instmem.init(dev);
	ret = engine->instmem.init(dev);
	if (ret)
	if (ret)
		return ret;
		goto out_gpuobj_early;


	/* Setup the memory manager */
	/* Setup the memory manager */
	ret = nouveau_mem_init(dev);
	ret = nouveau_mem_init(dev);
	if (ret)
	if (ret)
		return ret;
		goto out_instmem;


	ret = nouveau_gpuobj_init(dev);
	ret = nouveau_gpuobj_init(dev);
	if (ret)
	if (ret)
		return ret;
		goto out_mem;


	/* PMC */
	/* PMC */
	ret = engine->mc.init(dev);
	ret = engine->mc.init(dev);
	if (ret)
	if (ret)
		return ret;
		goto out_gpuobj;


	/* PTIMER */
	/* PTIMER */
	ret = engine->timer.init(dev);
	ret = engine->timer.init(dev);
	if (ret)
	if (ret)
		return ret;
		goto out_mc;


	/* PFB */
	/* PFB */
	ret = engine->fb.init(dev);
	ret = engine->fb.init(dev);
	if (ret)
	if (ret)
		return ret;
		goto out_timer;


	/* PGRAPH */
	/* PGRAPH */
	ret = engine->graph.init(dev);
	ret = engine->graph.init(dev);
	if (ret)
	if (ret)
		return ret;
		goto out_fb;


	/* PFIFO */
	/* PFIFO */
	ret = engine->fifo.init(dev);
	ret = engine->fifo.init(dev);
	if (ret)
	if (ret)
		return ret;
		goto out_graph;


	/* this call irq_preinstall, register irq handler and
	/* this call irq_preinstall, register irq handler and
	 * call irq_postinstall
	 * call irq_postinstall
	 */
	 */
	ret = drm_irq_install(dev);
	ret = drm_irq_install(dev);
	if (ret)
	if (ret)
		return ret;
		goto out_fifo;


	ret = drm_vblank_init(dev, 0);
	ret = drm_vblank_init(dev, 0);
	if (ret)
	if (ret)
		return ret;
		goto out_irq;


	/* what about PVIDEO/PCRTC/PRAMDAC etc? */
	/* what about PVIDEO/PCRTC/PRAMDAC etc? */


@@ -391,7 +391,7 @@ nouveau_card_init(struct drm_device *dev)
				    (struct drm_file *)-2,
				    (struct drm_file *)-2,
				    NvDmaFB, NvDmaTT);
				    NvDmaFB, NvDmaTT);
	if (ret)
	if (ret)
		return ret;
		goto out_irq;


	gpuobj = NULL;
	gpuobj = NULL;
	ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
	ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY,
@@ -399,13 +399,13 @@ nouveau_card_init(struct drm_device *dev)
				     NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
				     NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM,
				     &gpuobj);
				     &gpuobj);
	if (ret)
	if (ret)
		return ret;
		goto out_irq;


	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM,
	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM,
				     gpuobj, NULL);
				     gpuobj, NULL);
	if (ret) {
	if (ret) {
		nouveau_gpuobj_del(dev, &gpuobj);
		nouveau_gpuobj_del(dev, &gpuobj);
		return ret;
		goto out_irq;
	}
	}


	gpuobj = NULL;
	gpuobj = NULL;
@@ -413,25 +413,22 @@ nouveau_card_init(struct drm_device *dev)
					  dev_priv->gart_info.aper_size,
					  dev_priv->gart_info.aper_size,
					  NV_DMA_ACCESS_RW, &gpuobj, NULL);
					  NV_DMA_ACCESS_RW, &gpuobj, NULL);
	if (ret)
	if (ret)
		return ret;
		goto out_irq;


	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART,
	ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART,
				     gpuobj, NULL);
				     gpuobj, NULL);
	if (ret) {
	if (ret) {
		nouveau_gpuobj_del(dev, &gpuobj);
		nouveau_gpuobj_del(dev, &gpuobj);
		return ret;
		goto out_irq;
	}
	}


	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
		if (dev_priv->card_type >= NV_50) {
		if (dev_priv->card_type >= NV_50)
			ret = nv50_display_create(dev);
			ret = nv50_display_create(dev);
			if (ret)
		else
				return ret;
		} else {
			ret = nv04_display_create(dev);
			ret = nv04_display_create(dev);
		if (ret)
		if (ret)
				return ret;
			goto out_irq;
		}
	}
	}


	ret = nouveau_backlight_init(dev);
	ret = nouveau_backlight_init(dev);
@@ -444,6 +441,32 @@ nouveau_card_init(struct drm_device *dev)
		drm_helper_initial_config(dev);
		drm_helper_initial_config(dev);


	return 0;
	return 0;

out_irq:
	drm_irq_uninstall(dev);
out_fifo:
	engine->fifo.takedown(dev);
out_graph:
	engine->graph.takedown(dev);
out_fb:
	engine->fb.takedown(dev);
out_timer:
	engine->timer.takedown(dev);
out_mc:
	engine->mc.takedown(dev);
out_gpuobj:
	nouveau_gpuobj_takedown(dev);
out_mem:
	nouveau_mem_close(dev);
out_instmem:
	engine->instmem.takedown(dev);
out_gpuobj_early:
	nouveau_gpuobj_late_takedown(dev);
out_bios:
	nouveau_bios_takedown(dev);
out:
	vga_client_register(dev->pdev, NULL, NULL, NULL);
	return ret;
}
}


static void nouveau_card_takedown(struct drm_device *dev)
static void nouveau_card_takedown(struct drm_device *dev)