From b8584f4233dc11a328cd245a5843ec3d67462200 Mon Sep 17 00:00:00 2001 From: robert Date: Sat, 13 Jan 2018 13:03:42 +0000 Subject: [PATCH] add kqueue support to drm(4) by making the drm_sysfs_hotplug_event() available on OpenBSD well and by notifying listeners of a device state change using EVFILT_DEVICE and NOTE_CHANGE. drm_sysfs_hotplug_event() gets called when a state change of the device occured, like an hdmi cable has been plugged, this in the future will be used by the modesetting xorg driver to notify desktop environments via randr events to update their screen configuration ok kettenis@ --- sys/dev/pci/drm/drmP.h | 12 ++++----- sys/dev/pci/drm/drm_drv.c | 52 ++++++++++++++++++++++++++++++++++++- sys/dev/pci/drm/drm_linux.c | 9 ++++++- sys/sys/conf.h | 4 +-- 4 files changed, 67 insertions(+), 10 deletions(-) diff --git a/sys/dev/pci/drm/drmP.h b/sys/dev/pci/drm/drmP.h index f04240a6737..78e9f97bc26 100644 --- a/sys/dev/pci/drm/drmP.h +++ b/sys/dev/pci/drm/drmP.h @@ -1,4 +1,4 @@ -/* $OpenBSD: drmP.h,v 1.215 2017/07/22 14:33:45 kettenis Exp $ */ +/* $OpenBSD: drmP.h,v 1.216 2018/01/13 13:03:42 robert Exp $ */ /* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*- * Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com */ @@ -735,6 +735,8 @@ struct drm_device { struct drm_driver *driver; + struct klist note; + struct pci_dev _pdev; struct pci_dev *pdev; u_int16_t pci_device; @@ -1014,6 +1016,9 @@ int drm_agp_free_ioctl(struct drm_device *, void *, struct drm_file *); int drm_agp_unbind_ioctl(struct drm_device *, void *, struct drm_file *); int drm_agp_bind_ioctl(struct drm_device *, void *, struct drm_file *); +/* hotplug support */ +void drm_sysfs_hotplug_event(struct drm_device *); + static inline int drm_sysfs_connector_add(struct drm_connector *connector) { @@ -1025,11 +1030,6 @@ drm_sysfs_connector_remove(struct drm_connector *connector) { } -static inline void -drm_sysfs_hotplug_event(struct drm_device *dev) -{ -} - /* Graphics Execution Manager library functions (drm_gem.c) */ int drm_gem_init(struct drm_device *dev); void drm_gem_destroy(struct drm_device *dev); diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c index 523ccfe486b..065691abe85 100644 --- a/sys/dev/pci/drm/drm_drv.c +++ b/sys/dev/pci/drm/drm_drv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: drm_drv.c,v 1.154 2017/07/19 22:05:58 kettenis Exp $ */ +/* $OpenBSD: drm_drv.c,v 1.155 2018/01/13 13:03:42 robert Exp $ */ /*- * Copyright 2007-2009 Owain G. Ainsworth * Copyright © 2008 Intel Corporation @@ -50,6 +50,7 @@ #include #include /* for TIOCSGRP */ #include +#include #include #include @@ -633,6 +634,55 @@ drm_lastclose(struct drm_device *dev) return 0; } +void +filt_drmdetach(struct knote *kn) +{ + struct drm_device *dev = kn->kn_hook; + int s; + + s = spltty(); + SLIST_REMOVE(&dev->note, kn, knote, kn_selnext); + splx(s); +} + +int +filt_drmkms(struct knote *kn, long hint) +{ + if (kn->kn_sfflags & hint) + kn->kn_fflags |= hint; + return (kn->kn_fflags != 0); +} + +struct filterops drm_filtops = + { 1, NULL, filt_drmdetach, filt_drmkms }; + +int +drmkqfilter(dev_t kdev, struct knote *kn) +{ + struct drm_device *dev = NULL; + int s; + + dev = drm_get_device_from_kdev(kdev); + if (dev == NULL || dev->dev_private == NULL) + return (ENXIO); + + switch (kn->kn_filter) { + case EVFILT_DEVICE: + kn->kn_fop = &drm_filtops; + break; + default: + return (EINVAL); + } + + kn->kn_hook = dev; + + s = spltty(); + SLIST_INSERT_HEAD(&dev->note, kn, kn_selnext); + splx(s); + + return (0); +} + int drmopen(dev_t kdev, int flags, int fmt, struct proc *p) { diff --git a/sys/dev/pci/drm/drm_linux.c b/sys/dev/pci/drm/drm_linux.c index 4c4498bb58d..40141b85b98 100644 --- a/sys/dev/pci/drm/drm_linux.c +++ b/sys/dev/pci/drm/drm_linux.c @@ -1,4 +1,4 @@ -/* $OpenBSD: drm_linux.c,v 1.16 2018/01/12 11:03:15 jsg Exp $ */ +/* $OpenBSD: drm_linux.c,v 1.17 2018/01/13 13:03:42 robert Exp $ */ /* * Copyright (c) 2013 Jonathan Gray * Copyright (c) 2015, 2016 Mark Kettenis @@ -18,6 +18,7 @@ #include #include +#include void flush_barrier(void *arg) @@ -730,3 +731,9 @@ backlight_schedule_update_status(struct backlight_device *bd) { task_add(systq, &bd->task); } + +void +drm_sysfs_hotplug_event(struct drm_device *dev) +{ + KNOTE(&dev->note, NOTE_CHANGE); +} diff --git a/sys/sys/conf.h b/sys/sys/conf.h index 79c5f6c1da3..6967ffb5d45 100644 --- a/sys/sys/conf.h +++ b/sys/sys/conf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.h,v 1.143 2016/09/04 10:51:24 naddy Exp $ */ +/* $OpenBSD: conf.h,v 1.144 2018/01/13 13:03:42 robert Exp $ */ /* $NetBSD: conf.h,v 1.33 1996/05/03 20:03:32 christos Exp $ */ /*- @@ -444,7 +444,7 @@ extern struct cdevsw cdevsw[]; dev_init(c,n,open), dev_init(c,n,close), dev_init(c, n, read), \ (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \ (dev_type_stop((*))) enodev, 0, dev_init(c,n,poll), \ - dev_init(c,n,mmap), 0, D_CLONE } + dev_init(c,n,mmap), 0, D_CLONE, dev_init(c,n,kqfilter) } /* open, close, ioctl */ #define cdev_amdmsr_init(c,n) { \ -- 2.20.1