[PATCH 1/2] drm/radeon: move vga_switcheroo registration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Move the registration later to avoid a possible race
between driver initialization and a vga_switcheroo
request.

bug: https://bugzilla.redhat.com/show_bug.cgi?id=1411034

Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
---
 drivers/gpu/drm/radeon/radeon.h        |  2 ++
 drivers/gpu/drm/radeon/radeon_device.c | 38 ++++++++++++++++++----------------
 drivers/gpu/drm/radeon/radeon_kms.c    |  5 ++++-
 3 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 7e9d3b9..8cd4799 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -2477,6 +2477,8 @@ struct radeon_device {
 };
 
 bool radeon_is_px(struct drm_device *dev);
+void radeon_device_switcheroo_init(struct radeon_device *rdev);
+void radeon_device_switcheroo_fini(struct radeon_device *rdev);
 int radeon_device_init(struct radeon_device *rdev,
 		       struct drm_device *ddev,
 		       struct pci_dev *pdev,
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 34e138b..0c3de4f 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -1298,6 +1298,26 @@ static const struct vga_switcheroo_client_ops radeon_switcheroo_ops = {
 	.can_switch = radeon_switcheroo_can_switch,
 };
 
+void radeon_device_switcheroo_init(struct radeon_device *rdev)
+{
+	bool runtime = false;
+
+	if (rdev->flags & RADEON_IS_PX) {
+		radeon_device_handle_px_quirks(rdev);
+		runtime = true;
+	}
+	vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime);
+	if (runtime)
+		vga_switcheroo_init_domain_pm_ops(rdev->dev, &rdev->vga_pm_domain);
+}
+
+void radeon_device_switcheroo_fini(struct radeon_device *rdev)
+{
+	vga_switcheroo_unregister_client(rdev->pdev);
+	if (rdev->flags & RADEON_IS_PX)
+		vga_switcheroo_fini_domain_pm_ops(rdev->dev);
+}
+
 /**
  * radeon_device_init - initialize the driver
  *
@@ -1317,7 +1337,6 @@ int radeon_device_init(struct radeon_device *rdev,
 {
 	int r, i;
 	int dma_bits;
-	bool runtime = false;
 
 	rdev->shutdown = false;
 	rdev->dev = &pdev->dev;
@@ -1458,20 +1477,11 @@ int radeon_device_init(struct radeon_device *rdev,
 	if (rdev->rio_mem == NULL)
 		DRM_ERROR("Unable to find PCI I/O BAR\n");
 
-	if (rdev->flags & RADEON_IS_PX)
-		radeon_device_handle_px_quirks(rdev);
-
 	/* if we have > 1 VGA cards, then disable the radeon VGA resources */
 	/* this will fail for cards that aren't VGA class devices, just
 	 * ignore it */
 	vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
 
-	if (rdev->flags & RADEON_IS_PX)
-		runtime = true;
-	vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime);
-	if (runtime)
-		vga_switcheroo_init_domain_pm_ops(rdev->dev, &rdev->vga_pm_domain);
-
 	r = radeon_init(rdev);
 	if (r)
 		goto failed;
@@ -1538,11 +1548,6 @@ int radeon_device_init(struct radeon_device *rdev,
 	return 0;
 
 failed:
-	/* balance pm_runtime_get_sync() in radeon_driver_unload_kms() */
-	if (radeon_is_px(ddev))
-		pm_runtime_put_noidle(ddev->dev);
-	if (runtime)
-		vga_switcheroo_fini_domain_pm_ops(rdev->dev);
 	return r;
 }
 
@@ -1563,9 +1568,6 @@ void radeon_device_fini(struct radeon_device *rdev)
 	/* evict vram memory */
 	radeon_bo_evict_vram(rdev);
 	radeon_fini(rdev);
-	vga_switcheroo_unregister_client(rdev->pdev);
-	if (rdev->flags & RADEON_IS_PX)
-		vga_switcheroo_fini_domain_pm_ops(rdev->dev);
 	vga_client_register(rdev->pdev, NULL, NULL, NULL);
 	if (rdev->rio_mem)
 		pci_iounmap(rdev->pdev, rdev->rio_mem);
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 4388dde..140a060 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -71,9 +71,10 @@ int radeon_driver_unload_kms(struct drm_device *dev)
 	radeon_kfd_device_fini(rdev);
 
 	radeon_acpi_fini(rdev);
-	
+
 	radeon_modeset_fini(rdev);
 	radeon_device_fini(rdev);
+	radeon_device_switcheroo_fini(rdev);
 
 done_free:
 	kfree(rdev);
@@ -149,6 +150,8 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
 				"Error during ACPI methods call\n");
 	}
 
+	radeon_device_switcheroo_init(rdev);
+
 	radeon_kfd_device_probe(rdev);
 	radeon_kfd_device_init(rdev);
 
-- 
2.5.5



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux