diff --git a/kernel-open/nvidia-drm/nvidia-drm-drv.c b/kernel-open/nvidia-drm/nvidia-drm-drv.c index 8cb94219..27b3cbd9 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-drv.c +++ b/kernel-open/nvidia-drm/nvidia-drm-drv.c @@ -100,6 +100,11 @@ #include #endif +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) +#include +#endif + static int nv_drm_revoke_modeset_permission(struct drm_device *dev, struct drm_file *filep, NvU32 dpyId); @@ -147,7 +152,7 @@ #if defined(NV_DRM_ATOMIC_MODESET_AVAILABLE) -#if defined(NV_DRM_OUTPUT_POLL_CHANGED_PRESENT) + static void nv_drm_output_poll_changed(struct drm_device *dev) { struct drm_connector *connector = NULL; @@ -191,7 +196,7 @@ nv_drm_connector_list_iter_end(&conn_iter); #endif } -#endif /* NV_DRM_OUTPUT_POLL_CHANGED_PRESENT */ + static struct drm_framebuffer *nv_drm_framebuffer_create( struct drm_device *dev, @@ -229,9 +234,7 @@ .atomic_check = nv_drm_atomic_check, .atomic_commit = nv_drm_atomic_commit, - #if defined(NV_DRM_OUTPUT_POLL_CHANGED_PRESENT) - .output_poll_changed = nv_drm_output_poll_changed, - #endif + }; static void nv_drm_event_callback(const struct NvKmsKapiEvent *event) @@ -1711,6 +1714,10 @@ .read = drm_read, .llseek = noop_llseek, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) + // Rel. commit. "fs: move FMODE_UNSIGNED_OFFSET to fop_flags" (Christian Brauner, 9 Aug 2024) + .fop_flags = FOP_UNSIGNED_OFFSET, +#endif }; static const struct drm_ioctl_desc nv_drm_ioctls[] = { @@ -1939,6 +1946,20 @@ } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) +static int hotplug_helper_client_hotplug(struct drm_client_dev *client) +{ + nv_drm_output_poll_changed(client->dev); + return 0; +} + +static const struct drm_client_funcs nv_hotplug_helper_client_funcs = { + .owner = THIS_MODULE, + .hotplug = hotplug_helper_client_hotplug, +}; +#endif + + /* * Helper function for allocate/register DRM device for given NVIDIA GPU ID. @@ -2029,8 +2050,27 @@ nv_dev->next = dev_list; dev_list = nv_dev; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) + /* Register a DRM client for receiving hotplug events */ + struct drm_client_dev *client = kzalloc(sizeof(*client), GFP_KERNEL); + if (client == NULL || drm_client_init(dev, client, + "nv-hotplug-helper", &nv_hotplug_helper_client_funcs)) { + printk(KERN_WARNING "Failed to initialize the nv-hotplug-helper DRM client."); + goto failed_drm_client_init; + } + + drm_client_register(client); + pr_info("Registered the nv-hotplug-helper DRM client."); +#endif + return; /* Success */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 12, 0) +failed_drm_client_init: + + kfree(client); +#endif + failed_drm_register: nv_drm_dev_free(dev);