Эх сурвалжийг харах

drm/radeon/kms: Don't try to enable IRQ if we have no handler installed

If for any reason we haven't installed handler we shouldn't try to
enable IRQ/MSI on the hw so we don't get unhandled IRQ/MSI which
makes the kernel sad.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Jerome Glisse 15 жил өмнө
parent
commit
003e69f986

+ 7 - 1
drivers/gpu/drm/radeon/r100.c

@@ -131,7 +131,8 @@ void r100_hpd_init(struct radeon_device *rdev)
 			break;
 			break;
 		}
 		}
 	}
 	}
-	r100_irq_set(rdev);
+	if (rdev->irq.installed)
+		r100_irq_set(rdev);
 }
 }
 
 
 void r100_hpd_fini(struct radeon_device *rdev)
 void r100_hpd_fini(struct radeon_device *rdev)
@@ -243,6 +244,11 @@ int r100_irq_set(struct radeon_device *rdev)
 {
 {
 	uint32_t tmp = 0;
 	uint32_t tmp = 0;
 
 
+	if (!rdev->irq.installed) {
+		WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n");
+		WREG32(R_000040_GEN_INT_CNTL, 0);
+		return -EINVAL;
+	}
 	if (rdev->irq.sw_int) {
 	if (rdev->irq.sw_int) {
 		tmp |= RADEON_SW_INT_ENABLE;
 		tmp |= RADEON_SW_INT_ENABLE;
 	}
 	}

+ 6 - 1
drivers/gpu/drm/radeon/r600.c

@@ -285,7 +285,8 @@ void r600_hpd_init(struct radeon_device *rdev)
 			}
 			}
 		}
 		}
 	}
 	}
-	r600_irq_set(rdev);
+	if (rdev->irq.installed)
+		r600_irq_set(rdev);
 }
 }
 
 
 void r600_hpd_fini(struct radeon_device *rdev)
 void r600_hpd_fini(struct radeon_device *rdev)
@@ -2461,6 +2462,10 @@ int r600_irq_set(struct radeon_device *rdev)
 	u32 mode_int = 0;
 	u32 mode_int = 0;
 	u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0;
 	u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0;
 
 
+	if (!rdev->irq.installed) {
+		WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n");
+		return -EINVAL;
+	}
 	/* don't enable anything if the ih is disabled */
 	/* don't enable anything if the ih is disabled */
 	if (!rdev->ih.enabled)
 	if (!rdev->ih.enabled)
 		return 0;
 		return 0;

+ 8 - 2
drivers/gpu/drm/radeon/radeon_irq_kms.c

@@ -97,6 +97,7 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev)
 	rdev->irq.sw_int = false;
 	rdev->irq.sw_int = false;
 	for (i = 0; i < 2; i++) {
 	for (i = 0; i < 2; i++) {
 		rdev->irq.crtc_vblank_int[i] = false;
 		rdev->irq.crtc_vblank_int[i] = false;
+		rdev->irq.hpd[i] = false;
 	}
 	}
 	radeon_irq_set(rdev);
 	radeon_irq_set(rdev);
 }
 }
@@ -128,17 +129,22 @@ int radeon_irq_kms_init(struct radeon_device *rdev)
 			DRM_INFO("radeon: using MSI.\n");
 			DRM_INFO("radeon: using MSI.\n");
 		}
 		}
 	}
 	}
-	drm_irq_install(rdev->ddev);
 	rdev->irq.installed = true;
 	rdev->irq.installed = true;
+	r = drm_irq_install(rdev->ddev);
+	if (r) {
+		rdev->irq.installed = false;
+		return r;
+	}
 	DRM_INFO("radeon: irq initialized.\n");
 	DRM_INFO("radeon: irq initialized.\n");
 	return 0;
 	return 0;
 }
 }
 
 
 void radeon_irq_kms_fini(struct radeon_device *rdev)
 void radeon_irq_kms_fini(struct radeon_device *rdev)
 {
 {
+	drm_vblank_cleanup(rdev->ddev);
 	if (rdev->irq.installed) {
 	if (rdev->irq.installed) {
-		rdev->irq.installed = false;
 		drm_irq_uninstall(rdev->ddev);
 		drm_irq_uninstall(rdev->ddev);
+		rdev->irq.installed = false;
 		if (rdev->msi_enabled)
 		if (rdev->msi_enabled)
 			pci_disable_msi(rdev->pdev);
 			pci_disable_msi(rdev->pdev);
 	}
 	}

+ 7 - 1
drivers/gpu/drm/radeon/rs600.c

@@ -135,7 +135,8 @@ void rs600_hpd_init(struct radeon_device *rdev)
 			break;
 			break;
 		}
 		}
 	}
 	}
-	rs600_irq_set(rdev);
+	if (rdev->irq.installed)
+		rs600_irq_set(rdev);
 }
 }
 
 
 void rs600_hpd_fini(struct radeon_device *rdev)
 void rs600_hpd_fini(struct radeon_device *rdev)
@@ -316,6 +317,11 @@ int rs600_irq_set(struct radeon_device *rdev)
 	u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) &
 	u32 hpd2 = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL) &
 		~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1);
 		~S_007D18_DC_HOT_PLUG_DETECT2_INT_EN(1);
 
 
+	if (!rdev->irq.installed) {
+		WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n");
+		WREG32(R_000040_GEN_INT_CNTL, 0);
+		return -EINVAL;
+	}
 	if (rdev->irq.sw_int) {
 	if (rdev->irq.sw_int) {
 		tmp |= S_000040_SW_INT_EN(1);
 		tmp |= S_000040_SW_INT_EN(1);
 	}
 	}