diff options
Diffstat (limited to 'drivers/gpu/drm/udl/udl_drv.c')
-rw-r--r-- | drivers/gpu/drm/udl/udl_drv.c | 102 |
1 files changed, 62 insertions, 40 deletions
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 3ddd6cd98ac1..8607e9e513db 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c | |||
@@ -7,48 +7,13 @@ | |||
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <drm/drm_usb.h> | 10 | #include <drm/drmP.h> |
11 | #include <drm/drm_crtc_helper.h> | 11 | #include <drm/drm_crtc_helper.h> |
12 | #include "udl_drv.h" | 12 | #include "udl_drv.h" |
13 | 13 | ||
14 | static struct drm_driver driver; | 14 | static int udl_driver_set_busid(struct drm_device *d, struct drm_master *m) |
15 | |||
16 | /* | ||
17 | * There are many DisplayLink-based graphics products, all with unique PIDs. | ||
18 | * So we match on DisplayLink's VID + Vendor-Defined Interface Class (0xff) | ||
19 | * We also require a match on SubClass (0x00) and Protocol (0x00), | ||
20 | * which is compatible with all known USB 2.0 era graphics chips and firmware, | ||
21 | * but allows DisplayLink to increment those for any future incompatible chips | ||
22 | */ | ||
23 | static struct usb_device_id id_table[] = { | ||
24 | {.idVendor = 0x17e9, .bInterfaceClass = 0xff, | ||
25 | .bInterfaceSubClass = 0x00, | ||
26 | .bInterfaceProtocol = 0x00, | ||
27 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | | ||
28 | USB_DEVICE_ID_MATCH_INT_CLASS | | ||
29 | USB_DEVICE_ID_MATCH_INT_SUBCLASS | | ||
30 | USB_DEVICE_ID_MATCH_INT_PROTOCOL,}, | ||
31 | {}, | ||
32 | }; | ||
33 | MODULE_DEVICE_TABLE(usb, id_table); | ||
34 | |||
35 | MODULE_LICENSE("GPL"); | ||
36 | |||
37 | static int udl_usb_probe(struct usb_interface *interface, | ||
38 | const struct usb_device_id *id) | ||
39 | { | 15 | { |
40 | return drm_get_usb_dev(interface, id, &driver); | 16 | return 0; |
41 | } | ||
42 | |||
43 | static void udl_usb_disconnect(struct usb_interface *interface) | ||
44 | { | ||
45 | struct drm_device *dev = usb_get_intfdata(interface); | ||
46 | |||
47 | drm_kms_helper_poll_disable(dev); | ||
48 | drm_connector_unplug_all(dev); | ||
49 | udl_fbdev_unplug(dev); | ||
50 | udl_drop_usb(dev); | ||
51 | drm_unplug_dev(dev); | ||
52 | } | 17 | } |
53 | 18 | ||
54 | static const struct vm_operations_struct udl_gem_vm_ops = { | 19 | static const struct vm_operations_struct udl_gem_vm_ops = { |
@@ -75,6 +40,7 @@ static struct drm_driver driver = { | |||
75 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, | 40 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, |
76 | .load = udl_driver_load, | 41 | .load = udl_driver_load, |
77 | .unload = udl_driver_unload, | 42 | .unload = udl_driver_unload, |
43 | .set_busid = udl_driver_set_busid, | ||
78 | 44 | ||
79 | /* gem hooks */ | 45 | /* gem hooks */ |
80 | .gem_free_object = udl_gem_free_object, | 46 | .gem_free_object = udl_gem_free_object, |
@@ -96,6 +62,61 @@ static struct drm_driver driver = { | |||
96 | .patchlevel = DRIVER_PATCHLEVEL, | 62 | .patchlevel = DRIVER_PATCHLEVEL, |
97 | }; | 63 | }; |
98 | 64 | ||
65 | static int udl_usb_probe(struct usb_interface *interface, | ||
66 | const struct usb_device_id *id) | ||
67 | { | ||
68 | struct usb_device *udev = interface_to_usbdev(interface); | ||
69 | struct drm_device *dev; | ||
70 | int r; | ||
71 | |||
72 | dev = drm_dev_alloc(&driver, &interface->dev); | ||
73 | if (!dev) | ||
74 | return -ENOMEM; | ||
75 | |||
76 | r = drm_dev_register(dev, (unsigned long)udev); | ||
77 | if (r) | ||
78 | goto err_free; | ||
79 | |||
80 | usb_set_intfdata(interface, dev); | ||
81 | DRM_INFO("Initialized udl on minor %d\n", dev->primary->index); | ||
82 | |||
83 | return 0; | ||
84 | |||
85 | err_free: | ||
86 | drm_dev_unref(dev); | ||
87 | return r; | ||
88 | } | ||
89 | |||
90 | static void udl_usb_disconnect(struct usb_interface *interface) | ||
91 | { | ||
92 | struct drm_device *dev = usb_get_intfdata(interface); | ||
93 | |||
94 | drm_kms_helper_poll_disable(dev); | ||
95 | drm_connector_unplug_all(dev); | ||
96 | udl_fbdev_unplug(dev); | ||
97 | udl_drop_usb(dev); | ||
98 | drm_unplug_dev(dev); | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * There are many DisplayLink-based graphics products, all with unique PIDs. | ||
103 | * So we match on DisplayLink's VID + Vendor-Defined Interface Class (0xff) | ||
104 | * We also require a match on SubClass (0x00) and Protocol (0x00), | ||
105 | * which is compatible with all known USB 2.0 era graphics chips and firmware, | ||
106 | * but allows DisplayLink to increment those for any future incompatible chips | ||
107 | */ | ||
108 | static struct usb_device_id id_table[] = { | ||
109 | {.idVendor = 0x17e9, .bInterfaceClass = 0xff, | ||
110 | .bInterfaceSubClass = 0x00, | ||
111 | .bInterfaceProtocol = 0x00, | ||
112 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | | ||
113 | USB_DEVICE_ID_MATCH_INT_CLASS | | ||
114 | USB_DEVICE_ID_MATCH_INT_SUBCLASS | | ||
115 | USB_DEVICE_ID_MATCH_INT_PROTOCOL,}, | ||
116 | {}, | ||
117 | }; | ||
118 | MODULE_DEVICE_TABLE(usb, id_table); | ||
119 | |||
99 | static struct usb_driver udl_driver = { | 120 | static struct usb_driver udl_driver = { |
100 | .name = "udl", | 121 | .name = "udl", |
101 | .probe = udl_usb_probe, | 122 | .probe = udl_usb_probe, |
@@ -105,13 +126,14 @@ static struct usb_driver udl_driver = { | |||
105 | 126 | ||
106 | static int __init udl_init(void) | 127 | static int __init udl_init(void) |
107 | { | 128 | { |
108 | return drm_usb_init(&driver, &udl_driver); | 129 | return usb_register(&udl_driver); |
109 | } | 130 | } |
110 | 131 | ||
111 | static void __exit udl_exit(void) | 132 | static void __exit udl_exit(void) |
112 | { | 133 | { |
113 | drm_usb_exit(&driver, &udl_driver); | 134 | usb_deregister(&udl_driver); |
114 | } | 135 | } |
115 | 136 | ||
116 | module_init(udl_init); | 137 | module_init(udl_init); |
117 | module_exit(udl_exit); | 138 | module_exit(udl_exit); |
139 | MODULE_LICENSE("GPL"); | ||