From 5320918b9a87865223fd6b228e530bf30bc64d9d Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 15 Dec 2010 07:14:24 +1000 Subject: drm/udl: initial UDL driver (v4) This is an initial drm/kms driver for the displaylink devices. Supports fb_defio, supports KMS dumb interface supports 24bpp via conversion to 16bpp, hw can do this better. supports hot unplug using new drm core features. On an unplug, it disables connector polling, unplugs connectors from sysfs, unplugs fbdev layer (using Kay's API), drops all the USB device URBs, and call the drm core to unplug the device. This driver is based in large parts on udlfb.c so I've licensed it under GPLv2. Signed-off-by: Dave Airlie --- drivers/gpu/drm/udl/udl_drv.c | 99 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 drivers/gpu/drm/udl/udl_drv.c (limited to 'drivers/gpu/drm/udl/udl_drv.c') diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c new file mode 100644 index 000000000000..5340c5f3987b --- /dev/null +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2012 Red Hat + * + * This file is subject to the terms and conditions of the GNU General Public + * License v2. See the file COPYING in the main directory of this archive for + * more details. + */ + +#include +#include "drm_usb.h" +#include "drm_crtc_helper.h" +#include "udl_drv.h" + +static struct drm_driver driver; + +static struct usb_device_id id_table[] = { + {.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,}, + {}, +}; +MODULE_DEVICE_TABLE(usb, id_table); + +MODULE_LICENSE("GPL"); + +static int udl_usb_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + return drm_get_usb_dev(interface, id, &driver); +} + +static void udl_usb_disconnect(struct usb_interface *interface) +{ + struct drm_device *dev = usb_get_intfdata(interface); + + drm_kms_helper_poll_disable(dev); + drm_connector_unplug_all(dev); + udl_fbdev_unplug(dev); + udl_drop_usb(dev); + drm_unplug_dev(dev); +} + +static struct vm_operations_struct udl_gem_vm_ops = { + .fault = udl_gem_fault, + .open = drm_gem_vm_open, + .close = drm_gem_vm_close, +}; + +static const struct file_operations udl_driver_fops = { + .owner = THIS_MODULE, + .open = drm_open, + .mmap = drm_gem_mmap, + .poll = drm_poll, + .read = drm_read, + .unlocked_ioctl = drm_ioctl, + .release = drm_release, + .fasync = drm_fasync, + .llseek = noop_llseek, +}; + +static struct drm_driver driver = { + .driver_features = DRIVER_MODESET | DRIVER_GEM, + .load = udl_driver_load, + .unload = udl_driver_unload, + + /* gem hooks */ + .gem_init_object = udl_gem_init_object, + .gem_free_object = udl_gem_free_object, + .gem_vm_ops = &udl_gem_vm_ops, + + .dumb_create = udl_dumb_create, + .dumb_map_offset = udl_gem_mmap, + .dumb_destroy = udl_dumb_destroy, + .fops = &udl_driver_fops, + .name = DRIVER_NAME, + .desc = DRIVER_DESC, + .date = DRIVER_DATE, + .major = DRIVER_MAJOR, + .minor = DRIVER_MINOR, + .patchlevel = DRIVER_PATCHLEVEL, +}; + +static struct usb_driver udl_driver = { + .name = "udl", + .probe = udl_usb_probe, + .disconnect = udl_usb_disconnect, + .id_table = id_table, +}; + +static int __init udl_init(void) +{ + return drm_usb_init(&driver, &udl_driver); +} + +static void __exit udl_exit(void) +{ + drm_usb_exit(&driver, &udl_driver); +} + +module_init(udl_init); +module_exit(udl_exit); -- cgit v1.2.3 From fa9e855025b19e96e493ee00de7d933a9794f742 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Sat, 31 Mar 2012 13:29:25 +0400 Subject: mm, drm/udl: fixup vma flags on mmap There should be VM_MIXEDMAP, not VM_PFNMAP, because udl_gem_fault() inserts pages via vm_insert_page(). Other drm/gem drivers already do this. Signed-off-by: Konstantin Khlebnikov Cc: Dave Airlie Cc: dri-devel@lists.freedesktop.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/udl/udl_drv.c | 2 +- drivers/gpu/drm/udl/udl_drv.h | 1 + drivers/gpu/drm/udl/udl_gem.c | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/udl/udl_drv.c') diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 5340c5f3987b..53673907a6a0 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -47,7 +47,7 @@ static struct vm_operations_struct udl_gem_vm_ops = { static const struct file_operations udl_driver_fops = { .owner = THIS_MODULE, .open = drm_open, - .mmap = drm_gem_mmap, + .mmap = udl_drm_gem_mmap, .poll = drm_poll, .read = drm_read, .unlocked_ioctl = drm_ioctl, diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 1612954a5bc4..96820d03a303 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -121,6 +121,7 @@ struct udl_gem_object *udl_gem_alloc_object(struct drm_device *dev, int udl_gem_vmap(struct udl_gem_object *obj); void udl_gem_vunmap(struct udl_gem_object *obj); +int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); int udl_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int udl_handle_damage(struct udl_framebuffer *fb, int x, int y, diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index 852642dc1187..92f19ef329b0 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -71,6 +71,20 @@ int udl_dumb_destroy(struct drm_file *file, struct drm_device *dev, return drm_gem_handle_delete(file, handle); } +int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) +{ + int ret; + + ret = drm_gem_mmap(filp, vma); + if (ret) + return ret; + + vma->vm_flags &= ~VM_PFNMAP; + vma->vm_flags |= VM_MIXEDMAP; + + return ret; +} + int udl_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct udl_gem_object *obj = to_udl_bo(vma->vm_private_data); -- cgit v1.2.3