summaryrefslogtreecommitdiffstats
path: root/include/video
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2018-10-08 12:57:34 +0200
committerBartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>2018-10-08 12:57:34 +0200
commit68a958a915ca912b8ce71b9eea7445996f6e681e (patch)
tree23476581d14a94613b449d7536f71a9511d6638f /include/video
parentad4366ad4831f9a42d86f19c43a482c7cb04cecb (diff)
downloadlinux-68a958a915ca912b8ce71b9eea7445996f6e681e.tar.gz
linux-68a958a915ca912b8ce71b9eea7445996f6e681e.tar.bz2
linux-68a958a915ca912b8ce71b9eea7445996f6e681e.zip
udlfb: handle unplug properly
The udlfb driver maintained an open count and cleaned up itself when the count reached zero. But the console is also counted in the reference count - so, if the user unplugged the device, the open count would not drop to zero and the driver stayed loaded with console attached. If the user re-plugged the adapter, it would create a device /dev/fb1, show green screen and the access to the console would be lost. The framebuffer subsystem has reference counting on its own - in order to fix the unplug bug, we rely the framebuffer reference counting. When the user unplugs the adapter, we call unregister_framebuffer unconditionally. unregister_framebuffer will unbind the console, wait until all users stop using the framebuffer and then call the fb_destroy method. The fb_destroy cleans up the USB driver. This patch makes the following changes: * Drop dlfb->kref and rely on implicit framebuffer reference counting instead. * dlfb_usb_disconnect calls unregister_framebuffer, the rest of driver cleanup is done in the function dlfb_ops_destroy. dlfb_ops_destroy will be called by the framebuffer subsystem when no processes have the framebuffer open or mapped. * We don't use workqueue during initialization, but initialize directly from dlfb_usb_probe. The workqueue could race with dlfb_usb_disconnect and this racing would produce various kinds of memory corruption. * We use usb_get_dev and usb_put_dev to make sure that the USB subsystem doesn't free the device under us. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> cc: Dave Airlie <airlied@redhat.com> Cc: Bernie Thompson <bernie@plugable.com>, Cc: Ladislav Michl <ladis@linux-mips.org> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Diffstat (limited to 'include/video')
-rw-r--r--include/video/udlfb.h3
1 files changed, 0 insertions, 3 deletions
diff --git a/include/video/udlfb.h b/include/video/udlfb.h
index 3abd327bada6..7d09e54ae54e 100644
--- a/include/video/udlfb.h
+++ b/include/video/udlfb.h
@@ -36,12 +36,9 @@ struct dlfb_data {
struct usb_device *udev;
struct fb_info *info;
struct urb_list urbs;
- struct kref kref;
char *backing_buffer;
int fb_count;
bool virtualized; /* true when physical usb device not present */
- struct delayed_work init_framebuffer_work;
- struct delayed_work free_framebuffer_work;
atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */
atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */
char *edid; /* null until we read edid from hw or get from sysfs */