Skip to content

Instantly share code, notes, and snippets.

@rockorequin
Created January 5, 2021 09:05
Show Gist options
  • Save rockorequin/f3047e748bcba9be9d1fff06f472dbda to your computer and use it in GitHub Desktop.
Save rockorequin/f3047e748bcba9be9d1fff06f472dbda to your computer and use it in GitHub Desktop.
diff --git a/module/Makefile b/module/Makefile
index 227457b..118ab60 100644
--- a/module/Makefile
+++ b/module/Makefile
@@ -17,7 +17,7 @@ ifneq ($(DKMS_BUILD),)
KERN_DIR := /lib/modules/$(KERNELRELEASE)/build
-ccflags-y := -Iinclude/drm $(EL8FLAG)
+ccflags-y := -Iinclude/drm $(EL8FLAG) -DCONFIG_DRM_LEGACY
evdi-y := evdi_platform_drv.o evdi_platform_dev.o evdi_sysfs.o evdi_modeset.o evdi_connector.o evdi_encoder.o evdi_drm_drv.o evdi_fb.o evdi_gem.o evdi_painter.o evdi_params.o evdi_cursor.o evdi_debug.o evdi_i2c.o
evdi-$(CONFIG_COMPAT) += evdi_ioc32.o
obj-m := evdi.o
diff --git a/module/evdi_drm_drv.c b/module/evdi_drm_drv.c
index c9b9e0a..368425e 100644
--- a/module/evdi_drm_drv.c
+++ b/module/evdi_drm_drv.c
@@ -39,11 +39,13 @@ struct drm_ioctl_desc evdi_painter_ioctls[] = {
DRM_UNLOCKED),
};
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
static const struct vm_operations_struct evdi_gem_vm_ops = {
.fault = evdi_gem_fault,
.open = drm_gem_vm_open,
.close = drm_gem_vm_close,
};
+#endif
static const struct file_operations evdi_driver_fops = {
.owner = THIS_MODULE,
@@ -78,17 +80,25 @@ static struct drm_driver driver = {
| DRIVER_ATOMIC,
#endif
.unload = evdi_driver_unload,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
.preclose = evdi_driver_preclose,
+#endif
.postclose = evdi_driver_postclose,
/* gem hooks */
-#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
- .gem_free_object_unlocked = evdi_gem_free_object,
-#else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)
+ // In 5.9 and below we have gem_free_object
.gem_free_object = evdi_gem_free_object,
+#elsif LINUX_VERSION_CODE <= KERNEL_VERSION(5, 11, 0)
+ // In 5.9 and 5.10 this is called gem_free_object_unlocked
+ .gem_free_object_unlocked = evdi_gem_free_object,
+ // Note that gem_free_object_unlocked no longer exists in 5.11 - it needs to be added to the gem object instead
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
+ // In 5.11+, this is set in the object instance
.gem_vm_ops = &evdi_gem_vm_ops,
+#endif
.dumb_create = evdi_dumb_create,
.dumb_map_offset = evdi_gem_mmap,
@@ -102,8 +112,11 @@ static struct drm_driver driver = {
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = drm_gem_prime_import,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
+ // In kernel 5.11, these have been moved to the object instance
.gem_prime_export = drm_gem_prime_export,
.gem_prime_get_sg_table = evdi_prime_get_sg_table,
+#endif
.gem_prime_import_sg_table = evdi_prime_import_sg_table,
.enable_vblank = evdi_enable_vblank,
diff --git a/module/evdi_gem.c b/module/evdi_gem.c
index e48abed..a5bf51c 100644
--- a/module/evdi_gem.c
+++ b/module/evdi_gem.c
@@ -18,6 +18,17 @@
#include <linux/dma-buf.h>
#include <drm/drm_cache.h>
+void evdi_gem_free_object(struct drm_gem_object *gem_obj);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
+static const struct vm_operations_struct evdi_gem_vm_ops = {
+ .fault = evdi_gem_fault,
+ .open = drm_gem_vm_open,
+ .close = drm_gem_vm_close,
+};
+#endif
+
+
uint32_t evdi_gem_object_handle_lookup(struct drm_file *filp,
struct drm_gem_object *obj)
{
@@ -41,6 +52,9 @@ struct evdi_gem_object *evdi_gem_alloc_object(struct drm_device *dev,
size_t size)
{
struct evdi_gem_object *obj;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
+ struct drm_gem_object_funcs *funcs;
+#endif
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (obj == NULL)
@@ -51,6 +65,21 @@ struct evdi_gem_object *evdi_gem_alloc_object(struct drm_device *dev,
return NULL;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
+ funcs = kzalloc(sizeof(struct drm_gem_object_funcs), GFP_KERNEL);
+ if (funcs == NULL) {
+ kfree(obj);
+ return NULL;
+ }
+ funcs->free = evdi_gem_free_object;
+ funcs->vm_ops = &evdi_gem_vm_ops;
+ // This is just setting the default drm_gem_prime_export kernel function, so wouldn't NULL also work?
+ funcs->export = drm_gem_prime_export;
+ funcs->get_sg_table = evdi_prime_get_sg_table;
+
+ obj->base.funcs = funcs;
+#endif
+
#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE || defined(EL8)
dma_resv_init(&obj->_resv);
#else
@@ -210,7 +239,11 @@ int evdi_gem_vmap(struct evdi_gem_object *obj)
int ret;
if (obj->base.import_attach) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
obj->vmapping = dma_buf_vmap(obj->base.import_attach->dmabuf);
+#else
+ dma_buf_vmap(obj->base.import_attach->dmabuf, obj->vmapping);
+#endif
if (!obj->vmapping)
return -ENOMEM;
return 0;
@@ -263,6 +296,12 @@ void evdi_gem_free_object(struct drm_gem_object *gem_obj)
reservation_object_fini(&obj->_resv);
#endif
obj->resv = NULL;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
+ // We allocated this in evdi_gem_alloc_object
+ kfree(obj->base.funcs);
+#endif
+
}
/*
diff --git a/module/evdi_modeset.c b/module/evdi_modeset.c
index e0189eb..f359172 100644
--- a/module/evdi_modeset.c
+++ b/module/evdi_modeset.c
@@ -56,7 +56,11 @@ static void evdi_crtc_set_nofb(__always_unused struct drm_crtc *crtc)
static void evdi_crtc_atomic_flush(
struct drm_crtc *crtc
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
, __always_unused struct drm_crtc_state *old_state
+#else
+ , __always_unused struct drm_atomic_state *old_state
+#endif
)
{
struct drm_crtc_state *state = crtc->state;
diff --git a/module/Makefile b/module/Makefile
index 227457b..118ab60 100644
--- a/module/Makefile
+++ b/module/Makefile
@@ -17,7 +17,7 @@ ifneq ($(DKMS_BUILD),)
KERN_DIR := /lib/modules/$(KERNELRELEASE)/build
-ccflags-y := -Iinclude/drm $(EL8FLAG)
+ccflags-y := -Iinclude/drm $(EL8FLAG) -DCONFIG_DRM_LEGACY
evdi-y := evdi_platform_drv.o evdi_platform_dev.o evdi_sysfs.o evdi_modeset.o evdi_connector.o evdi_encoder.o evdi_drm_drv.o evdi_fb.o evdi_gem.o evdi_painter.o evdi_params.o evdi_cursor.o evdi_debug.o evdi_i2c.o
evdi-$(CONFIG_COMPAT) += evdi_ioc32.o
obj-m := evdi.o
diff --git a/module/evdi_drm_drv.c b/module/evdi_drm_drv.c
index c9b9e0a..368425e 100644
--- a/module/evdi_drm_drv.c
+++ b/module/evdi_drm_drv.c
@@ -39,11 +39,13 @@ struct drm_ioctl_desc evdi_painter_ioctls[] = {
DRM_UNLOCKED),
};
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
static const struct vm_operations_struct evdi_gem_vm_ops = {
.fault = evdi_gem_fault,
.open = drm_gem_vm_open,
.close = drm_gem_vm_close,
};
+#endif
static const struct file_operations evdi_driver_fops = {
.owner = THIS_MODULE,
@@ -78,17 +80,25 @@ static struct drm_driver driver = {
| DRIVER_ATOMIC,
#endif
.unload = evdi_driver_unload,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
.preclose = evdi_driver_preclose,
+#endif
.postclose = evdi_driver_postclose,
/* gem hooks */
-#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE
- .gem_free_object_unlocked = evdi_gem_free_object,
-#else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)
+ // In 5.9 and below we have gem_free_object
.gem_free_object = evdi_gem_free_object,
+#elsif LINUX_VERSION_CODE <= KERNEL_VERSION(5, 11, 0)
+ // In 5.9 and 5.10 this is called gem_free_object_unlocked
+ .gem_free_object_unlocked = evdi_gem_free_object,
+ // Note that gem_free_object_unlocked no longer exists in 5.11 - it needs to be added to the gem object instead
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
+ // In 5.11+, this is set in the object instance
.gem_vm_ops = &evdi_gem_vm_ops,
+#endif
.dumb_create = evdi_dumb_create,
.dumb_map_offset = evdi_gem_mmap,
@@ -102,8 +112,11 @@ static struct drm_driver driver = {
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = drm_gem_prime_import,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
+ // In kernel 5.11, these have been moved to the object instance
.gem_prime_export = drm_gem_prime_export,
.gem_prime_get_sg_table = evdi_prime_get_sg_table,
+#endif
.gem_prime_import_sg_table = evdi_prime_import_sg_table,
.enable_vblank = evdi_enable_vblank,
diff --git a/module/evdi_gem.c b/module/evdi_gem.c
index e48abed..a5bf51c 100644
--- a/module/evdi_gem.c
+++ b/module/evdi_gem.c
@@ -18,6 +18,17 @@
#include <linux/dma-buf.h>
#include <drm/drm_cache.h>
+void evdi_gem_free_object(struct drm_gem_object *gem_obj);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
+static const struct vm_operations_struct evdi_gem_vm_ops = {
+ .fault = evdi_gem_fault,
+ .open = drm_gem_vm_open,
+ .close = drm_gem_vm_close,
+};
+#endif
+
+
uint32_t evdi_gem_object_handle_lookup(struct drm_file *filp,
struct drm_gem_object *obj)
{
@@ -41,6 +52,9 @@ struct evdi_gem_object *evdi_gem_alloc_object(struct drm_device *dev,
size_t size)
{
struct evdi_gem_object *obj;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
+ struct drm_gem_object_funcs *funcs;
+#endif
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (obj == NULL)
@@ -51,6 +65,21 @@ struct evdi_gem_object *evdi_gem_alloc_object(struct drm_device *dev,
return NULL;
}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
+ funcs = kzalloc(sizeof(struct drm_gem_object_funcs), GFP_KERNEL);
+ if (funcs == NULL) {
+ kfree(obj);
+ return NULL;
+ }
+ funcs->free = evdi_gem_free_object;
+ funcs->vm_ops = &evdi_gem_vm_ops;
+ // This is just setting the default drm_gem_prime_export kernel function, so wouldn't NULL also work?
+ funcs->export = drm_gem_prime_export;
+ funcs->get_sg_table = evdi_prime_get_sg_table;
+
+ obj->base.funcs = funcs;
+#endif
+
#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE || defined(EL8)
dma_resv_init(&obj->_resv);
#else
@@ -210,7 +239,11 @@ int evdi_gem_vmap(struct evdi_gem_object *obj)
int ret;
if (obj->base.import_attach) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
obj->vmapping = dma_buf_vmap(obj->base.import_attach->dmabuf);
+#else
+ dma_buf_vmap(obj->base.import_attach->dmabuf, obj->vmapping);
+#endif
if (!obj->vmapping)
return -ENOMEM;
return 0;
@@ -263,6 +296,12 @@ void evdi_gem_free_object(struct drm_gem_object *gem_obj)
reservation_object_fini(&obj->_resv);
#endif
obj->resv = NULL;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0)
+ // We allocated this in evdi_gem_alloc_object
+ kfree(obj->base.funcs);
+#endif
+
}
/*
diff --git a/module/evdi_modeset.c b/module/evdi_modeset.c
index e0189eb..f359172 100644
--- a/module/evdi_modeset.c
+++ b/module/evdi_modeset.c
@@ -56,7 +56,11 @@ static void evdi_crtc_set_nofb(__always_unused struct drm_crtc *crtc)
static void evdi_crtc_atomic_flush(
struct drm_crtc *crtc
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0)
, __always_unused struct drm_crtc_state *old_state
+#else
+ , __always_unused struct drm_atomic_state *old_state
+#endif
)
{
struct drm_crtc_state *state = crtc->state;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment