aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fbmem.c
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2012-01-28 14:57:46 -0500
committerDave Airlie <airlied@redhat.com>2012-03-15 09:35:22 -0400
commitce880cb860f36694d2cdebfac9e6ae18176fe4c4 (patch)
tree6fa674bd935d7f4c48dec243970c6b0b92f0c0a7 /drivers/video/fbmem.c
parent8229c885fe361e521ac64de36b16011e54a30de0 (diff)
udlfb: remove sysfs framebuffer device with USB .disconnect()
The USB graphics card driver delays the unregistering of the framebuffer device to a workqueue, which breaks the userspace visible remove uevent sequence. Recent userspace tools started to support USB graphics card hotplug out-of-the-box and rely on proper events sent by the kernel. The framebuffer device is a direct child of the USB interface which is removed immediately after the USB .disconnect() callback. But the fb device in /sys stays around until its final cleanup, at a time where all the parent devices have been removed already. To work around that, we remove the sysfs fb device directly in the USB .disconnect() callback and leave only the cleanup of the internal fb data to the delayed work. Before: add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb0 (graphics) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) remove /2-1.2:1.0/graphics/fb0 (graphics) After: add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) Cc: stable@vger.kernel.org Tested-by: Bernie Thompson <bernie@plugable.com> Acked-by: Bernie Thompson <bernie@plugable.com> Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
Diffstat (limited to 'drivers/video/fbmem.c')
-rw-r--r--drivers/video/fbmem.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index ac9141b85356..c6ce416ab587 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1665,6 +1665,7 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
1665 if (ret) 1665 if (ret)
1666 return -EINVAL; 1666 return -EINVAL;
1667 1667
1668 unlink_framebuffer(fb_info);
1668 if (fb_info->pixmap.addr && 1669 if (fb_info->pixmap.addr &&
1669 (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) 1670 (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
1670 kfree(fb_info->pixmap.addr); 1671 kfree(fb_info->pixmap.addr);
@@ -1672,7 +1673,6 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
1672 registered_fb[i] = NULL; 1673 registered_fb[i] = NULL;
1673 num_registered_fb--; 1674 num_registered_fb--;
1674 fb_cleanup_device(fb_info); 1675 fb_cleanup_device(fb_info);
1675 device_destroy(fb_class, MKDEV(FB_MAJOR, i));
1676 event.info = fb_info; 1676 event.info = fb_info;
1677 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); 1677 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
1678 1678
@@ -1681,6 +1681,22 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
1681 return 0; 1681 return 0;
1682} 1682}
1683 1683
1684int unlink_framebuffer(struct fb_info *fb_info)
1685{
1686 int i;
1687
1688 i = fb_info->node;
1689 if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
1690 return -EINVAL;
1691
1692 if (fb_info->dev) {
1693 device_destroy(fb_class, MKDEV(FB_MAJOR, i));
1694 fb_info->dev = NULL;
1695 }
1696 return 0;
1697}
1698EXPORT_SYMBOL(unlink_framebuffer);
1699
1684void remove_conflicting_framebuffers(struct apertures_struct *a, 1700void remove_conflicting_framebuffers(struct apertures_struct *a,
1685 const char *name, bool primary) 1701 const char *name, bool primary)
1686{ 1702{