forked from Minki/linux
76bba2cdb5
Since
commit ca8e2ad710
Author: Thierry Reding <treding@nvidia.com>
Date: Fri Apr 11 15:23:00 2014 +0200
drm: Introduce drm_dev_set_unique()
the ->set_busid callback is optional. On top of that the udl one isn't
really fully compliant with the drm uabi, but since only modesetting
ever binds to it (there's no 3d accel on udl) it doesn't matter.
Still, can't harm to aling and use the default used by everyone else.
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170524145212.27837-4-daniel.vetter@ffwll.ch
137 lines
3.4 KiB
C
137 lines
3.4 KiB
C
/*
|
|
* 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 <linux/module.h>
|
|
#include <drm/drmP.h>
|
|
#include <drm/drm_crtc_helper.h>
|
|
#include "udl_drv.h"
|
|
|
|
static int udl_usb_suspend(struct usb_interface *interface,
|
|
pm_message_t message)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int udl_usb_resume(struct usb_interface *interface)
|
|
{
|
|
struct drm_device *dev = usb_get_intfdata(interface);
|
|
|
|
udl_modeset_restore(dev);
|
|
return 0;
|
|
}
|
|
|
|
static const 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 = udl_drm_gem_mmap,
|
|
.poll = drm_poll,
|
|
.read = drm_read,
|
|
.unlocked_ioctl = drm_ioctl,
|
|
.release = drm_release,
|
|
.compat_ioctl = drm_compat_ioctl,
|
|
.llseek = noop_llseek,
|
|
};
|
|
|
|
static struct drm_driver driver = {
|
|
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
|
|
.load = udl_driver_load,
|
|
.unload = udl_driver_unload,
|
|
|
|
/* gem hooks */
|
|
.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 = drm_gem_dumb_destroy,
|
|
.fops = &udl_driver_fops,
|
|
|
|
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
|
|
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
|
|
.gem_prime_export = udl_gem_prime_export,
|
|
.gem_prime_import = udl_gem_prime_import,
|
|
|
|
.name = DRIVER_NAME,
|
|
.desc = DRIVER_DESC,
|
|
.date = DRIVER_DATE,
|
|
.major = DRIVER_MAJOR,
|
|
.minor = DRIVER_MINOR,
|
|
.patchlevel = DRIVER_PATCHLEVEL,
|
|
};
|
|
|
|
static int udl_usb_probe(struct usb_interface *interface,
|
|
const struct usb_device_id *id)
|
|
{
|
|
struct usb_device *udev = interface_to_usbdev(interface);
|
|
struct drm_device *dev;
|
|
int r;
|
|
|
|
dev = drm_dev_alloc(&driver, &interface->dev);
|
|
if (IS_ERR(dev))
|
|
return PTR_ERR(dev);
|
|
|
|
r = drm_dev_register(dev, (unsigned long)udev);
|
|
if (r)
|
|
goto err_free;
|
|
|
|
usb_set_intfdata(interface, dev);
|
|
DRM_INFO("Initialized udl on minor %d\n", dev->primary->index);
|
|
|
|
return 0;
|
|
|
|
err_free:
|
|
drm_dev_unref(dev);
|
|
return r;
|
|
}
|
|
|
|
static void udl_usb_disconnect(struct usb_interface *interface)
|
|
{
|
|
struct drm_device *dev = usb_get_intfdata(interface);
|
|
|
|
drm_kms_helper_poll_disable(dev);
|
|
udl_fbdev_unplug(dev);
|
|
udl_drop_usb(dev);
|
|
drm_unplug_dev(dev);
|
|
}
|
|
|
|
/*
|
|
* There are many DisplayLink-based graphics products, all with unique PIDs.
|
|
* So we match on DisplayLink's VID + Vendor-Defined Interface Class (0xff)
|
|
* We also require a match on SubClass (0x00) and Protocol (0x00),
|
|
* which is compatible with all known USB 2.0 era graphics chips and firmware,
|
|
* but allows DisplayLink to increment those for any future incompatible chips
|
|
*/
|
|
static struct usb_device_id id_table[] = {
|
|
{.idVendor = 0x17e9, .bInterfaceClass = 0xff,
|
|
.bInterfaceSubClass = 0x00,
|
|
.bInterfaceProtocol = 0x00,
|
|
.match_flags = USB_DEVICE_ID_MATCH_VENDOR |
|
|
USB_DEVICE_ID_MATCH_INT_CLASS |
|
|
USB_DEVICE_ID_MATCH_INT_SUBCLASS |
|
|
USB_DEVICE_ID_MATCH_INT_PROTOCOL,},
|
|
{},
|
|
};
|
|
MODULE_DEVICE_TABLE(usb, id_table);
|
|
|
|
static struct usb_driver udl_driver = {
|
|
.name = "udl",
|
|
.probe = udl_usb_probe,
|
|
.disconnect = udl_usb_disconnect,
|
|
.suspend = udl_usb_suspend,
|
|
.resume = udl_usb_resume,
|
|
.id_table = id_table,
|
|
};
|
|
module_usb_driver(udl_driver);
|
|
MODULE_LICENSE("GPL");
|