소스 검색

drm/nouveau: initialise display before enabling interrupts

In some situations it's possible we can receive a spurious hotplug IRQ
before we're ready to handle it, leading to an oops.

Calling the display init before enabling interrupts should clear any
pending IRQs on the GPU and prevent this from happening.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Ben Skeggs 15 년 전
부모
커밋
e88efe056d
1개의 변경된 파일13개의 추가작업 그리고 13개의 파일을 삭제
  1. 13 13
      drivers/gpu/drm/nouveau/nouveau_state.c

+ 13 - 13
drivers/gpu/drm/nouveau/nouveau_state.c

@@ -471,12 +471,19 @@ nouveau_card_init(struct drm_device *dev)
 			goto out_graph;
 			goto out_graph;
 	}
 	}
 
 
+	if (dev_priv->card_type >= NV_50)
+		ret = nv50_display_create(dev);
+	else
+		ret = nv04_display_create(dev);
+	if (ret)
+		goto out_fifo;
+
 	/* 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)
-		goto out_fifo;
+		goto out_display;
 
 
 	ret = drm_vblank_init(dev, 0);
 	ret = drm_vblank_init(dev, 0);
 	if (ret)
 	if (ret)
@@ -490,13 +497,6 @@ nouveau_card_init(struct drm_device *dev)
 			goto out_irq;
 			goto out_irq;
 	}
 	}
 
 
-	if (dev_priv->card_type >= NV_50)
-		ret = nv50_display_create(dev);
-	else
-		ret = nv04_display_create(dev);
-	if (ret)
-		goto out_channel;
-
 	ret = nouveau_backlight_init(dev);
 	ret = nouveau_backlight_init(dev);
 	if (ret)
 	if (ret)
 		NV_ERROR(dev, "Error %d registering backlight\n", ret);
 		NV_ERROR(dev, "Error %d registering backlight\n", ret);
@@ -505,13 +505,13 @@ nouveau_card_init(struct drm_device *dev)
 	drm_kms_helper_poll_init(dev);
 	drm_kms_helper_poll_init(dev);
 	return 0;
 	return 0;
 
 
-out_channel:
-	if (dev_priv->channel) {
-		nouveau_channel_free(dev_priv->channel);
-		dev_priv->channel = NULL;
-	}
 out_irq:
 out_irq:
 	drm_irq_uninstall(dev);
 	drm_irq_uninstall(dev);
+out_display:
+	if (dev_priv->card_type >= NV_50)
+		nv50_display_destroy(dev);
+	else
+		nv04_display_destroy(dev);
 out_fifo:
 out_fifo:
 	if (!nouveau_noaccel)
 	if (!nouveau_noaccel)
 		engine->fifo.takedown(dev);
 		engine->fifo.takedown(dev);