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