--- kernel/nvidia-drm/nvidia-drm-drv.c 2024-04-03 18:22:50.582571976 +0300 +++ kernel/nvidia-drm/nvidia-drm-drv.c 2024-04-03 18:47:57.000877801 +0300 @@ -480,6 +480,22 @@ return -ENODEV; } +#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) + /* + * If fbdev is enabled, take modeset ownership now before other DRM clients + * can take master (and thus NVKMS ownership). + */ + if (nv_drm_fbdev_module_param) { + if (!nvKms->grabOwnership(pDevice)) { + nvKms->freeDevice(pDevice); + NV_DRM_DEV_LOG_ERR(nv_dev, "Failed to grab NVKMS modeset ownership"); + return -EBUSY; + } + + nv_dev->hasFramebufferConsole = NV_TRUE; + } +#endif + mutex_lock(&nv_dev->lock); /* Set NvKmsKapiDevice */ @@ -590,6 +606,15 @@ return; } + /* Release modeset ownership if fbdev is enabled */ + +#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) + if (nv_dev->hasFramebufferConsole) { + drm_atomic_helper_shutdown(dev); + nvKms->releaseOwnership(nv_dev->pDevice); + } +#endif + cancel_delayed_work_sync(&nv_dev->hotplug_event_work); mutex_lock(&nv_dev->lock); @@ -1749,14 +1774,7 @@ } #if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) - if (nv_drm_fbdev_module_param && - drm_core_check_feature(dev, DRIVER_MODESET)) { - - if (!nvKms->grabOwnership(nv_dev->pDevice)) { - NV_DRM_DEV_LOG_ERR(nv_dev, "Failed to grab NVKMS modeset ownership"); - goto failed_grab_ownership; - } - + if (nv_dev->hasFramebufferConsole) { if (device->bus == &pci_bus_type) { struct pci_dev *pdev = to_pci_dev(device); @@ -1767,8 +1785,6 @@ #endif } drm_fbdev_generic_setup(dev, 32); - - nv_dev->hasFramebufferConsole = NV_TRUE; } #endif /* defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) */ @@ -1779,12 +1795,6 @@ return; /* Success */ -#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) -failed_grab_ownership: - - drm_dev_unregister(dev); -#endif - failed_drm_register: nv_drm_dev_free(dev); @@ -1849,12 +1859,6 @@ struct nv_drm_device *next = dev_list->next; struct drm_device *dev = dev_list->dev; -#if defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) - if (dev_list->hasFramebufferConsole) { - drm_atomic_helper_shutdown(dev); - nvKms->releaseOwnership(dev_list->pDevice); - } -#endif drm_dev_unregister(dev); nv_drm_dev_free(dev);