diff options
author | Jiri Kosina <jkosina@suse.cz> | 2014-11-20 14:42:02 +0100 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2014-11-20 14:42:02 +0100 |
commit | a02001086bbfb4da35d1228bebc2f1b442db455f (patch) | |
tree | 62ab47936cef06fd08657ca5b6cd1df98c19be57 /drivers/gpu/drm/udl | |
parent | eff264efeeb0898408e8c9df72d8a32621035bed (diff) | |
parent | fc14f9c1272f62c3e8d01300f52467c0d9af50f9 (diff) |
Merge Linus' tree to be be to apply submitted patches to newer code than
current trivial.git base
Diffstat (limited to 'drivers/gpu/drm/udl')
-rw-r--r-- | drivers/gpu/drm/udl/Kconfig | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/udl/udl_connector.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/udl/udl_drv.c | 102 | ||||
-rw-r--r-- | drivers/gpu/drm/udl/udl_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/udl/udl_fb.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/udl/udl_gem.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/udl/udl_main.c | 23 | ||||
-rw-r--r-- | drivers/gpu/drm/udl/udl_modeset.c | 21 |
8 files changed, 121 insertions, 63 deletions
diff --git a/drivers/gpu/drm/udl/Kconfig b/drivers/gpu/drm/udl/Kconfig index f02528686cd..613ab0622d6 100644 --- a/drivers/gpu/drm/udl/Kconfig +++ b/drivers/gpu/drm/udl/Kconfig @@ -1,8 +1,9 @@ config DRM_UDL tristate "DisplayLink" depends on DRM + depends on USB_SUPPORT depends on USB_ARCH_HAS_HCD - select DRM_USB + select USB select FB_SYS_FILLRECT select FB_SYS_COPYAREA select FB_SYS_IMAGEBLIT diff --git a/drivers/gpu/drm/udl/udl_connector.c b/drivers/gpu/drm/udl/udl_connector.c index b44d548c56f..0110d95522f 100644 --- a/drivers/gpu/drm/udl/udl_connector.c +++ b/drivers/gpu/drm/udl/udl_connector.c @@ -34,8 +34,8 @@ static u8 *udl_get_edid(struct udl_device *udl) goto error; for (i = 0; i < EDID_LENGTH; i++) { - ret = usb_control_msg(udl->ddev->usbdev, - usb_rcvctrlpipe(udl->ddev->usbdev, 0), (0x02), + ret = usb_control_msg(udl->udev, + usb_rcvctrlpipe(udl->udev, 0), (0x02), (0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2, HZ); if (ret < 1) { @@ -105,14 +105,7 @@ static struct drm_encoder* udl_best_single_encoder(struct drm_connector *connector) { int enc_id = connector->encoder_ids[0]; - struct drm_mode_object *obj; - struct drm_encoder *encoder; - - obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER); - if (!obj) - return NULL; - encoder = obj_to_encoder(obj); - return encoder; + return drm_encoder_find(connector->dev, enc_id); } static int udl_connector_set_property(struct drm_connector *connector, @@ -124,7 +117,7 @@ static int udl_connector_set_property(struct drm_connector *connector, static void udl_connector_destroy(struct drm_connector *connector) { - drm_sysfs_connector_remove(connector); + drm_connector_unregister(connector); drm_connector_cleanup(connector); kfree(connector); } @@ -154,7 +147,7 @@ int udl_connector_init(struct drm_device *dev, struct drm_encoder *encoder) drm_connector_init(dev, connector, &udl_connector_funcs, DRM_MODE_CONNECTOR_DVII); drm_connector_helper_add(connector, &udl_connector_helper_funcs); - drm_sysfs_connector_add(connector); + drm_connector_register(connector); drm_mode_connector_attach_encoder(connector, encoder); drm_object_attach_property(&connector->base, diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 3ddd6cd98ac..8607e9e513d 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -7,48 +7,13 @@ */ #include <linux/module.h> -#include <drm/drm_usb.h> +#include <drm/drmP.h> #include <drm/drm_crtc_helper.h> #include "udl_drv.h" -static struct drm_driver driver; - -/* - * 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); - -MODULE_LICENSE("GPL"); - -static int udl_usb_probe(struct usb_interface *interface, - const struct usb_device_id *id) +static int udl_driver_set_busid(struct drm_device *d, struct drm_master *m) { - 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); + return 0; } static const struct vm_operations_struct udl_gem_vm_ops = { @@ -75,6 +40,7 @@ static struct drm_driver driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, .load = udl_driver_load, .unload = udl_driver_unload, + .set_busid = udl_driver_set_busid, /* gem hooks */ .gem_free_object = udl_gem_free_object, @@ -96,6 +62,61 @@ static struct drm_driver driver = { .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 (!dev) + return -ENOMEM; + + 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); + drm_connector_unplug_all(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, @@ -105,13 +126,14 @@ static struct usb_driver udl_driver = { static int __init udl_init(void) { - return drm_usb_init(&driver, &udl_driver); + return usb_register(&udl_driver); } static void __exit udl_exit(void) { - drm_usb_exit(&driver, &udl_driver); + usb_deregister(&udl_driver); } module_init(udl_init); module_exit(udl_exit); +MODULE_LICENSE("GPL"); diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h index 1fbf7b357f1..c7490a2489a 100644 --- a/drivers/gpu/drm/udl/udl_drv.h +++ b/drivers/gpu/drm/udl/udl_drv.h @@ -15,6 +15,7 @@ #define UDL_DRV_H #include <linux/usb.h> +#include <drm/drm_gem.h> #define DRIVER_NAME "udl" #define DRIVER_DESC "DisplayLink" @@ -47,6 +48,7 @@ struct udl_fbdev; struct udl_device { struct device *dev; struct drm_device *ddev; + struct usb_device *udev; int sku_pixel_limit; diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c index 377176372da..8cbcb4589bd 100644 --- a/drivers/gpu/drm/udl/udl_fb.c +++ b/drivers/gpu/drm/udl/udl_fb.c @@ -472,7 +472,8 @@ udl_framebuffer_init(struct drm_device *dev, static int udlfb_create(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { - struct udl_fbdev *ufbdev = (struct udl_fbdev *)helper; + struct udl_fbdev *ufbdev = + container_of(helper, struct udl_fbdev, helper); struct drm_device *dev = ufbdev->helper.dev; struct fb_info *info; struct device *device = dev->dev; @@ -550,7 +551,7 @@ out: return ret; } -static struct drm_fb_helper_funcs udl_fb_helper_funcs = { +static const struct drm_fb_helper_funcs udl_fb_helper_funcs = { .fb_probe = udlfb_create, }; @@ -583,7 +584,8 @@ int udl_fbdev_init(struct drm_device *dev) return -ENOMEM; udl->fbdev = ufbdev; - ufbdev->helper.funcs = &udl_fb_helper_funcs; + + drm_fb_helper_prepare(dev, &ufbdev->helper, &udl_fb_helper_funcs); ret = drm_fb_helper_init(dev, &ufbdev->helper, 1, 1); diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index c041cd73f39..8044f5fb7c4 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c @@ -107,14 +107,14 @@ int udl_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) } } -static int udl_gem_get_pages(struct udl_gem_object *obj, gfp_t gfpmask) +static int udl_gem_get_pages(struct udl_gem_object *obj) { struct page **pages; if (obj->pages) return 0; - pages = drm_gem_get_pages(&obj->base, gfpmask); + pages = drm_gem_get_pages(&obj->base); if (IS_ERR(pages)) return PTR_ERR(pages); @@ -147,7 +147,7 @@ int udl_gem_vmap(struct udl_gem_object *obj) return 0; } - ret = udl_gem_get_pages(obj, GFP_KERNEL); + ret = udl_gem_get_pages(obj); if (ret) return ret; @@ -205,7 +205,7 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev, } gobj = to_udl_bo(obj); - ret = udl_gem_get_pages(gobj, GFP_KERNEL); + ret = udl_gem_get_pages(gobj); if (ret) goto out; ret = drm_gem_create_mmap_offset(obj); diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index 7094b92d1ec..33dbfb2c474 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -202,7 +202,7 @@ static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size) } unode->urb = urb; - buf = usb_alloc_coherent(udl->ddev->usbdev, MAX_TRANSFER, GFP_KERNEL, + buf = usb_alloc_coherent(udl->udev, MAX_TRANSFER, GFP_KERNEL, &urb->transfer_dma); if (!buf) { kfree(unode); @@ -211,7 +211,7 @@ static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size) } /* urb->transfer_buffer_length set to actual before submit */ - usb_fill_bulk_urb(urb, udl->ddev->usbdev, usb_sndbulkpipe(udl->ddev->usbdev, 1), + usb_fill_bulk_urb(urb, udl->udev, usb_sndbulkpipe(udl->udev, 1), buf, size, udl_urb_completion, unode); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; @@ -282,6 +282,7 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len) int udl_driver_load(struct drm_device *dev, unsigned long flags) { + struct usb_device *udev = (void*)flags; struct udl_device *udl; int ret = -ENOMEM; @@ -290,10 +291,11 @@ int udl_driver_load(struct drm_device *dev, unsigned long flags) if (!udl) return -ENOMEM; + udl->udev = udev; udl->ddev = dev; dev->dev_private = udl; - if (!udl_parse_vendor_descriptor(dev, dev->usbdev)) { + if (!udl_parse_vendor_descriptor(dev, udl->udev)) { ret = -ENODEV; DRM_ERROR("firmware not recognized. Assume incompatible device\n"); goto err; @@ -306,10 +308,23 @@ int udl_driver_load(struct drm_device *dev, unsigned long flags) DRM_DEBUG("\n"); ret = udl_modeset_init(dev); + if (ret) + goto err; ret = udl_fbdev_init(dev); + if (ret) + goto err; + + ret = drm_vblank_init(dev, 1); + if (ret) + goto err_fb; + return 0; +err_fb: + udl_fbdev_cleanup(dev); err: + if (udl->urbs.count) + udl_free_urb_list(dev); kfree(udl); DRM_ERROR("%d\n", ret); return ret; @@ -325,6 +340,8 @@ int udl_driver_unload(struct drm_device *dev) { struct udl_device *udl = dev->dev_private; + drm_vblank_cleanup(dev); + if (udl->urbs.count) udl_free_urb_list(dev); diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c index cddc4fcf35c..dc145d320b2 100644 --- a/drivers/gpu/drm/udl/udl_modeset.c +++ b/drivers/gpu/drm/udl/udl_modeset.c @@ -363,6 +363,26 @@ static void udl_crtc_destroy(struct drm_crtc *crtc) kfree(crtc); } +static int udl_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event, + uint32_t page_flip_flags) +{ + struct udl_framebuffer *ufb = to_udl_fb(fb); + struct drm_device *dev = crtc->dev; + unsigned long flags; + + udl_handle_damage(ufb, 0, 0, fb->width, fb->height); + + spin_lock_irqsave(&dev->event_lock, flags); + if (event) + drm_send_vblank_event(dev, 0, event); + spin_unlock_irqrestore(&dev->event_lock, flags); + crtc->primary->fb = fb; + + return 0; +} + static void udl_crtc_prepare(struct drm_crtc *crtc) { } @@ -384,6 +404,7 @@ static struct drm_crtc_helper_funcs udl_helper_funcs = { static const struct drm_crtc_funcs udl_crtc_funcs = { .set_config = drm_crtc_helper_set_config, .destroy = udl_crtc_destroy, + .page_flip = udl_crtc_page_flip, }; static int udl_crtc_init(struct drm_device *dev) |