Package: evdi Version: 1.9.0+dfsg-1 Severity: normal Tags: patch pending Dear maintainer,
I've prepared an NMU for evdi (versioned as 1.12.0+dfsg-0.1) and uploaded it to DELAYED/0 as there has been no activity for some time and it has been dropped from testing. Regards. diff -Nru evdi-1.9.0+dfsg/debian/changelog evdi-1.12.0+dfsg/debian/changelog --- evdi-1.9.0+dfsg/debian/changelog 2021-01-26 10:32:36.000000000 -0500 +++ evdi-1.12.0+dfsg/debian/changelog 2022-11-01 11:56:26.000000000 -0400 @@ -1,3 +1,12 @@ +evdi (1.12.0+dfsg-0.1) unstable; urgency=medium + + * Non-maintainer upload. + * New upstream release (Closes: #994892, #1017058) + * Import patch to fix FTBFS in Linux >= 6.0 from upstream + * Add dh-dkms to build-depends + + -- Harlan Lieberman-Berg <hlieber...@debian.org> Tue, 01 Nov 2022 11:56:26 -0400 + evdi (1.9.0+dfsg-1) unstable; urgency=medium * new upstream release 1.9.0 diff -Nru evdi-1.9.0+dfsg/debian/control evdi-1.12.0+dfsg/debian/control --- evdi-1.9.0+dfsg/debian/control 2021-01-26 10:32:36.000000000 -0500 +++ evdi-1.12.0+dfsg/debian/control 2022-11-01 11:56:26.000000000 -0400 @@ -2,7 +2,7 @@ Section: misc Priority: optional Maintainer: Hanno Stock <opensou...@hanno-stock.de> -Build-Depends: debhelper-compat (= 13), dkms, dh-exec, libdrm-dev +Build-Depends: debhelper-compat (= 13), dh-dkms, dkms, dh-exec, libdrm-dev Standards-Version: 4.5.0 Rules-Requires-Root: no Homepage: https://github.com/DisplayLink/evdi diff -Nru evdi-1.9.0+dfsg/debian/patches/0001-fix-6.0-ftbfs.patch evdi-1.12.0+dfsg/debian/patches/0001-fix-6.0-ftbfs.patch --- evdi-1.9.0+dfsg/debian/patches/0001-fix-6.0-ftbfs.patch 1969-12-31 19:00:00.000000000 -0500 +++ evdi-1.12.0+dfsg/debian/patches/0001-fix-6.0-ftbfs.patch 2022-11-01 11:56:26.000000000 -0400 @@ -0,0 +1,53 @@ +From bdc258b25df4d00f222fde0e3c5003bf88ef17b5 Mon Sep 17 00:00:00 2001 +From: Adam Tazul <71192298+simpilotad...@users.noreply.github.com> +Date: Thu, 13 Oct 2022 10:50:00 +0100 +Subject: [PATCH] Add support for kernel 6.0 + a minor fix (#381) + +* Add support for kernel 6.0 + +Fixes #376 by implementing @Crashdummyy's fix as posted [here](https://github.com/DisplayLink/evdi/issues/376#issuecomment-1237450695) + +* Fixing the style used in evdi_painter.c + +* Update evdi_painter.c + +* drm_framebuffer is only included on 5.15 and later + +* drm_framebuffer is only included on 6.0.0 and later + +* drm_framebuffer is only included on 6.0.0 and later + +* drm_framebuffer is only included on 6.0.0 and later + +* drm_framebuffer is only included on 5.15.0 and later +--- + module/evdi_drm_drv.h | 2 +- + module/evdi_painter.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +Index: evdi/module/evdi_drm_drv.h +=================================================================== +--- evdi.orig/module/evdi_drm_drv.h ++++ evdi/module/evdi_drm_drv.h +@@ -26,7 +26,7 @@ + #include <drm/drmP.h> + #endif + #if KERNEL_VERSION(5, 15, 0) <= LINUX_VERSION_CODE +-#include <drm/drm_legacy.h> ++#include <drm/drm_framebuffer.h> + #else + #include <drm/drm_irq.h> + #endif +Index: evdi/module/evdi_painter.c +=================================================================== +--- evdi.orig/module/evdi_painter.c ++++ evdi/module/evdi_painter.c +@@ -885,7 +885,7 @@ evdi_painter_connect(struct evdi_device + + painter_lock(painter); + +- evdi->pixel_area_limit = pixel_area_limit; ++ evdi->pixel_area_limit = pixel_area_limit; + evdi->pixel_per_second_limit = pixel_per_second_limit; + painter->drm_filp = file; + kfree(painter->edid); diff -Nru evdi-1.9.0+dfsg/debian/patches/series evdi-1.12.0+dfsg/debian/patches/series --- evdi-1.9.0+dfsg/debian/patches/series 1969-12-31 19:00:00.000000000 -0500 +++ evdi-1.12.0+dfsg/debian/patches/series 2022-11-01 11:56:26.000000000 -0400 @@ -0,0 +1 @@ +0001-fix-6.0-ftbfs.patch diff -Nru evdi-1.9.0+dfsg/library/evdi_lib.c evdi-1.12.0+dfsg/library/evdi_lib.c --- evdi-1.9.0+dfsg/library/evdi_lib.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/library/evdi_lib.c 2022-07-13 09:58:06.000000000 -0400 @@ -29,7 +29,7 @@ #define EVDI_INVALID_DEVICE_INDEX -1 #define EVDI_MODULE_COMPATIBILITY_VERSION_MAJOR 1 -#define EVDI_MODULE_COMPATIBILITY_VERSION_MINOR 8 +#define EVDI_MODULE_COMPATIBILITY_VERSION_MINOR 9 #define EVDI_MODULE_COMPATIBILITY_VERSION_PATCH 0 #define evdi_log(...) do { \ @@ -468,15 +468,45 @@ return dev_index; } -static int find_unused_card_for(const char *sysfs_parent_device_path) +static bool is_correct_parent_device(const char *dirname, const char *parent_device) { + char link_path[PATH_MAX]; + + snprintf(link_path, PATH_MAX - 7, "%s/device", dirname); + + if (parent_device == NULL) + return access(link_path, F_OK) != 0; + + char link_resolution[PATH_MAX]; + const ssize_t link_resolution_len = readlink(link_path, link_resolution, PATH_MAX); + + if (link_resolution_len == -1 || link_resolution_len == PATH_MAX) + return false; + + link_resolution[link_resolution_len] = '\0'; + char *parent_device_token = strrchr(link_resolution, '/'); + + if (strlen(parent_device) < 2) + return false; + + parent_device_token++; + size_t len = strlen(parent_device_token); + + bool is_same_device = strlen(parent_device) == len && strncmp(parent_device_token, parent_device, len) == 0; + + return is_same_device; +} + +static int find_unused_card_for(const char *parent_device) +{ + char evdi_platform_root[] = "/sys/bus/platform/devices"; struct dirent *fd_entry; DIR *fd_dir; int device_index = EVDI_INVALID_DEVICE_INDEX; - fd_dir = opendir(sysfs_parent_device_path); + fd_dir = opendir(evdi_platform_root); if (fd_dir == NULL) { - evdi_log("Failed to open dir %s", sysfs_parent_device_path); + evdi_log("Failed to open dir %s", evdi_platform_root); return device_index; } @@ -484,9 +514,16 @@ if (strncmp(fd_entry->d_name, "evdi", 4) != 0) continue; + char evdi_path[PATH_MAX]; + + snprintf(evdi_path, PATH_MAX, "%s/%s", evdi_platform_root, fd_entry->d_name); + + if (!is_correct_parent_device(evdi_path, parent_device)) + continue; + char evdi_drm_path[PATH_MAX]; - snprintf(evdi_drm_path, PATH_MAX, "%s/%s/drm", sysfs_parent_device_path, fd_entry->d_name); + snprintf(evdi_drm_path, PATH_MAX - strlen(evdi_path), "%s/drm", evdi_path); int dev_index = get_drm_device_index(evdi_drm_path); assert(dev_index < EVDI_USAGE_LEN && dev_index >= 0); @@ -503,37 +540,30 @@ static int get_generic_device(void) { - char evdi_platform_root[] = "/sys/devices/platform"; int device_index = EVDI_INVALID_DEVICE_INDEX; - device_index = find_unused_card_for(evdi_platform_root); + device_index = find_unused_card_for(NULL); if (device_index == EVDI_INVALID_DEVICE_INDEX) { - evdi_log("Creating card in %s", evdi_platform_root); + evdi_log("Creating card in /sys/devices/platform"); write_add_device("1", 1); - device_index = find_unused_card_for(evdi_platform_root); + device_index = find_unused_card_for(NULL); } return device_index; } -static int get_device_attached_to_usb(const char *bus_ident) +static int get_device_attached_to_usb(const char *sysfs_parent_device) { int device_index = EVDI_INVALID_DEVICE_INDEX; - char evdi_usb_parent_path[PATH_MAX] = "/sys/bus/usb/devices/"; - - strncat(evdi_usb_parent_path, bus_ident, PATH_MAX - strlen(evdi_usb_parent_path)); + const char *parent_device = &sysfs_parent_device[4]; - device_index = find_unused_card_for(evdi_usb_parent_path); + device_index = find_unused_card_for(parent_device); if (device_index == EVDI_INVALID_DEVICE_INDEX) { - evdi_log("Creating card for %s", bus_ident); - char usb_dev_path[PATH_MAX] = "usb:"; - const size_t current_len = strlen(usb_dev_path); + evdi_log("Creating card for usb device %s in /sys/bus/platform/devices", parent_device); + const size_t len = strlen(sysfs_parent_device); - strncat(usb_dev_path, bus_ident, PATH_MAX - current_len); - const size_t len = strlen(usb_dev_path); - - write_add_device(usb_dev_path, len); - device_index = find_unused_card_for(evdi_usb_parent_path); + write_add_device(sysfs_parent_device, len); + device_index = find_unused_card_for(parent_device); } return device_index; @@ -616,14 +646,8 @@ if (sysfs_parent_device == NULL) device_index = get_generic_device(); - if (sysfs_parent_device != NULL && strncmp(sysfs_parent_device, "usb:", 4) == 0 && strlen(sysfs_parent_device) > 4) { - char bus_ident[PATH_MAX]; - const size_t len = strlen(sysfs_parent_device) - 4; - - strncpy(bus_ident, &sysfs_parent_device[4], len); - bus_ident[len] = 0; - device_index = get_device_attached_to_usb(bus_ident); - } + if (sysfs_parent_device != NULL && strncmp(sysfs_parent_device, "usb:", 4) == 0 && strlen(sysfs_parent_device) > 4) + device_index = get_device_attached_to_usb(sysfs_parent_device); if (device_index >= 0 && device_index < EVDI_USAGE_LEN) { evdi_handle handle = evdi_open(device_index); @@ -651,14 +675,16 @@ void evdi_connect(evdi_handle handle, const unsigned char *edid, const unsigned int edid_length, - const uint32_t sku_area_limit) + const uint32_t pixel_area_limit, + const uint32_t pixel_per_second_limit) { struct drm_evdi_connect cmd = { .connected = 1, .dev_index = handle->device_index, .edid = edid, .edid_length = edid_length, - .sku_area_limit = sku_area_limit, + .pixel_area_limit = pixel_area_limit, + .pixel_per_second_limit = pixel_per_second_limit, }; do_ioctl(handle->fd, DRM_IOCTL_EVDI_CONNECT, &cmd, "connect"); @@ -666,44 +692,22 @@ void evdi_disconnect(evdi_handle handle) { - struct drm_evdi_connect cmd = { 0, 0, 0, 0, 0 }; + struct drm_evdi_connect cmd = { 0, 0, 0, 0, 0, 0 }; do_ioctl(handle->fd, DRM_IOCTL_EVDI_CONNECT, &cmd, "disconnect"); } -void evdi_enable_cursor_events(evdi_handle handle) +void evdi_enable_cursor_events(evdi_handle handle, bool enable) { - char path[PATH_MAX] = {0}; - static const char enable[] = "Y"; - int path_len = 0; - FILE *cursor_evs = NULL; - size_t written = 0; - const size_t elem_bytes = 1; - int errcode = 0; - - if (evdi_device_to_platform(handle->device_index, path) != - AVAILABLE) { - evdi_log("Failed to enable cursor events"); - evdi_log("Device /dev/dri/card%d, device is not available.", - handle->device_index); - return; - } + struct drm_evdi_enable_cursor_events cmd = { + .enable = enable, + }; - path_len = strlen(path); - snprintf(path+path_len, PATH_MAX-path_len, "/cursor_events"); - cursor_evs = fopen(path, "w"); - if (cursor_evs == NULL) { - evdi_log("Failed to open %s, err: %s", path, strerror(errno)); - return; - } + evdi_log("%s cursor events on /dev/dri/card%d", + (enable ? "Enabling" : "Disabling"), + handle->device_index); - written = fwrite(enable, elem_bytes, sizeof(enable), cursor_evs); - errcode = errno; - fclose(cursor_evs); - evdi_log("Enabling cursor events on /dev/dri/card%d %s %s", - handle->device_index, - written < sizeof(enable) ? "failed: " : "succeeded", - written < sizeof(enable) ? strerror(errcode) : ""); + do_ioctl(handle->fd, DRM_IOCTL_EVDI_ENABLE_CURSOR_EVENTS, &cmd, "enable cursor events"); } void evdi_grab_pixels(evdi_handle handle, @@ -861,6 +865,8 @@ cursor_set.buffer = malloc(size); memcpy(cursor_set.buffer, ptr, size); munmap(ptr, size); + } else { + evdi_log("Error: mmap failed with error: %s", strerror(errno)); } } @@ -936,10 +942,13 @@ if (evtctx->cursor_set_handler) { struct drm_evdi_event_cursor_set *event = (struct drm_evdi_event_cursor_set *) e; + struct evdi_cursor_set cursor_set = to_evdi_cursor_set(handle, event); - evtctx->cursor_set_handler(to_evdi_cursor_set(handle, - event), - evtctx->user_data); + if (cursor_set.enabled && cursor_set.buffer == NULL) + evdi_log("Error: Cursor buffer is null!"); + else + evtctx->cursor_set_handler(cursor_set, + evtctx->user_data); } break; diff -Nru evdi-1.9.0+dfsg/library/evdi_lib.h evdi-1.12.0+dfsg/library/evdi_lib.h --- evdi-1.9.0+dfsg/library/evdi_lib.h 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/library/evdi_lib.h 2022-07-13 09:58:06.000000000 -0400 @@ -12,7 +12,7 @@ #endif #define LIBEVDI_VERSION_MAJOR 1 -#define LIBEVDI_VERSION_MINOR 9 +#define LIBEVDI_VERSION_MINOR 12 #define LIBEVDI_VERSION_PATCH 0 struct evdi_lib_version { @@ -107,9 +107,10 @@ void evdi_close(evdi_handle handle); void evdi_connect(evdi_handle handle, const unsigned char *edid, const unsigned int edid_length, - const uint32_t sku_area_limit); + const uint32_t pixel_area_limit, + const uint32_t pixel_per_second_limit); void evdi_disconnect(evdi_handle handle); -void evdi_enable_cursor_events(evdi_handle handle); +void evdi_enable_cursor_events(evdi_handle handle, bool enable); void evdi_grab_pixels(evdi_handle handle, struct evdi_rect *rects, diff -Nru evdi-1.9.0+dfsg/library/Makefile evdi-1.12.0+dfsg/library/Makefile --- evdi-1.9.0+dfsg/library/Makefile 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/library/Makefile 2022-07-13 09:58:06.000000000 -0400 @@ -8,9 +8,9 @@ RM ?= rm DEPS = evdi_ioctl.h -CFLAGS := -I../module -std=gnu99 -fPIC $(CFLAGS) +CFLAGS := -I../module -std=gnu99 -fPIC -D_FILE_OFFSET_BITS=64 $(CFLAGS) -LIBVER := 1.9.0 +LIBVER := 1.12.0 LIBABI := 0 PREFIX ?= /usr/local diff -Nru evdi-1.9.0+dfsg/module/dkms.conf evdi-1.12.0+dfsg/module/dkms.conf --- evdi-1.9.0+dfsg/module/dkms.conf 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/dkms.conf 2022-07-13 09:58:06.000000000 -0400 @@ -7,7 +7,7 @@ # PACKAGE_NAME="evdi" -PACKAGE_VERSION=1.9.0 +PACKAGE_VERSION=1.12.0 AUTOINSTALL=yes MAKE[0]="make all INCLUDEDIR=/lib/modules/$kernelver/build/include KVERSION=$kernelver DKMS_BUILD=1" diff -Nru evdi-1.9.0+dfsg/module/evdi_connector.c evdi-1.12.0+dfsg/module/evdi_connector.c --- evdi-1.9.0+dfsg/module/evdi_connector.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_connector.c 2022-07-13 09:58:06.000000000 -0400 @@ -50,11 +50,14 @@ ret = drm_mode_connector_update_edid_property(connector, edid); #endif - if (!ret) - ret = drm_add_edid_modes(connector, edid); - else - EVDI_ERROR("Failed to set edid modes! error: %d", ret); + if (ret) { + EVDI_ERROR("Failed to set edid property! error: %d", ret); + goto err; + } + ret = drm_add_edid_modes(connector, edid); + EVDI_INFO("(card%d) Edid property set", evdi->dev_index); +err: kfree(edid); return ret; } @@ -63,13 +66,15 @@ struct drm_display_mode *mode) { struct evdi_device *evdi = connector->dev->dev_private; - uint32_t mode_area = mode->hdisplay * mode->vdisplay; + uint32_t area_limit = mode->hdisplay * mode->vdisplay; + uint32_t mode_limit = area_limit * drm_mode_vrefresh(mode); - if (evdi->sku_area_limit == 0) + if (evdi->pixel_per_second_limit == 0) return MODE_OK; - if (mode_area > evdi->sku_area_limit) { - EVDI_WARN("(dev=%d) Mode %dx%d@%d rejected\n", + if (area_limit > evdi->pixel_area_limit || + mode_limit > evdi->pixel_per_second_limit) { + EVDI_WARN("(card%d) Mode %dx%d@%d rejected\n", evdi->dev_index, mode->hdisplay, mode->vdisplay, @@ -87,11 +92,11 @@ EVDI_CHECKPT(); if (evdi_painter_is_connected(evdi->painter)) { - EVDI_DEBUG("(dev=%d) poll connector state: connected\n", + EVDI_INFO("(card%d) Connector state: connected\n", evdi->dev_index); return connector_status_connected; } - EVDI_DEBUG("(dev=%d) poll connector state: disconnected\n", + EVDI_VERBOSE("(card%d) Connector state: disconnected\n", evdi->dev_index); return connector_status_disconnected; } diff -Nru evdi-1.9.0+dfsg/module/evdi_cursor.c evdi-1.12.0+dfsg/module/evdi_cursor.c --- evdi-1.9.0+dfsg/module/evdi_cursor.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_cursor.c 2022-07-13 09:58:06.000000000 -0400 @@ -55,7 +55,7 @@ if (obj) drm_gem_object_get(&obj->base); if (cursor->obj) -#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8) drm_gem_object_put(&cursor->obj->base); #else drm_gem_object_put_unlocked(&cursor->obj->base); @@ -232,8 +232,8 @@ bool const is_pix_sane = mouse_pix_x >= 0 && mouse_pix_y >= 0 && - mouse_pix_x < fb->width && - mouse_pix_y < fb->height; + mouse_pix_x < (int)fb->width && + mouse_pix_y < (int)fb->height; if (!is_pix_sane) continue; diff -Nru evdi-1.9.0+dfsg/module/evdi_debug.c evdi-1.12.0+dfsg/module/evdi_debug.c --- evdi-1.9.0+dfsg/module/evdi_debug.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_debug.c 2022-07-13 09:58:06.000000000 -0400 @@ -10,7 +10,7 @@ #include "evdi_debug.h" -void evdi_log_process(void) +void evdi_log_process(char *buf, size_t size) { int task_pid = (int)task_pid_nr(current); char task_comm[TASK_COMM_LEN] = { 0 }; @@ -21,13 +21,13 @@ char process_comm[TASK_COMM_LEN] = { 0 }; get_task_comm(process_comm, current->group_leader); - EVDI_INFO("Task %d (%s) of process %d (%s)\n", + snprintf(buf, size, "Task %d (%s) of process %d (%s)", task_pid, task_comm, (int)task_pid_nr(current->group_leader), process_comm); } else { - EVDI_INFO("Task %d (%s)\n", + snprintf(buf, size, "Task %d (%s)", task_pid, task_comm); } diff -Nru evdi-1.9.0+dfsg/module/evdi_debug.h evdi-1.12.0+dfsg/module/evdi_debug.h --- evdi-1.9.0+dfsg/module/evdi_debug.h 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_debug.h 2022-07-13 09:58:06.000000000 -0400 @@ -11,7 +11,6 @@ #include "evdi_params.h" -#define EVDI_LOGLEVEL_ALWAYS 0 #define EVDI_LOGLEVEL_FATAL 1 #define EVDI_LOGLEVEL_ERROR 2 #define EVDI_LOGLEVEL_WARN 3 @@ -53,6 +52,6 @@ #define EVDI_ENTER() EVDI_VERBOSE("enter\n") #define EVDI_EXIT() EVDI_VERBOSE("exit\n") -void evdi_log_process(void); +void evdi_log_process(char *buf, size_t size); #endif /* EVDI_DEBUG_H */ diff -Nru evdi-1.9.0+dfsg/module/evdi_drm_drv.c evdi-1.12.0+dfsg/module/evdi_drm_drv.c --- evdi-1.9.0+dfsg/module/evdi_drm_drv.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_drm_drv.c 2022-07-13 09:58:06.000000000 -0400 @@ -12,14 +12,22 @@ */ #include <linux/version.h> -#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8) +#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE +#include <drm/drm_ioctl.h> +#include <drm/drm_file.h> +#include <drm/drm_drv.h> +#include <drm/drm_vblank.h> +#elif KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8) #else #include <drm/drmP.h> #endif #if KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE || defined(EL8) #include <drm/drm_probe_helper.h> #endif - +#if KERNEL_VERSION(5, 8, 0) <= LINUX_VERSION_CODE +#include <drm/drm_managed.h> +#endif +#include <drm/drm_atomic_helper.h> #include "evdi_drm_drv.h" #include "evdi_platform_drv.h" #include "evdi_cursor.h" @@ -37,13 +45,18 @@ DRM_UNLOCKED), DRM_IOCTL_DEF_DRV(EVDI_DDCCI_RESPONSE, evdi_painter_ddcci_response_ioctl, DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(EVDI_ENABLE_CURSOR_EVENTS, evdi_painter_enable_cursor_events_ioctl, + DRM_UNLOCKED), }; +#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8) +#else 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, @@ -53,12 +66,16 @@ .read = drm_read, .unlocked_ioctl = drm_ioctl, .release = drm_release, + #ifdef CONFIG_COMPAT .compat_ioctl = evdi_compat_ioctl, #endif + .llseek = noop_llseek, }; +#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8) +#else static int evdi_enable_vblank(__always_unused struct drm_device *dev, __always_unused unsigned int pipe) { @@ -69,30 +86,39 @@ __always_unused unsigned int pipe) { } +#endif static struct drm_driver driver = { -#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE || defined(EL8) .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, #else .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_ATOMIC, #endif - .unload = evdi_driver_unload, - .preclose = evdi_driver_preclose, + .unload = evdi_drm_device_unload, + .open = evdi_driver_open, .postclose = evdi_driver_postclose, /* gem hooks */ -#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8) +#elif KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE .gem_free_object_unlocked = evdi_gem_free_object, #else .gem_free_object = evdi_gem_free_object, #endif + +#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8) +#else .gem_vm_ops = &evdi_gem_vm_ops, +#endif .dumb_create = evdi_dumb_create, .dumb_map_offset = evdi_gem_mmap, +#if KERNEL_VERSION(5, 12, 0) <= LINUX_VERSION_CODE || defined(EL8) +#else .dumb_destroy = drm_gem_dumb_destroy, +#endif .ioctls = evdi_painter_ioctls, .num_ioctls = ARRAY_SIZE(evdi_painter_ioctls), @@ -102,12 +128,15 @@ .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 KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8) +#else + .preclose = evdi_driver_preclose, .gem_prime_export = drm_gem_prime_export, .gem_prime_get_sg_table = evdi_prime_get_sg_table, - .gem_prime_import_sg_table = evdi_prime_import_sg_table, - .enable_vblank = evdi_enable_vblank, .disable_vblank = evdi_disable_vblank, +#endif + .gem_prime_import_sg_table = evdi_prime_import_sg_table, .name = DRIVER_NAME, .desc = DRIVER_DESC, @@ -117,7 +146,15 @@ .patchlevel = DRIVER_PATCH, }; -static int evdi_driver_setup(struct drm_device *dev) +#if KERNEL_VERSION(5, 8, 0) <= LINUX_VERSION_CODE +static void evdi_drm_device_release_cb(__always_unused struct drm_device *dev, + __always_unused void *ptr) +{ + EVDI_INFO("Evdi drm_device removed.\n"); +} +#endif + +static int evdi_drm_device_setup(struct drm_device *dev) { struct evdi_device *evdi; int ret; @@ -129,19 +166,12 @@ evdi->ddev = dev; dev->dev_private = evdi; + evdi->dev_index = dev->primary->index; + evdi->cursor_events_enabled = false; ret = evdi_cursor_init(&evdi->cursor); if (ret) - goto err; - - evdi->cursor_attr = (struct dev_ext_attribute) { - __ATTR(cursor_events, 0644, device_show_bool, device_store_bool), - &evdi->cursor_events_enabled - }; - ret = device_create_file(dev->dev, &evdi->cursor_attr.attr); - if (ret) - goto err_fb; - + goto err_free; EVDI_CHECKPT(); evdi_modeset_init(dev); @@ -149,7 +179,7 @@ #ifdef CONFIG_FB ret = evdi_fbdev_init(dev); if (ret) - goto err; + goto err_cursor; #endif /* CONFIG_FB */ ret = drm_vblank_init(dev, 1); @@ -162,21 +192,26 @@ drm_kms_helper_poll_init(dev); +#if KERNEL_VERSION(5, 8, 0) <= LINUX_VERSION_CODE + ret = drmm_add_action_or_reset(dev, evdi_drm_device_release_cb, NULL); + if (ret) + goto err_fb; +#endif return 0; err_fb: #ifdef CONFIG_FB evdi_fbdev_cleanup(dev); +err_cursor: #endif /* CONFIG_FB */ -err: - EVDI_ERROR("%d\n", ret); - if (evdi->cursor) - evdi_cursor_free(evdi->cursor); + evdi_cursor_free(evdi->cursor); +err_free: + EVDI_ERROR("Failed to setup drm device %d\n", ret); kfree(evdi); return ret; } -void evdi_driver_unload(struct drm_device *dev) +void evdi_drm_device_unload(struct drm_device *dev) { struct evdi_device *evdi = dev->dev_private; @@ -190,7 +225,6 @@ if (evdi->cursor) evdi_cursor_free(evdi->cursor); - device_remove_file(dev->dev, &evdi->cursor_attr.attr); evdi_painter_cleanup(evdi->painter); #ifdef CONFIG_FB evdi_fbdev_cleanup(dev); @@ -200,6 +234,16 @@ kfree(evdi); } +int evdi_driver_open(struct drm_device *drm_dev, __always_unused struct drm_file *file) +{ + struct evdi_device *evdi = drm_dev->dev_private; + char buf[100]; + + evdi_log_process(buf, sizeof(buf)); + EVDI_INFO("(card%d) Opened by %s\n", evdi->dev_index, buf); + return 0; +} + static void evdi_driver_close(struct drm_device *drm_dev, struct drm_file *file) { struct evdi_device *evdi = drm_dev->dev_private; @@ -217,10 +261,11 @@ void evdi_driver_postclose(struct drm_device *drm_dev, struct drm_file *file) { struct evdi_device *evdi = drm_dev->dev_private; + char buf[100]; - EVDI_DEBUG("(dev=%d) Process tries to close us, postclose\n", - evdi ? evdi->dev_index : -1); - evdi_log_process(); + evdi_log_process(buf, sizeof(buf)); + EVDI_INFO("(card%d) Closed by %s\n", + evdi->dev_index, buf); evdi_driver_close(drm_dev, file); } @@ -234,7 +279,7 @@ if (IS_ERR(dev)) return dev; - ret = evdi_driver_setup(dev); + ret = evdi_drm_device_setup(dev); if (ret) goto err_free; @@ -252,6 +297,8 @@ int evdi_drm_device_remove(struct drm_device *dev) { drm_dev_unplug(dev); + drm_atomic_helper_shutdown(dev); + drm_dev_put(dev); return 0; } diff -Nru evdi-1.9.0+dfsg/module/evdi_drm_drv.h evdi-1.12.0+dfsg/module/evdi_drm_drv.h --- evdi-1.9.0+dfsg/module/evdi_drm_drv.h 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_drm_drv.h 2022-07-13 09:58:06.000000000 -0400 @@ -15,16 +15,21 @@ #include <linux/module.h> #include <linux/version.h> +#include <linux/mutex.h> #include <linux/device.h> #if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8) #include <drm/drm_drv.h> #include <drm/drm_fourcc.h> #include <drm/drm_ioctl.h> -#include <drm/drm_irq.h> #include <drm/drm_vblank.h> #else #include <drm/drmP.h> #endif +#if KERNEL_VERSION(5, 15, 0) <= LINUX_VERSION_CODE +#include <drm/drm_legacy.h> +#else +#include <drm/drm_irq.h> +#endif #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_rect.h> @@ -44,10 +49,10 @@ struct drm_device *ddev; struct drm_connector *conn; struct evdi_cursor *cursor; - struct dev_ext_attribute cursor_attr; bool cursor_events_enabled; - uint32_t sku_area_limit; + uint32_t pixel_area_limit; + uint32_t pixel_per_second_limit; struct evdi_fbdev *fbdev; struct evdi_painter *painter; @@ -59,7 +64,12 @@ struct evdi_gem_object { struct drm_gem_object base; struct page **pages; + unsigned int pages_pin_count; + struct mutex pages_lock; void *vmapping; +#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8) + bool vmap_is_iomem; +#endif struct sg_table *sg; #if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE || defined(EL8) struct dma_resv *resv; @@ -68,6 +78,7 @@ struct reservation_object *resv; struct reservation_object _resv; #endif + bool allow_sw_cursor_rect_updates; }; #define to_evdi_bo(x) container_of(x, struct evdi_gem_object, base) @@ -87,8 +98,8 @@ struct drm_encoder *evdi_encoder_init(struct drm_device *dev); -int evdi_driver_load(struct drm_device *dev, unsigned long flags); -void evdi_driver_unload(struct drm_device *dev); +void evdi_drm_device_unload(struct drm_device *dev); +int evdi_driver_open(struct drm_device *drm_dev, struct drm_file *file); void evdi_driver_preclose(struct drm_device *dev, struct drm_file *file_priv); void evdi_driver_postclose(struct drm_device *dev, struct drm_file *file_priv); @@ -96,6 +107,7 @@ long evdi_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); #endif + #ifdef CONFIG_FB int evdi_fbdev_init(struct drm_device *dev); void evdi_fbdev_cleanup(struct drm_device *dev); @@ -146,7 +158,6 @@ void evdi_painter_dpms_notify(struct evdi_device *evdi, int mode); void evdi_painter_mode_changed_notify(struct evdi_device *evdi, struct drm_display_mode *mode); -void evdi_painter_crtc_state_notify(struct evdi_device *evdi, int state); unsigned int evdi_painter_poll(struct file *filp, struct poll_table_struct *wait); @@ -160,6 +171,8 @@ struct drm_file *file); int evdi_painter_ddcci_response_ioctl(struct drm_device *drm_dev, void *data, struct drm_file *file); +int evdi_painter_enable_cursor_events_ioctl(struct drm_device *drm_dev, void *data, + struct drm_file *file); int evdi_painter_init(struct evdi_device *evdi); void evdi_painter_cleanup(struct evdi_painter *painter); diff -Nru evdi-1.9.0+dfsg/module/evdi_drm.h evdi-1.12.0+dfsg/module/evdi_drm.h --- evdi-1.9.0+dfsg/module/evdi_drm.h 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_drm.h 2022-07-13 09:58:06.000000000 -0400 @@ -47,7 +47,8 @@ int32_t dev_index; const unsigned char * __user edid; uint32_t edid_length; - uint32_t sku_area_limit; + uint32_t pixel_area_limit; + uint32_t pixel_per_second_limit; }; struct drm_evdi_request_update { @@ -94,6 +95,11 @@ uint8_t result; }; +struct drm_evdi_enable_cursor_events { + struct drm_event base; + uint8_t enable; +}; + #define DDCCI_BUFFER_SIZE 64 struct drm_evdi_event_ddcci_data { @@ -109,6 +115,7 @@ #define DRM_EVDI_REQUEST_UPDATE 0x01 #define DRM_EVDI_GRABPIX 0x02 #define DRM_EVDI_DDCCI_RESPONSE 0x03 +#define DRM_EVDI_ENABLE_CURSOR_EVENTS 0x04 /* LAST_IOCTL 0x5F -- 96 driver specific ioctls to use */ #define DRM_IOCTL_EVDI_CONNECT DRM_IOWR(DRM_COMMAND_BASE + \ @@ -119,5 +126,7 @@ DRM_EVDI_GRABPIX, struct drm_evdi_grabpix) #define DRM_IOCTL_EVDI_DDCCI_RESPONSE DRM_IOWR(DRM_COMMAND_BASE + \ DRM_EVDI_DDCCI_RESPONSE, struct drm_evdi_ddcci_response) +#define DRM_IOCTL_EVDI_ENABLE_CURSOR_EVENTS DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_EVDI_ENABLE_CURSOR_EVENTS, struct drm_evdi_enable_cursor_events) #endif /* __EVDI_UAPI_DRM_H__ */ diff -Nru evdi-1.9.0+dfsg/module/evdi_fb.c evdi-1.12.0+dfsg/module/evdi_fb.c --- evdi-1.9.0+dfsg/module/evdi_fb.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_fb.c 2022-07-13 09:58:06.000000000 -0400 @@ -25,7 +25,7 @@ #include <drm/drm_crtc_helper.h> #include <drm/drm_fb_helper.h> #include <drm/drm_atomic.h> -#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8) #include <drm/drm_damage_helper.h> #endif #include "evdi_drm_drv.h" @@ -63,28 +63,29 @@ if (rect.x1 > fb->base.width) { - EVDI_WARN("Wrong clip rect: x1 > fb.width\n"); + EVDI_DEBUG("Wrong clip rect: x1 > fb.width\n"); rect.x1 = fb->base.width; } if (rect.y1 > fb->base.height) { - EVDI_WARN("Wrong clip rect: y1 > fb.height\n"); + EVDI_DEBUG("Wrong clip rect: y1 > fb.height\n"); rect.y1 = fb->base.height; } if (rect.x2 > fb->base.width) { - EVDI_WARN("Wrong clip rect: x2 > fb.width\n"); + EVDI_DEBUG("Wrong clip rect: x2 > fb.width\n"); rect.x2 = fb->base.width; } if (rect.y2 > fb->base.height) { - EVDI_WARN("Wrong clip rect: y2 > fb.height\n"); + EVDI_DEBUG("Wrong clip rect: y2 > fb.height\n"); rect.y2 = fb->base.height; } return rect; } +#ifdef CONFIG_FB static int evdi_handle_damage(struct evdi_framebuffer *fb, int x, int y, int width, int height) { @@ -104,7 +105,6 @@ return 0; } -#ifdef CONFIG_FB static int evdi_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) { unsigned long start = vma->vm_start; @@ -221,7 +221,7 @@ }; #endif /* CONFIG_FB */ -#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8) #else /* * Function taken from @@ -243,7 +243,7 @@ struct drm_atomic_state *state; struct drm_plane *plane; int ret = 0; - int i; + unsigned int i; EVDI_CHECKPT(); @@ -319,7 +319,7 @@ EVDI_CHECKPT(); if (efb->obj) -#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8) drm_gem_object_put(&efb->obj->base); #else drm_gem_object_put_unlocked(&efb->obj->base); @@ -331,7 +331,7 @@ static const struct drm_framebuffer_funcs evdifb_funcs = { .create_handle = evdi_user_framebuffer_create_handle, .destroy = evdi_user_framebuffer_destroy, -#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8) .dirty = drm_atomic_helper_dirtyfb, #else .dirty = evdi_user_framebuffer_dirty, @@ -441,7 +441,7 @@ return ret; out_gfree: -#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8) drm_gem_object_put(&efbdev->efb.obj->base); #else drm_gem_object_put_unlocked(&efbdev->efb.obj->base); @@ -471,7 +471,7 @@ if (efbdev->efb.obj) { drm_framebuffer_unregister_private(&efbdev->efb.base); drm_framebuffer_cleanup(&efbdev->efb.base); -#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8) drm_gem_object_put(&efbdev->efb.obj->base); #else drm_gem_object_put_unlocked(&efbdev->efb.obj->base); @@ -493,7 +493,7 @@ evdi->fbdev = efbdev; drm_fb_helper_prepare(dev, &efbdev->helper, &evdi_fb_helper_funcs); -#if KERNEL_VERSION(5, 7, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 7, 0) <= LINUX_VERSION_CODE || defined(EL8) ret = drm_fb_helper_init(dev, &efbdev->helper); #else ret = drm_fb_helper_init(dev, &efbdev->helper, 1); @@ -503,7 +503,7 @@ return ret; } -#if KERNEL_VERSION(5, 7, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 7, 0) <= LINUX_VERSION_CODE || defined(EL8) #else drm_fb_helper_single_add_all_connectors(&efbdev->helper); #endif @@ -541,7 +541,7 @@ struct fb_info *info; info = efbdev->helper.fbdev; -#if KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE || defined(EL8) unregister_framebuffer(info); #else unlink_framebuffer(info); diff -Nru evdi-1.9.0+dfsg/module/evdi_gem.c evdi-1.12.0+dfsg/module/evdi_gem.c --- evdi-1.9.0+dfsg/module/evdi_gem.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_gem.c 2022-07-13 09:58:06.000000000 -0400 @@ -8,16 +8,66 @@ * more details. */ +#include <linux/sched.h> #include <linux/version.h> -#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8) +#if KERNEL_VERSION(5, 18, 0) <= LINUX_VERSION_CODE +#elif KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE +#include <linux/dma-buf-map.h> +#endif +#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE +#include <drm/drm_prime.h> +#include <drm/drm_file.h> +#elif KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8) #else #include <drm/drmP.h> #endif #include "evdi_drm_drv.h" +#include "evdi_params.h" #include <linux/shmem_fs.h> #include <linux/dma-buf.h> #include <drm/drm_cache.h> +#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE +MODULE_IMPORT_NS(DMA_BUF); +#endif + +#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8) +static int evdi_prime_pin(struct drm_gem_object *obj); +static void evdi_prime_unpin(struct drm_gem_object *obj); + +static const struct vm_operations_struct evdi_gem_vm_ops = { + .fault = evdi_gem_fault, + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; + +static struct drm_gem_object_funcs gem_obj_funcs = { + .free = evdi_gem_free_object, + .pin = evdi_prime_pin, + .unpin = evdi_prime_unpin, + .vm_ops = &evdi_gem_vm_ops, + .export = drm_gem_prime_export, + .get_sg_table = evdi_prime_get_sg_table, +}; +#endif + +static bool evdi_was_called_by_mutter(void) +{ + char task_comm[TASK_COMM_LEN] = { 0 }; + + get_task_comm(task_comm, current); + + return strcmp(task_comm, "gnome-shell") == 0; +} + +static bool evdi_drm_gem_object_use_import_attach(struct drm_gem_object *obj) +{ + if (!obj || !obj->import_attach) + return false; + + return obj->import_attach && strcmp(obj->import_attach->dmabuf->owner->name, "amdgpu") != 0; +} + uint32_t evdi_gem_object_handle_lookup(struct drm_file *filp, struct drm_gem_object *obj) { @@ -58,6 +108,14 @@ #endif obj->resv = &obj->_resv; +#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8) + obj->base.funcs = &gem_obj_funcs; +#endif + + obj->allow_sw_cursor_rect_updates = false; + + mutex_init(&obj->pages_lock); + return obj; } @@ -81,11 +139,12 @@ kfree(obj); return ret; } -#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8) drm_gem_object_put(&obj->base); #else drm_gem_object_put_unlocked(&obj->base); #endif + obj->allow_sw_cursor_rect_updates = evdi_was_called_by_mutter(); *handle_p = handle; return 0; } @@ -186,7 +245,7 @@ obj->pages = pages; #if defined(CONFIG_X86) - drm_clflush_pages(obj->pages, obj->base.size / PAGE_SIZE); + drm_clflush_pages(obj->pages, DIV_ROUND_UP(obj->base.size, PAGE_SIZE)); #endif return 0; @@ -204,19 +263,55 @@ obj->pages = NULL; } +static int evdi_pin_pages(struct evdi_gem_object *obj) +{ + int ret = 0; + + mutex_lock(&obj->pages_lock); + if (obj->pages_pin_count++ == 0) { + ret = evdi_gem_get_pages(obj, GFP_KERNEL); + if (ret) + obj->pages_pin_count--; + } + mutex_unlock(&obj->pages_lock); + return ret; +} + +static void evdi_unpin_pages(struct evdi_gem_object *obj) +{ + mutex_lock(&obj->pages_lock); + if (--obj->pages_pin_count == 0) + evdi_gem_put_pages(obj); + mutex_unlock(&obj->pages_lock); +} + int evdi_gem_vmap(struct evdi_gem_object *obj) { - int page_count = obj->base.size / PAGE_SIZE; + int page_count = DIV_ROUND_UP(obj->base.size, PAGE_SIZE); int ret; - if (obj->base.import_attach) { + if (evdi_drm_gem_object_use_import_attach(&obj->base)) { +#if KERNEL_VERSION(5, 18, 0) <= LINUX_VERSION_CODE + struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL); +#elif KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8) + struct dma_buf_map map = DMA_BUF_MAP_INIT_VADDR(NULL); +#endif + +#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8) + ret = dma_buf_vmap(obj->base.import_attach->dmabuf, &map); + if (ret) + return -ENOMEM; + obj->vmapping = map.vaddr; + obj->vmap_is_iomem = map.is_iomem; +#else obj->vmapping = dma_buf_vmap(obj->base.import_attach->dmabuf); if (!obj->vmapping) return -ENOMEM; +#endif return 0; } - ret = evdi_gem_get_pages(obj, GFP_KERNEL); + ret = evdi_pin_pages(obj); if (ret) return ret; @@ -228,8 +323,29 @@ void evdi_gem_vunmap(struct evdi_gem_object *obj) { - if (obj->base.import_attach) { + if (evdi_drm_gem_object_use_import_attach(&obj->base)) { +#if KERNEL_VERSION(5, 18, 0) <= LINUX_VERSION_CODE + struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL); + + if (obj->vmap_is_iomem) + iosys_map_set_vaddr_iomem(&map, obj->vmapping); + else + iosys_map_set_vaddr(&map, obj->vmapping); + + dma_buf_vunmap(obj->base.import_attach->dmabuf, &map); + +#elif KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8) + struct dma_buf_map map; + + if (obj->vmap_is_iomem) + dma_buf_map_set_vaddr_iomem(&map, obj->vmapping); + else + dma_buf_map_set_vaddr(&map, obj->vmapping); + + dma_buf_vunmap(obj->base.import_attach->dmabuf, &map); +#else dma_buf_vunmap(obj->base.import_attach->dmabuf, obj->vmapping); +#endif obj->vmapping = NULL; return; } @@ -239,7 +355,7 @@ obj->vmapping = NULL; } - evdi_gem_put_pages(obj); + evdi_unpin_pages(obj); } void evdi_gem_free_object(struct drm_gem_object *gem_obj) @@ -263,6 +379,7 @@ reservation_object_fini(&obj->_resv); #endif obj->resv = NULL; + mutex_destroy(&obj->pages_lock); } /* @@ -284,7 +401,7 @@ } gobj = to_evdi_bo(obj); - ret = evdi_gem_get_pages(gobj, GFP_KERNEL); + ret = evdi_pin_pages(gobj); if (ret) goto out; @@ -308,12 +425,15 @@ { struct evdi_gem_object *obj; int npages; + bool called_by_mutter; + + called_by_mutter = evdi_was_called_by_mutter(); obj = evdi_gem_alloc_object(dev, attach->dmabuf->size); if (IS_ERR(obj)) return ERR_CAST(obj); - npages = PAGE_ALIGN(attach->dmabuf->size) / PAGE_SIZE; + npages = DIV_ROUND_UP(attach->dmabuf->size, PAGE_SIZE); DRM_DEBUG_PRIME("Importing %d pages\n", npages); obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); if (!obj->pages) { @@ -321,15 +441,36 @@ return ERR_PTR(-ENOMEM); } +#if KERNEL_VERSION(5, 12, 0) <= LINUX_VERSION_CODE || defined(EL8) + drm_prime_sg_to_page_array(sg, obj->pages, npages); +#else drm_prime_sg_to_page_addr_arrays(sg, obj->pages, NULL, npages); +#endif obj->sg = sg; + obj->allow_sw_cursor_rect_updates = called_by_mutter; return &obj->base; } +#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(EL8) +static int evdi_prime_pin(struct drm_gem_object *obj) +{ + struct evdi_gem_object *bo = to_evdi_bo(obj); + + return evdi_pin_pages(bo); +} + +static void evdi_prime_unpin(struct drm_gem_object *obj) +{ + struct evdi_gem_object *bo = to_evdi_bo(obj); + + evdi_unpin_pages(bo); +} +#endif + struct sg_table *evdi_prime_get_sg_table(struct drm_gem_object *obj) { struct evdi_gem_object *bo = to_evdi_bo(obj); - #if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE + #if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE || defined(EL8) return drm_prime_pages_to_sg(obj->dev, bo->pages, bo->base.size >> PAGE_SHIFT); #else return drm_prime_pages_to_sg(bo->pages, bo->base.size >> PAGE_SHIFT); diff -Nru evdi-1.9.0+dfsg/module/evdi_ioc32.c evdi-1.12.0+dfsg/module/evdi_ioc32.c --- evdi-1.9.0+dfsg/module/evdi_ioc32.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_ioc32.c 2022-07-13 09:58:06.000000000 -0400 @@ -22,7 +22,9 @@ #include <linux/compat.h> #include <linux/version.h> -#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8) +#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE +#include <drm/drm_ioctl.h> +#elif KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8) #else #include <drm/drmP.h> #endif @@ -36,7 +38,8 @@ int32_t dev_index; uint32_t edid_ptr32; uint32_t edid_length; - uint32_t sku_area_limit; + uint32_t pixel_area_limit; + uint32_t pixel_per_second_limit; }; struct drm_evdi_grabpix32 { @@ -59,7 +62,11 @@ if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) return -EFAULT; +#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE && KERNEL_VERSION(5, 14, 0) >= LINUX_VERSION_CODE || defined(EL8) request = compat_alloc_user_space(sizeof(*request)); +#else + request = kmalloc(sizeof(*request), GFP_USER); +#endif #if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8) if (!access_ok(request, sizeof(*request)) #else @@ -70,7 +77,8 @@ || __put_user((void __user *)(unsigned long)req32.edid_ptr32, &request->edid) || __put_user(req32.edid_length, &request->edid_length) - || __put_user(req32.sku_area_limit, &request->sku_area_limit)) + || __put_user(req32.pixel_area_limit, &request->pixel_area_limit) + || __put_user(req32.pixel_per_second_limit, &request->pixel_per_second_limit)) return -EFAULT; return drm_ioctl(file, DRM_IOCTL_EVDI_CONNECT, @@ -87,7 +95,11 @@ if (copy_from_user(&req32, (void __user *)arg, sizeof(req32))) return -EFAULT; +#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE && KERNEL_VERSION(5, 14, 0) >= LINUX_VERSION_CODE || defined(EL8) request = compat_alloc_user_space(sizeof(*request)); +#else + request = kmalloc(sizeof(*request), GFP_USER); +#endif #if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8) if (!access_ok(request, sizeof(*request)) #else diff -Nru evdi-1.9.0+dfsg/module/evdi_modeset.c evdi-1.12.0+dfsg/module/evdi_modeset.c --- evdi-1.9.0+dfsg/module/evdi_modeset.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_modeset.c 2022-07-13 09:58:06.000000000 -0400 @@ -12,7 +12,11 @@ */ #include <linux/version.h> -#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8) +#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE +#include <drm/drm_vblank.h> +#include <drm/drm_damage_helper.h> +#elif KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8) +#include <drm/drm_damage_helper.h> #else #include <drm/drmP.h> #endif @@ -25,7 +29,11 @@ #include "evdi_drm_drv.h" #include "evdi_cursor.h" #include "evdi_params.h" +#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE +#include <drm/drm_gem_atomic_helper.h> +#else #include <drm/drm_gem_framebuffer_helper.h> +#endif static void evdi_crtc_dpms(__always_unused struct drm_crtc *crtc, __always_unused int mode) @@ -36,6 +44,7 @@ static void evdi_crtc_disable(__always_unused struct drm_crtc *crtc) { EVDI_CHECKPT(); + drm_crtc_vblank_off(crtc); } static void evdi_crtc_destroy(struct drm_crtc *crtc) @@ -56,25 +65,37 @@ static void evdi_crtc_atomic_flush( struct drm_crtc *crtc +#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(RPI) || defined(EL8) + , struct drm_atomic_state *state +#else , __always_unused struct drm_crtc_state *old_state +#endif ) { - struct drm_crtc_state *state = crtc->state; +#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(RPI) || defined(EL8) + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); +#else + struct drm_crtc_state *crtc_state = crtc->state; +#endif struct evdi_device *evdi = crtc->dev->dev_private; + bool notify_mode_changed = crtc_state->active && + (crtc_state->mode_changed || evdi_painter_needs_full_modeset(evdi->painter)); + bool notify_dpms = crtc_state->active_changed || evdi_painter_needs_full_modeset(evdi->painter); + if (notify_mode_changed) + evdi_painter_mode_changed_notify(evdi, &crtc_state->adjusted_mode); - if (state->mode_changed && state->active) - evdi_painter_mode_changed_notify(evdi, &state->adjusted_mode); - - if (state->active_changed) + if (notify_dpms) evdi_painter_dpms_notify(evdi, - state->active ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF); + crtc_state->active ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF); - evdi_painter_set_vblank(evdi->painter, crtc, state->event); + evdi_painter_set_vblank(evdi->painter, crtc, crtc_state->event); evdi_painter_send_update_ready_if_needed(evdi->painter); - state->event = NULL; + crtc_state->event = NULL; } +#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE || defined(EL8) +#else static void evdi_mark_full_screen_dirty(struct evdi_device *evdi) { const struct drm_clip_rect rect = @@ -125,7 +146,7 @@ evdi_cursor_set(evdi->cursor, eobj, width, height, hot_x, hot_y, format, stride); -#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8) drm_gem_object_put(obj); #else drm_gem_object_put_unlocked(obj); @@ -157,6 +178,7 @@ return 0; } +#endif static struct drm_crtc_helper_funcs evdi_helper_funcs = { .mode_set_nofb = evdi_crtc_set_nofb, @@ -167,6 +189,17 @@ .disable = evdi_crtc_disable }; +#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(RPI) || defined(EL8) +static int evdi_enable_vblank(__always_unused struct drm_crtc *crtc) +{ + return 1; +} + +static void evdi_disable_vblank(__always_unused struct drm_crtc *crtc) +{ +} +#endif + static const struct drm_crtc_funcs evdi_crtc_funcs = { .reset = drm_atomic_helper_crtc_reset, .destroy = evdi_crtc_destroy, @@ -175,18 +208,40 @@ .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, +#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE || defined(EL8) +#else .cursor_set2 = evdi_crtc_cursor_set, - .cursor_move = evdi_crtc_cursor_move + .cursor_move = evdi_crtc_cursor_move, +#endif +#if KERNEL_VERSION(5, 11, 0) <= LINUX_VERSION_CODE || defined(RPI) || defined(EL8) + .enable_vblank = evdi_enable_vblank, + .disable_vblank = evdi_disable_vblank, +#endif }; static void evdi_plane_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) +#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE + struct drm_atomic_state *atom_state +#else + struct drm_plane_state *old_state +#endif + ) { +#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(atom_state, plane); +#else +#endif struct drm_plane_state *state; struct evdi_device *evdi; struct evdi_painter *painter; struct drm_crtc *crtc; +#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8) + struct drm_atomic_helper_damage_iter iter; + struct drm_rect rect; + struct drm_clip_rect clip_rect; +#endif + if (!plane || !plane->state) { EVDI_WARN("Plane state is null\n"); return; @@ -228,10 +283,28 @@ evdi_painter_needs_full_modeset(painter)) { evdi_painter_set_scanout_buffer(painter, efb); + +#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8) + state->visible = true; + state->src.x1 = 0; + state->src.y1 = 0; + state->src.x2 = fb->width << 16; + state->src.y2 = fb->height << 16; + + drm_atomic_helper_damage_iter_init(&iter, old_state, state); + while (drm_atomic_helper_damage_iter_next(&iter, &rect)) { + clip_rect.x1 = rect.x1; + clip_rect.y1 = rect.y1; + clip_rect.x2 = rect.x2; + clip_rect.y2 = rect.y2; + evdi_painter_mark_dirty(evdi, &clip_rect); + } +#endif + + }; + + if (evdi_painter_get_num_dirts(painter) == 0) evdi_painter_mark_dirty(evdi, &fullscreen_rect); - } else if (evdi_painter_get_num_dirts(painter) == 0) { - evdi_painter_mark_dirty(evdi, &fullscreen_rect); - } } } @@ -245,8 +318,17 @@ } static void evdi_cursor_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) +#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE + struct drm_atomic_state *atom_state +#else + struct drm_plane_state *old_state +#endif + ) { +#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(atom_state, plane); +#else +#endif if (plane && plane->state && plane->dev && plane->dev->dev_private) { struct drm_plane_state *state = plane->state; struct evdi_device *evdi = plane->dev->dev_private; @@ -288,13 +370,20 @@ mutex_unlock(&plane->dev->struct_mutex); if (!evdi->cursor_events_enabled) { - evdi_cursor_atomic_get_rect(&old_rect, old_state); - evdi_cursor_atomic_get_rect(&rect, state); - - evdi_painter_mark_dirty(evdi, &old_rect); - evdi_painter_mark_dirty(evdi, &rect); + if (fb != NULL) { + if (efb->obj->allow_sw_cursor_rect_updates) { + evdi_cursor_atomic_get_rect(&old_rect, old_state); + evdi_cursor_atomic_get_rect(&rect, state); + + evdi_painter_mark_dirty(evdi, &old_rect); + } else { + rect = evdi_painter_framebuffer_size(evdi->painter); + } + evdi_painter_mark_dirty(evdi, &rect); + } return; } + if (cursor_changed) evdi_painter_send_cursor_set(evdi->painter, evdi->cursor); @@ -306,12 +395,20 @@ static const struct drm_plane_helper_funcs evdi_plane_helper_funcs = { .atomic_update = evdi_plane_atomic_update, +#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE + .prepare_fb = drm_gem_plane_helper_prepare_fb +#else .prepare_fb = drm_gem_fb_prepare_fb +#endif }; static const struct drm_plane_helper_funcs evdi_cursor_helper_funcs = { .atomic_update = evdi_cursor_atomic_update, +#if KERNEL_VERSION(5, 13, 0) <= LINUX_VERSION_CODE + .prepare_fb = drm_gem_plane_helper_prepare_fb +#else .prepare_fb = drm_gem_fb_prepare_fb +#endif }; static const struct drm_plane_funcs evdi_plane_funcs = { @@ -337,10 +434,11 @@ { struct drm_plane *plane; int ret; + char *plane_type = (type == DRM_PLANE_TYPE_CURSOR) ? "cursor" : "primary"; plane = kzalloc(sizeof(*plane), GFP_KERNEL); if (plane == NULL) { - EVDI_ERROR("Failed to allocate primary plane\n"); + EVDI_ERROR("Failed to allocate %s plane\n", plane_type); return NULL; } plane->format_default = true; @@ -357,7 +455,7 @@ ); if (ret) { - EVDI_ERROR("Failed to initialize primary plane\n"); + EVDI_ERROR("Failed to initialize %s plane\n", plane_type); kfree(plane); return NULL; } @@ -381,6 +479,16 @@ primary_plane = evdi_create_plane(dev, DRM_PLANE_TYPE_PRIMARY, &evdi_plane_helper_funcs); + +#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE || defined(EL8) + cursor_plane = evdi_create_plane(dev, DRM_PLANE_TYPE_CURSOR, + &evdi_cursor_helper_funcs); +#endif + +#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE || defined(EL8) + drm_plane_enable_fb_damage_clips(primary_plane); +#endif + status = drm_crtc_init_with_planes(dev, crtc, primary_plane, cursor_plane, &evdi_crtc_funcs, @@ -393,29 +501,11 @@ return 0; } -static int evdi_atomic_check(struct drm_device *dev, - struct drm_atomic_state *state) -{ - struct drm_crtc *crtc; - struct drm_crtc_state *crtc_state; - int i; - struct evdi_device *evdi = dev->dev_private; - - if (evdi_painter_needs_full_modeset(evdi->painter)) { - for_each_new_crtc_in_state(state, crtc, crtc_state, i) { - crtc_state->active_changed = true; - crtc_state->mode_changed = true; - } - } - - return drm_atomic_helper_check(dev, state); -} - static const struct drm_mode_config_funcs evdi_mode_funcs = { .fb_create = evdi_fb_user_fb_create, .output_poll_changed = NULL, .atomic_commit = drm_atomic_helper_commit, - .atomic_check = evdi_atomic_check + .atomic_check = drm_atomic_helper_check }; void evdi_modeset_init(struct drm_device *dev) @@ -429,8 +519,8 @@ dev->mode_config.min_width = 64; dev->mode_config.min_height = 64; - dev->mode_config.max_width = 3840; - dev->mode_config.max_height = 2160; + dev->mode_config.max_width = 7680; + dev->mode_config.max_height = 4320; dev->mode_config.prefer_shadow = 0; dev->mode_config.preferred_depth = 24; @@ -446,8 +536,10 @@ drm_mode_config_reset(dev); } -void evdi_modeset_cleanup(struct drm_device *dev) +void evdi_modeset_cleanup(__maybe_unused struct drm_device *dev) { - EVDI_CHECKPT(); +#if KERNEL_VERSION(5, 8, 0) <= LINUX_VERSION_CODE +#else drm_mode_config_cleanup(dev); +#endif } diff -Nru evdi-1.9.0+dfsg/module/evdi_painter.c evdi-1.12.0+dfsg/module/evdi_painter.c --- evdi-1.9.0+dfsg/module/evdi_painter.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_painter.c 2022-07-13 09:58:06.000000000 -0400 @@ -10,7 +10,11 @@ #include "linux/thread_info.h" #include "linux/mm.h" #include <linux/version.h> -#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8) +#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE +#include <drm/drm_file.h> +#include <drm/drm_vblank.h> +#include <drm/drm_ioctl.h> +#elif KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8) #else #include <drm/drmP.h> #endif @@ -27,6 +31,10 @@ #include <linux/dma-buf.h> +#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE +MODULE_IMPORT_NS(DMA_BUF); +#endif + #if KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE || defined(EL8) #include <drm/drm_probe_helper.h> #endif @@ -239,7 +247,6 @@ memcpy(block, evdi->painter->edid, evdi->painter->edid_length); - EVDI_DEBUG("(dev=%d) EDID valid\n", evdi->dev_index); } } painter_unlock(evdi->painter); @@ -318,7 +325,7 @@ } if (!painter->drm_filp) { - EVDI_WARN("Painter is not connected!"); + EVDI_VERBOSE("Painter is not connected!"); drm_event_cancel_free(painter->drm_device, event); return; } @@ -496,31 +503,6 @@ evdi_painter_send_event(painter, event); } -static struct drm_pending_event *create_crtc_state_event(int state) -{ - struct evdi_event_crtc_state_pending *event; - - event = kzalloc(sizeof(*event), GFP_KERNEL); - if (!event) { - EVDI_ERROR("Failed to create crtc state event"); - return NULL; - } - - event->crtc_state.base.type = DRM_EVDI_EVENT_CRTC_STATE; - event->crtc_state.base.length = sizeof(event->crtc_state); - event->crtc_state.state = state; - event->base.event = &event->crtc_state.base; - return &event->base; -} - -static void evdi_painter_send_crtc_state(struct evdi_painter *painter, - int state) -{ - struct drm_pending_event *event = create_crtc_state_event(state); - - evdi_painter_send_event(painter, event); -} - static struct drm_pending_event *create_mode_changed_event( struct drm_display_mode *current_mode, int32_t bits_per_pixel, @@ -591,7 +573,8 @@ painter_lock(painter); efb = painter->scanout_fb; if (!efb) { - EVDI_DEBUG("Scanout buffer not set."); + if (painter->is_connected) + EVDI_WARN("Scanout buffer not set."); goto unlock; } rect.x1 = 0; @@ -618,14 +601,15 @@ painter_lock(painter); efb = painter->scanout_fb; if (!efb) { - EVDI_DEBUG("(dev=%d) Skip clip rect. Scanout buffer not set.\n", + if (painter->is_connected) + EVDI_WARN("(card%d) Skip clip rect. Scanout buffer not set.\n", evdi->dev_index); goto unlock; } rect = evdi_framebuffer_sanitize_rect(efb, dirty_rect); - EVDI_VERBOSE("(dev=%d) %d,%d-%d,%d\n", evdi->dev_index, rect.x1, + EVDI_VERBOSE("(card%d) %d,%d-%d,%d\n", evdi->dev_index, rect.x1, rect.y1, rect.x2, rect.y2); if (painter->num_dirts == MAX_DIRTS) @@ -695,8 +679,11 @@ EVDI_CHECKPT(); if (painter) { painter_lock(painter); - +#if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE || defined(EL8) + if (painter->was_update_requested && painter->num_dirts) { +#else if (painter->was_update_requested) { +#endif evdi_painter_send_update_ready(painter); painter->was_update_requested = false; } @@ -707,38 +694,47 @@ } } +static const char * const dpms_str[] = { "on", "standby", "suspend", "off" }; + void evdi_painter_dpms_notify(struct evdi_device *evdi, int mode) { struct evdi_painter *painter = evdi->painter; + const char *mode_str; - if (painter) { - EVDI_DEBUG("(dev=%d) Notifying dpms mode: %d\n", - evdi->dev_index, mode); - evdi_painter_send_dpms(painter, mode); - } else { - EVDI_WARN("Painter does not exist!"); + if (!painter) { + EVDI_WARN("(card%d) Painter does not exist!", evdi->dev_index); + return; } -} -void evdi_painter_crtc_state_notify(struct evdi_device *evdi, int state) -{ - struct evdi_painter *painter = evdi->painter; + if (!painter->is_connected) + return; - if (painter) { - EVDI_DEBUG("(dev=%d) Notifying crtc state: %d\n", - evdi->dev_index, state); - evdi_painter_send_crtc_state(painter, state); - } else { - EVDI_WARN("Painter does not exist!"); - } + switch (mode) { + case DRM_MODE_DPMS_ON: + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: + mode_str = dpms_str[mode]; + break; + default: + mode_str = "unknown"; + }; + EVDI_INFO("(card%d) Notifying display power state: %s", + evdi->dev_index, mode_str); + evdi_painter_send_dpms(painter, mode); } -static void evdi_log_pixel_format(uint32_t pixel_format) +static void evdi_log_pixel_format(uint32_t pixel_format, + char *buf, size_t size) { +#if KERNEL_VERSION(5, 14, 0) <= LINUX_VERSION_CODE + snprintf(buf, size, "pixel format %p4cc", &pixel_format); +#else struct drm_format_name_buf format_name; drm_get_format_name(pixel_format, &format_name); - EVDI_DEBUG("pixel format %s\n", format_name.str); + snprintf(buf, size, "pixel format %s", format_name.str); +#endif } void evdi_painter_mode_changed_notify(struct evdi_device *evdi, @@ -748,6 +744,7 @@ struct drm_framebuffer *fb; int bits_per_pixel; uint32_t pixel_format; + char buf[100]; if (painter == NULL) return; @@ -759,10 +756,11 @@ bits_per_pixel = fb->format->cpp[0] * 8; pixel_format = fb->format->format; - EVDI_DEBUG("(dev=%d) Notifying mode changed: %dx%d@%d; bpp %d; ", + + evdi_log_pixel_format(pixel_format, buf, sizeof(buf)); + EVDI_INFO("(card%d) Notifying mode changed: %dx%d@%d; bpp %d; %s", evdi->dev_index, new_mode->hdisplay, new_mode->vdisplay, - drm_mode_vrefresh(new_mode), bits_per_pixel); - evdi_log_pixel_format(pixel_format); + drm_mode_vrefresh(new_mode), bits_per_pixel, buf); evdi_painter_send_mode_changed(painter, new_mode, @@ -795,7 +793,7 @@ evdi->i2c_adapter = kzalloc(sizeof(*evdi->i2c_adapter), GFP_KERNEL); if (!evdi->i2c_adapter) { - EVDI_ERROR("(dev=%d) Failed to allocate for i2c adapter", + EVDI_ERROR("(card%d) Failed to allocate for i2c adapter", evdi->dev_index); return; } @@ -805,19 +803,19 @@ if (result) { kfree(evdi->i2c_adapter); evdi->i2c_adapter = NULL; - EVDI_ERROR("(dev=%d) Failed to add i2c adapter, error %d", + EVDI_ERROR("(card%d) Failed to add i2c adapter, error %d", evdi->dev_index, result); return; } - EVDI_DEBUG("(dev=%d) Added i2c adapter bus number %d", + EVDI_INFO("(card%d) Added i2c adapter bus number %d", evdi->dev_index, evdi->i2c_adapter->nr); result = sysfs_create_link(&evdi->conn->kdev->kobj, &evdi->i2c_adapter->dev.kobj, "ddc"); if (result) { - EVDI_ERROR("(dev=%d) Failed to create sysfs link, error %d", + EVDI_ERROR("(card%d) Failed to create sysfs link, error %d", evdi->dev_index, result); return; } @@ -826,7 +824,7 @@ static void evdi_remove_i2c_adapter(struct evdi_device *evdi) { if (evdi->i2c_adapter) { - EVDI_DEBUG("(dev=%d) Removing i2c adapter bus number %d", + EVDI_INFO("(card%d) Removing i2c adapter bus number %d", evdi->dev_index, evdi->i2c_adapter->nr); sysfs_remove_link(&evdi->conn->kdev->kobj, "ddc"); @@ -841,16 +839,16 @@ static int evdi_painter_connect(struct evdi_device *evdi, void const __user *edid_data, unsigned int edid_length, - uint32_t sku_area_limit, - struct drm_file *file, int dev_index) + uint32_t pixel_area_limit, + uint32_t pixel_per_second_limit, + struct drm_file *file, __always_unused int dev_index) { struct evdi_painter *painter = evdi->painter; struct edid *new_edid = NULL; - int expected_edid_size = 0; + unsigned int expected_edid_size = 0; + char buf[100]; - EVDI_DEBUG("(dev=%d) Process is trying to connect\n", - evdi->dev_index); - evdi_log_process(); + evdi_log_process(buf, sizeof(buf)); if (edid_length < sizeof(struct edid)) { EVDI_ERROR("Edid length too small\n"); @@ -867,7 +865,7 @@ return -ENOMEM; if (copy_from_user(new_edid, edid_data, edid_length)) { - EVDI_ERROR("(dev=%d) Failed to read edid\n", dev_index); + EVDI_ERROR("(card%d) Failed to read edid\n", evdi->dev_index); kfree(new_edid); return -EFAULT; } @@ -882,13 +880,13 @@ } if (painter->drm_filp) - EVDI_WARN("(dev=%d) Double connect - replacing %p with %p\n", - dev_index, painter->drm_filp, file); + EVDI_WARN("(card%d) Double connect - replacing %p with %p\n", + evdi->dev_index, painter->drm_filp, file); painter_lock(painter); - evdi->dev_index = dev_index; - evdi->sku_area_limit = sku_area_limit; + evdi->pixel_area_limit = pixel_area_limit; + evdi->pixel_per_second_limit = pixel_per_second_limit; painter->drm_filp = file; kfree(painter->edid); painter->edid_length = edid_length; @@ -896,12 +894,12 @@ painter->is_connected = true; painter->needs_full_modeset = true; - evdi_add_i2c_adapter(evdi); + if (!evdi->i2c_adapter) + evdi_add_i2c_adapter(evdi); painter_unlock(painter); - EVDI_DEBUG("(dev=%d) Connected with %p\n", evdi->dev_index, - painter->drm_filp); + EVDI_INFO("(card%d) Connected with %s\n", evdi->dev_index, buf); drm_helper_hpd_irq_event(evdi->ddev); @@ -912,6 +910,7 @@ struct drm_file *file) { struct evdi_painter *painter = evdi->painter; + char buf[100]; EVDI_CHECKPT(); @@ -929,8 +928,8 @@ painter->is_connected = false; - EVDI_DEBUG("(dev=%d) Disconnected from %p\n", evdi->dev_index, - painter->drm_filp); + evdi_log_process(buf, sizeof(buf)); + EVDI_INFO("(card%d) Disconnected from %s\n", evdi->dev_index, buf); evdi_painter_events_cleanup(painter); evdi_painter_send_vblank(painter); @@ -944,7 +943,6 @@ evdi_remove_i2c_adapter(evdi); painter->drm_filp = NULL; - evdi->dev_index = -1; painter->was_update_requested = false; evdi->cursor_events_enabled = false; @@ -962,10 +960,8 @@ { EVDI_CHECKPT(); - if (evdi->painter) + if (evdi->painter && file == evdi->painter->drm_filp) evdi_painter_disconnect(evdi, file); - else - EVDI_WARN("Painter does not exist!"); } int evdi_painter_connect_ioctl(struct drm_device *drm_dev, void *data, @@ -982,19 +978,20 @@ ret = evdi_painter_connect(evdi, cmd->edid, cmd->edid_length, - cmd->sku_area_limit, + cmd->pixel_area_limit, + cmd->pixel_per_second_limit, file, cmd->dev_index); else ret = evdi_painter_disconnect(evdi, file); if (ret) { - EVDI_WARN("(dev=%d)(pid=%d) disconnect failed\n", + EVDI_WARN("(card%d)(pid=%d) disconnect failed\n", evdi->dev_index, (int)task_pid_nr(current)); } return ret; } - EVDI_WARN("Painter does not exist!"); + EVDI_WARN("(card%d) Painter does not exist!", evdi->dev_index); return -ENODEV; } @@ -1030,7 +1027,7 @@ painter_lock(painter); if (painter->was_update_requested) { - EVDI_WARN("(dev=%d) Update ready not sent,", + EVDI_WARN("(card%d) Update ready not sent,", evdi->dev_index); EVDI_WARN(" but pixels are grabbed.\n"); } @@ -1084,9 +1081,9 @@ } } - if (cmd->buf_width != efb->base.width || - cmd->buf_height != efb->base.height) { - EVDI_ERROR("Invalid buffer dimension\n"); + if ((unsigned int)cmd->buf_width != efb->base.width || + (unsigned int)cmd->buf_height != efb->base.height) { + EVDI_DEBUG("Invalid buffer dimension\n"); err = -EINVAL; goto err_fb; } @@ -1149,7 +1146,7 @@ if (painter->was_update_requested) { EVDI_WARN - ("(dev=%d) Update was already requested - ignoring\n", + ("(card%d) Update was already requested - ignoring\n", evdi->dev_index); } else { if (painter->num_dirts > 0) @@ -1210,6 +1207,9 @@ kfree(painter->edid); painter->edid_length = 0; painter->edid = NULL; + if (painter->scanout_fb) + drm_framebuffer_put(&painter->scanout_fb->base); + painter->scanout_fb = NULL; evdi_painter_send_vblank(painter); @@ -1318,7 +1318,7 @@ } if (msg->addr != I2C_ADDRESS_DDCCI) { - EVDI_DEBUG("Ignored ddc/ci data for address 0x%x\n", msg->addr); + EVDI_WARN("Ignored ddc/ci data for address 0x%x\n", msg->addr); return false; } @@ -1363,3 +1363,14 @@ painter_unlock(painter); return result; } + +int evdi_painter_enable_cursor_events_ioctl(struct drm_device *drm_dev, void *data, + __always_unused struct drm_file *file) +{ + struct evdi_device *evdi = drm_dev->dev_private; + struct drm_evdi_enable_cursor_events *cmd = data; + + evdi->cursor_events_enabled = cmd->enable; + + return 0; +} diff -Nru evdi-1.9.0+dfsg/module/evdi_params.c evdi-1.12.0+dfsg/module/evdi_params.c --- evdi-1.9.0+dfsg/module/evdi_params.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_params.c 2022-07-13 09:58:06.000000000 -0400 @@ -13,7 +13,7 @@ #include "evdi_params.h" #include "evdi_debug.h" -unsigned int evdi_loglevel __read_mostly = EVDI_LOGLEVEL_DEBUG; +unsigned int evdi_loglevel __read_mostly = EVDI_LOGLEVEL_INFO; unsigned short int evdi_initial_device_count __read_mostly; module_param_named(initial_loglevel, evdi_loglevel, int, 0400); @@ -22,3 +22,4 @@ module_param_named(initial_device_count, evdi_initial_device_count, ushort, 0644); MODULE_PARM_DESC(initial_device_count, "Initial DRM device count (default: 0)"); + diff -Nru evdi-1.9.0+dfsg/module/evdi_platform_dev.c evdi-1.12.0+dfsg/module/evdi_platform_dev.c --- evdi-1.9.0+dfsg/module/evdi_platform_dev.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_platform_dev.c 2022-07-13 09:58:06.000000000 -0400 @@ -21,7 +21,7 @@ #include <linux/dma-mapping.h> #include <linux/platform_device.h> #include <linux/slab.h> -#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8) #include <linux/iommu.h> #endif @@ -41,8 +41,8 @@ platform_dev = platform_device_register_full(info); if (dma_set_mask(&platform_dev->dev, DMA_BIT_MASK(64))) { - EVDI_DEBUG("Unable to change dma mask to 64 bit. "); - EVDI_DEBUG("Sticking with 32 bit\n"); + EVDI_WARN("Unable to change dma mask to 64 bit. "); + EVDI_WARN("Sticking with 32 bit\n"); } EVDI_INFO("Evdi platform_device create\n"); @@ -58,20 +58,22 @@ int evdi_platform_device_probe(struct platform_device *pdev) { - struct drm_device *dev = NULL; - struct evdi_platform_device_data *data = - kzalloc(sizeof(struct evdi_platform_device_data), GFP_KERNEL); + struct drm_device *dev; + struct evdi_platform_device_data *data; -#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8) #if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU) struct dev_iommu iommu; #endif #endif EVDI_CHECKPT(); + data = kzalloc(sizeof(struct evdi_platform_device_data), GFP_KERNEL); + if (!data) + return -ENOMEM; /* Intel-IOMMU workaround: platform-bus unsupported, force ID-mapping */ #if IS_ENABLED(CONFIG_IOMMU_API) && defined(CONFIG_INTEL_IOMMU) -#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE +#if KERNEL_VERSION(5, 9, 0) <= LINUX_VERSION_CODE || defined(EL8) memset(&iommu, 0, sizeof(iommu)); iommu.priv = (void *)-1; pdev->dev.iommu = &iommu; @@ -83,20 +85,21 @@ dev = evdi_drm_device_create(&pdev->dev); if (IS_ERR_OR_NULL(dev)) - kfree(data); - else { - data->drm_dev = dev; - data->symlinked = false; - platform_set_drvdata(pdev, data); - } + goto err_free; + data->drm_dev = dev; + data->symlinked = false; + platform_set_drvdata(pdev, data); + return PTR_ERR_OR_ZERO(dev); + +err_free: + kfree(data); return PTR_ERR_OR_ZERO(dev); } int evdi_platform_device_remove(struct platform_device *pdev) { - struct evdi_platform_device_data *data = - (struct evdi_platform_device_data *)platform_get_drvdata(pdev); + struct evdi_platform_device_data *data = platform_get_drvdata(pdev); EVDI_CHECKPT(); @@ -107,8 +110,7 @@ bool evdi_platform_device_is_free(struct platform_device *pdev) { - struct evdi_platform_device_data *data = - (struct evdi_platform_device_data *)platform_get_drvdata(pdev); + struct evdi_platform_device_data *data = platform_get_drvdata(pdev); struct evdi_device *evdi = data->drm_dev->dev_private; if (evdi && !evdi_painter_is_connected(evdi->painter) && @@ -121,23 +123,21 @@ struct device *parent) { struct evdi_platform_device_data *data = NULL; - char evdi_name[10] = { 0 }; int ret = 0; if (!parent || !pdev) return; - data = (struct evdi_platform_device_data *)platform_get_drvdata(pdev); + data = platform_get_drvdata(pdev); if (!evdi_platform_device_is_free(pdev)) { EVDI_FATAL("Device is already attached can't symlink again\n"); return; } - snprintf(evdi_name, sizeof(evdi_name), "evdi.%d", pdev->id); - ret = sysfs_create_link(&parent->kobj, &pdev->dev.kobj, evdi_name); - if (ret) - EVDI_FATAL("Failed to create sysfs link to parent device\n"); - else { + ret = sysfs_create_link(&pdev->dev.kobj, &parent->kobj, "device"); + if (ret) { + EVDI_FATAL("Failed to create sysfs link from evdi to parent device\n"); + } else { data->symlinked = true; data->parent = parent; } @@ -146,10 +146,10 @@ void evdi_platform_device_unlink_if_linked_with(struct platform_device *pdev, struct device *parent) { - struct evdi_platform_device_data *data = - (struct evdi_platform_device_data *)platform_get_drvdata(pdev); + struct evdi_platform_device_data *data = platform_get_drvdata(pdev); - if (data->parent == parent) { + if (parent && data->parent == parent) { + sysfs_remove_link(&pdev->dev.kobj, "device"); data->symlinked = false; data->parent = NULL; EVDI_INFO("Detached from parent device\n"); diff -Nru evdi-1.9.0+dfsg/module/evdi_platform_drv.c evdi-1.12.0+dfsg/module/evdi_platform_drv.c --- evdi-1.9.0+dfsg/module/evdi_platform_drv.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_platform_drv.c 2022-07-13 09:58:06.000000000 -0400 @@ -31,8 +31,15 @@ unsigned int dev_count; struct platform_device *devices[EVDI_DEVICE_COUNT_MAX]; struct notifier_block usb_notifier; + struct mutex lock; } g_ctx; +#define evdi_platform_drv_context_lock(ctx) \ + mutex_lock(&ctx->lock) + +#define evdi_platform_drv_context_unlock(ctx) \ + mutex_unlock(&ctx->lock) + static int evdi_platform_drv_usb(__always_unused struct notifier_block *nb, unsigned long action, void *data) @@ -54,8 +61,10 @@ if (pdev->dev.parent == &usb_dev->dev) { EVDI_INFO("Parent USB removed. Removing evdi.%d\n", i); evdi_platform_dev_destroy(pdev); + evdi_platform_drv_context_lock((&g_ctx)); g_ctx.dev_count--; g_ctx.devices[i] = NULL; + evdi_platform_drv_context_unlock((&g_ctx)); } } return 0; @@ -116,10 +125,15 @@ { struct evdi_platform_drv_context *ctx = (struct evdi_platform_drv_context *)dev_get_drvdata(device); - struct platform_device *pdev = evdi_platform_drv_get_free_device(ctx); + struct platform_device *pdev = NULL; + + evdi_platform_drv_context_lock(ctx); + if (parent) + pdev = evdi_platform_drv_get_free_device(ctx); if (IS_ERR_OR_NULL(pdev)) pdev = evdi_platform_drv_create_new_device(ctx); + evdi_platform_drv_context_unlock(ctx); if (IS_ERR_OR_NULL(pdev)) return -EINVAL; @@ -130,19 +144,18 @@ int evdi_platform_add_devices(struct device *device, unsigned int val) { - struct evdi_platform_drv_context *ctx = - (struct evdi_platform_drv_context *)dev_get_drvdata(device); + unsigned int dev_count = evdi_platform_device_count(device); if (val == 0) { EVDI_WARN("Adding 0 devices has no effect\n"); return 0; } - if (val > EVDI_DEVICE_COUNT_MAX - ctx->dev_count) { + if (val > EVDI_DEVICE_COUNT_MAX - dev_count) { EVDI_ERROR("Evdi device add failed. Too many devices.\n"); return -EINVAL; } - EVDI_DEBUG("Increasing device count to %u\n", ctx->dev_count + val); + EVDI_INFO("Increasing device count to %u\n", dev_count + val); while (val-- && evdi_platform_device_add(device, NULL) == 0) ; return 0; @@ -154,6 +167,7 @@ struct evdi_platform_drv_context *ctx = (struct evdi_platform_drv_context *)dev_get_drvdata(device); + evdi_platform_drv_context_lock(ctx); for (i = 0; i < EVDI_DEVICE_COUNT_MAX; ++i) { if (ctx->devices[i]) { EVDI_INFO("Removing evdi %d\n", i); @@ -163,14 +177,21 @@ } } ctx->dev_count = 0; + evdi_platform_drv_context_unlock(ctx); } -int evdi_platform_device_count(struct device *device) +unsigned int evdi_platform_device_count(struct device *device) { - struct evdi_platform_drv_context *ctx = - (struct evdi_platform_drv_context *)dev_get_drvdata(device); + unsigned int count = 0; + struct evdi_platform_drv_context *ctx = NULL; + + ctx = (struct evdi_platform_drv_context *)dev_get_drvdata(device); + evdi_platform_drv_context_lock(ctx); + count = ctx->dev_count; + evdi_platform_drv_context_unlock(ctx); + + return count; - return ctx->dev_count; } static struct platform_driver evdi_platform_driver = { @@ -193,6 +214,7 @@ memset(&g_ctx, 0, sizeof(g_ctx)); g_ctx.root_dev = root_device_register(DRIVER_NAME); g_ctx.usb_notifier.notifier_call = evdi_platform_drv_usb; + mutex_init(&g_ctx.lock); dev_set_drvdata(g_ctx.root_dev, &g_ctx); usb_register_notify(&g_ctx.usb_notifier); diff -Nru evdi-1.9.0+dfsg/module/evdi_platform_drv.h evdi-1.12.0+dfsg/module/evdi_platform_drv.h --- evdi-1.9.0+dfsg/module/evdi_platform_drv.h 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_platform_drv.h 2022-07-13 09:58:06.000000000 -0400 @@ -25,14 +25,14 @@ #define DRIVER_NAME "evdi" #define DRIVER_DESC "Extensible Virtual Display Interface" -#define DRIVER_DATE "20201210" +#define DRIVER_DATE "20220713" #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 9 +#define DRIVER_MINOR 12 #define DRIVER_PATCH 0 void evdi_platform_remove_all_devices(struct device *device); -int evdi_platform_device_count(struct device *device); +unsigned int evdi_platform_device_count(struct device *device); int evdi_platform_add_devices(struct device *device, unsigned int val); int evdi_platform_device_add(struct device *device, struct device *parent); diff -Nru evdi-1.9.0+dfsg/module/evdi_sysfs.c evdi-1.12.0+dfsg/module/evdi_sysfs.c --- evdi-1.9.0+dfsg/module/evdi_sysfs.c 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/evdi_sysfs.c 2022-07-13 09:58:06.000000000 -0400 @@ -28,6 +28,8 @@ #include "evdi_debug.h" #include "evdi_platform_drv.h" +#define MAX_EVDI_USB_ADDR 10 + static ssize_t version_show(__always_unused struct device *dev, __always_unused struct device_attribute *attr, char *buf) @@ -44,7 +46,6 @@ } struct evdi_usb_addr { - #define MAX_EVDI_USB_ADDR 10 int addr[MAX_EVDI_USB_ADDR]; int len; struct usb_device *usb; @@ -58,15 +59,17 @@ { char *usb_path = kstrdup(buf, GFP_KERNEL); char *temp_path = usb_path; - char *bus_token = NULL; - char *usb_token = NULL; + char *bus_token; + char *usb_token; char *usb_token_copy = NULL; - char *itf_token = NULL; - char *token = NULL; - char *bus = NULL; - char *port = NULL; + char *token; + char *bus; + char *port; struct evdi_usb_addr usb_addr; + if (!usb_path) + return -ENOMEM; + memset(&usb_addr, 0, sizeof(usb_addr)); temp_path = strnstr(temp_path, "usb:", count); if (!temp_path) @@ -83,7 +86,8 @@ if (!usb_token) goto err_parse_usb_path; - itf_token = strsep(&temp_path, ":"); + /* Separate trailing ':*' from usb_token */ + strsep(&temp_path, ":"); token = usb_token_copy = kstrdup(usb_token, GFP_KERNEL); bus = strsep(&token, "-"); @@ -231,7 +235,7 @@ void evdi_sysfs_init(struct device *root) { - int i; + unsigned int i; if (!PTR_ERR_OR_ZERO(root)) for (i = 0; i < ARRAY_SIZE(evdi_device_attributes); i++) @@ -240,7 +244,7 @@ void evdi_sysfs_exit(struct device *root) { - int i; + unsigned int i; if (PTR_ERR_OR_ZERO(root)) { EVDI_ERROR("root device is null"); diff -Nru evdi-1.9.0+dfsg/module/Kconfig evdi-1.12.0+dfsg/module/Kconfig --- evdi-1.9.0+dfsg/module/Kconfig 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/Kconfig 2022-07-13 09:58:06.000000000 -0400 @@ -9,6 +9,9 @@ config DRM_EVDI tristate "Extensible Virtual Display Interface" depends on DRM + depends on USB_SUPPORT + depends on USB_ARCH_HAS_HCD + select USB select DRM_KMS_HELPER help This is a KMS interface driver allowing user-space programs to diff -Nru evdi-1.9.0+dfsg/module/Makefile evdi-1.12.0+dfsg/module/Makefile --- evdi-1.9.0+dfsg/module/Makefile 2021-01-26 09:31:59.000000000 -0500 +++ evdi-1.12.0+dfsg/module/Makefile 2022-07-13 09:58:06.000000000 -0400 @@ -11,13 +11,18 @@ EL8FLAG := -DEL8 endif +Raspbian := $(shell grep -Eic 'raspb(erry|ian)' /proc/cpuinfo /etc/os-release 2>/dev/null ) +ifeq (,$(findstring 0, $(Raspbian))) +RPIFLAG := -DRPI +endif + ifneq ($(DKMS_BUILD),) # DKMS KERN_DIR := /lib/modules/$(KERNELRELEASE)/build -ccflags-y := -Iinclude/drm $(EL8FLAG) +ccflags-y := -Iinclude/drm $(EL8FLAG) $(RPIFLAG) 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 @@ -40,8 +45,7 @@ # inside kbuild # Note: this can be removed once it is in kernel tree and Kconfig is properly used CONFIG_DRM_EVDI := m -LINUXINCLUDE := $(subst -I,-isystem,$(LINUXINCLUDE)) -ccflags-y := -isystem include/drm $(CFLAGS) $(EL8FLAG) +ccflags-y := -isystem include/drm $(CFLAGS) $(EL8FLAG) $(RPIFLAG) 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-$(CONFIG_DRM_EVDI) := evdi.o @@ -53,7 +57,7 @@ DKMS ?= dkms RM ?= rm -MODVER=1.9.0 +MODVER=1.12.0 ifeq ($(KVER),) KVER := $(shell uname -r)