aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/udlfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/udlfb.c')
-rw-r--r--drivers/video/udlfb.c178
1 files changed, 102 insertions, 76 deletions
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index a40c05ebbdc2..a159b63e18b9 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -72,6 +72,7 @@ MODULE_DEVICE_TABLE(usb, id_table);
72static bool console = 1; /* Allow fbcon to open framebuffer */ 72static bool console = 1; /* Allow fbcon to open framebuffer */
73static bool fb_defio = 1; /* Detect mmap writes using page faults */ 73static bool fb_defio = 1; /* Detect mmap writes using page faults */
74static bool shadow = 1; /* Optionally disable shadow framebuffer */ 74static bool shadow = 1; /* Optionally disable shadow framebuffer */
75static int pixel_limit; /* Optionally force a pixel resolution limit */
75 76
76/* dlfb keeps a list of urbs for efficient bulk transfers */ 77/* dlfb keeps a list of urbs for efficient bulk transfers */
77static void dlfb_urb_completion(struct urb *urb); 78static void dlfb_urb_completion(struct urb *urb);
@@ -918,10 +919,6 @@ static void dlfb_free(struct kref *kref)
918{ 919{
919 struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref); 920 struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref);
920 921
921 /* this function will wait for all in-flight urbs to complete */
922 if (dev->urbs.count > 0)
923 dlfb_free_urb_list(dev);
924
925 if (dev->backing_buffer) 922 if (dev->backing_buffer)
926 vfree(dev->backing_buffer); 923 vfree(dev->backing_buffer);
927 924
@@ -940,35 +937,42 @@ static void dlfb_release_urb_work(struct work_struct *work)
940 up(&unode->dev->urbs.limit_sem); 937 up(&unode->dev->urbs.limit_sem);
941} 938}
942 939
943static void dlfb_free_framebuffer_work(struct work_struct *work) 940static void dlfb_free_framebuffer(struct dlfb_data *dev)
944{ 941{
945 struct dlfb_data *dev = container_of(work, struct dlfb_data,
946 free_framebuffer_work.work);
947 struct fb_info *info = dev->info; 942 struct fb_info *info = dev->info;
948 int node = info->node;
949 943
950 unregister_framebuffer(info); 944 if (info) {
945 int node = info->node;
951 946
952 if (info->cmap.len != 0) 947 unregister_framebuffer(info);
953 fb_dealloc_cmap(&info->cmap);
954 if (info->monspecs.modedb)
955 fb_destroy_modedb(info->monspecs.modedb);
956 if (info->screen_base)
957 vfree(info->screen_base);
958 948
959 fb_destroy_modelist(&info->modelist); 949 if (info->cmap.len != 0)
950 fb_dealloc_cmap(&info->cmap);
951 if (info->monspecs.modedb)
952 fb_destroy_modedb(info->monspecs.modedb);
953 if (info->screen_base)
954 vfree(info->screen_base);
960 955
961 dev->info = 0; 956 fb_destroy_modelist(&info->modelist);
962 957
963 /* Assume info structure is freed after this point */ 958 dev->info = NULL;
964 framebuffer_release(info);
965 959
966 pr_warn("fb_info for /dev/fb%d has been freed\n", node); 960 /* Assume info structure is freed after this point */
961 framebuffer_release(info);
962
963 pr_warn("fb_info for /dev/fb%d has been freed\n", node);
964 }
967 965
968 /* ref taken in probe() as part of registering framebfufer */ 966 /* ref taken in probe() as part of registering framebfufer */
969 kref_put(&dev->kref, dlfb_free); 967 kref_put(&dev->kref, dlfb_free);
970} 968}
971 969
970static void dlfb_free_framebuffer_work(struct work_struct *work)
971{
972 struct dlfb_data *dev = container_of(work, struct dlfb_data,
973 free_framebuffer_work.work);
974 dlfb_free_framebuffer(dev);
975}
972/* 976/*
973 * Assumes caller is holding info->lock mutex (for open and release at least) 977 * Assumes caller is holding info->lock mutex (for open and release at least)
974 */ 978 */
@@ -1012,7 +1016,8 @@ static int dlfb_is_valid_mode(struct fb_videomode *mode,
1012 return 0; 1016 return 0;
1013 } 1017 }
1014 1018
1015 pr_info("%dx%d valid mode\n", mode->xres, mode->yres); 1019 pr_info("%dx%d @ %d Hz valid mode\n", mode->xres, mode->yres,
1020 mode->refresh);
1016 1021
1017 return 1; 1022 return 1;
1018} 1023}
@@ -1427,19 +1432,22 @@ static ssize_t edid_store(
1427 struct device *fbdev = container_of(kobj, struct device, kobj); 1432 struct device *fbdev = container_of(kobj, struct device, kobj);
1428 struct fb_info *fb_info = dev_get_drvdata(fbdev); 1433 struct fb_info *fb_info = dev_get_drvdata(fbdev);
1429 struct dlfb_data *dev = fb_info->par; 1434 struct dlfb_data *dev = fb_info->par;
1435 int ret;
1430 1436
1431 /* We only support write of entire EDID at once, no offset*/ 1437 /* We only support write of entire EDID at once, no offset*/
1432 if ((src_size != EDID_LENGTH) || (src_off != 0)) 1438 if ((src_size != EDID_LENGTH) || (src_off != 0))
1433 return 0; 1439 return -EINVAL;
1434 1440
1435 dlfb_setup_modes(dev, fb_info, src, src_size); 1441 ret = dlfb_setup_modes(dev, fb_info, src, src_size);
1442 if (ret)
1443 return ret;
1436 1444
1437 if (dev->edid && (memcmp(src, dev->edid, src_size) == 0)) { 1445 if (!dev->edid || memcmp(src, dev->edid, src_size))
1438 pr_info("sysfs written EDID is new default\n"); 1446 return -EINVAL;
1439 dlfb_ops_set_par(fb_info); 1447
1440 return src_size; 1448 pr_info("sysfs written EDID is new default\n");
1441 } else 1449 dlfb_ops_set_par(fb_info);
1442 return 0; 1450 return src_size;
1443} 1451}
1444 1452
1445static ssize_t metrics_reset_store(struct device *fbdev, 1453static ssize_t metrics_reset_store(struct device *fbdev,
@@ -1537,7 +1545,7 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dev,
1537 u8 length; 1545 u8 length;
1538 u16 key; 1546 u16 key;
1539 1547
1540 key = *((u16 *) desc); 1548 key = le16_to_cpu(*((u16 *) desc));
1541 desc += sizeof(u16); 1549 desc += sizeof(u16);
1542 length = *desc; 1550 length = *desc;
1543 desc++; 1551 desc++;
@@ -1570,14 +1578,15 @@ success:
1570 kfree(buf); 1578 kfree(buf);
1571 return true; 1579 return true;
1572} 1580}
1581
1582static void dlfb_init_framebuffer_work(struct work_struct *work);
1583
1573static int dlfb_usb_probe(struct usb_interface *interface, 1584static int dlfb_usb_probe(struct usb_interface *interface,
1574 const struct usb_device_id *id) 1585 const struct usb_device_id *id)
1575{ 1586{
1576 struct usb_device *usbdev; 1587 struct usb_device *usbdev;
1577 struct dlfb_data *dev = 0; 1588 struct dlfb_data *dev = 0;
1578 struct fb_info *info = 0;
1579 int retval = -ENOMEM; 1589 int retval = -ENOMEM;
1580 int i;
1581 1590
1582 /* usb initialization */ 1591 /* usb initialization */
1583 1592
@@ -1589,9 +1598,7 @@ static int dlfb_usb_probe(struct usb_interface *interface,
1589 goto error; 1598 goto error;
1590 } 1599 }
1591 1600
1592 /* we need to wait for both usb and fbdev to spin down on disconnect */
1593 kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */ 1601 kref_init(&dev->kref); /* matching kref_put in usb .disconnect fn */
1594 kref_get(&dev->kref); /* matching kref_put in free_framebuffer_work */
1595 1602
1596 dev->udev = usbdev; 1603 dev->udev = usbdev;
1597 dev->gdev = &usbdev->dev; /* our generic struct device * */ 1604 dev->gdev = &usbdev->dev; /* our generic struct device * */
@@ -1613,16 +1620,53 @@ static int dlfb_usb_probe(struct usb_interface *interface,
1613 goto error; 1620 goto error;
1614 } 1621 }
1615 1622
1623 if (pixel_limit) {
1624 pr_warn("DL chip limit of %d overriden"
1625 " by module param to %d\n",
1626 dev->sku_pixel_limit, pixel_limit);
1627 dev->sku_pixel_limit = pixel_limit;
1628 }
1629
1630
1616 if (!dlfb_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) { 1631 if (!dlfb_alloc_urb_list(dev, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
1617 retval = -ENOMEM; 1632 retval = -ENOMEM;
1618 pr_err("dlfb_alloc_urb_list failed\n"); 1633 pr_err("dlfb_alloc_urb_list failed\n");
1619 goto error; 1634 goto error;
1620 } 1635 }
1621 1636
1637 kref_get(&dev->kref); /* matching kref_put in free_framebuffer_work */
1638
1622 /* We don't register a new USB class. Our client interface is fbdev */ 1639 /* We don't register a new USB class. Our client interface is fbdev */
1623 1640
1641 /* Workitem keep things fast & simple during USB enumeration */
1642 INIT_DELAYED_WORK(&dev->init_framebuffer_work,
1643 dlfb_init_framebuffer_work);
1644 schedule_delayed_work(&dev->init_framebuffer_work, 0);
1645
1646 return 0;
1647
1648error:
1649 if (dev) {
1650
1651 kref_put(&dev->kref, dlfb_free); /* ref for framebuffer */
1652 kref_put(&dev->kref, dlfb_free); /* last ref from kref_init */
1653
1654 /* dev has been deallocated. Do not dereference */
1655 }
1656
1657 return retval;
1658}
1659
1660static void dlfb_init_framebuffer_work(struct work_struct *work)
1661{
1662 struct dlfb_data *dev = container_of(work, struct dlfb_data,
1663 init_framebuffer_work.work);
1664 struct fb_info *info;
1665 int retval;
1666 int i;
1667
1624 /* allocates framebuffer driver structure, not framebuffer memory */ 1668 /* allocates framebuffer driver structure, not framebuffer memory */
1625 info = framebuffer_alloc(0, &interface->dev); 1669 info = framebuffer_alloc(0, dev->gdev);
1626 if (!info) { 1670 if (!info) {
1627 retval = -ENOMEM; 1671 retval = -ENOMEM;
1628 pr_err("framebuffer_alloc failed\n"); 1672 pr_err("framebuffer_alloc failed\n");
@@ -1668,15 +1712,13 @@ static int dlfb_usb_probe(struct usb_interface *interface,
1668 for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) { 1712 for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) {
1669 retval = device_create_file(info->dev, &fb_device_attrs[i]); 1713 retval = device_create_file(info->dev, &fb_device_attrs[i]);
1670 if (retval) { 1714 if (retval) {
1671 pr_err("device_create_file failed %d\n", retval); 1715 pr_warn("device_create_file failed %d\n", retval);
1672 goto err_del_attrs;
1673 } 1716 }
1674 } 1717 }
1675 1718
1676 retval = device_create_bin_file(info->dev, &edid_attr); 1719 retval = device_create_bin_file(info->dev, &edid_attr);
1677 if (retval) { 1720 if (retval) {
1678 pr_err("device_create_bin_file failed %d\n", retval); 1721 pr_warn("device_create_bin_file failed %d\n", retval);
1679 goto err_del_attrs;
1680 } 1722 }
1681 1723
1682 pr_info("DisplayLink USB device /dev/fb%d attached. %dx%d resolution." 1724 pr_info("DisplayLink USB device /dev/fb%d attached. %dx%d resolution."
@@ -1684,38 +1726,10 @@ static int dlfb_usb_probe(struct usb_interface *interface,
1684 info->var.xres, info->var.yres, 1726 info->var.xres, info->var.yres,
1685 ((dev->backing_buffer) ? 1727 ((dev->backing_buffer) ?
1686 info->fix.smem_len * 2 : info->fix.smem_len) >> 10); 1728 info->fix.smem_len * 2 : info->fix.smem_len) >> 10);
1687 return 0; 1729 return;
1688
1689err_del_attrs:
1690 for (i -= 1; i >= 0; i--)
1691 device_remove_file(info->dev, &fb_device_attrs[i]);
1692 1730
1693error: 1731error:
1694 if (dev) { 1732 dlfb_free_framebuffer(dev);
1695
1696 if (info) {
1697 if (info->cmap.len != 0)
1698 fb_dealloc_cmap(&info->cmap);
1699 if (info->monspecs.modedb)
1700 fb_destroy_modedb(info->monspecs.modedb);
1701 if (info->screen_base)
1702 vfree(info->screen_base);
1703
1704 fb_destroy_modelist(&info->modelist);
1705
1706 framebuffer_release(info);
1707 }
1708
1709 if (dev->backing_buffer)
1710 vfree(dev->backing_buffer);
1711
1712 kref_put(&dev->kref, dlfb_free); /* ref for framebuffer */
1713 kref_put(&dev->kref, dlfb_free); /* last ref from kref_init */
1714
1715 /* dev has been deallocated. Do not dereference */
1716 }
1717
1718 return retval;
1719} 1733}
1720 1734
1721static void dlfb_usb_disconnect(struct usb_interface *interface) 1735static void dlfb_usb_disconnect(struct usb_interface *interface)
@@ -1735,12 +1749,20 @@ static void dlfb_usb_disconnect(struct usb_interface *interface)
1735 /* When non-active we'll update virtual framebuffer, but no new urbs */ 1749 /* When non-active we'll update virtual framebuffer, but no new urbs */
1736 atomic_set(&dev->usb_active, 0); 1750 atomic_set(&dev->usb_active, 0);
1737 1751
1738 /* remove udlfb's sysfs interfaces */ 1752 /* this function will wait for all in-flight urbs to complete */
1739 for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) 1753 dlfb_free_urb_list(dev);
1740 device_remove_file(info->dev, &fb_device_attrs[i]); 1754
1741 device_remove_bin_file(info->dev, &edid_attr); 1755 if (info) {
1742 unlink_framebuffer(info); 1756 /* remove udlfb's sysfs interfaces */
1757 for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
1758 device_remove_file(info->dev, &fb_device_attrs[i]);
1759 device_remove_bin_file(info->dev, &edid_attr);
1760 unlink_framebuffer(info);
1761 }
1762
1743 usb_set_intfdata(interface, NULL); 1763 usb_set_intfdata(interface, NULL);
1764 dev->udev = NULL;
1765 dev->gdev = NULL;
1744 1766
1745 /* if clients still have us open, will be freed on last close */ 1767 /* if clients still have us open, will be freed on last close */
1746 if (dev->fb_count == 0) 1768 if (dev->fb_count == 0)
@@ -1806,12 +1828,12 @@ static void dlfb_free_urb_list(struct dlfb_data *dev)
1806 int ret; 1828 int ret;
1807 unsigned long flags; 1829 unsigned long flags;
1808 1830
1809 pr_notice("Waiting for completes and freeing all render urbs\n"); 1831 pr_notice("Freeing all render urbs\n");
1810 1832
1811 /* keep waiting and freeing, until we've got 'em all */ 1833 /* keep waiting and freeing, until we've got 'em all */
1812 while (count--) { 1834 while (count--) {
1813 1835
1814 /* Getting interrupted means a leak, but ok at shutdown*/ 1836 /* Getting interrupted means a leak, but ok at disconnect */
1815 ret = down_interruptible(&dev->urbs.limit_sem); 1837 ret = down_interruptible(&dev->urbs.limit_sem);
1816 if (ret) 1838 if (ret)
1817 break; 1839 break;
@@ -1833,6 +1855,7 @@ static void dlfb_free_urb_list(struct dlfb_data *dev)
1833 kfree(node); 1855 kfree(node);
1834 } 1856 }
1835 1857
1858 dev->urbs.count = 0;
1836} 1859}
1837 1860
1838static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size) 1861static int dlfb_alloc_urb_list(struct dlfb_data *dev, int count, size_t size)
@@ -1948,6 +1971,9 @@ MODULE_PARM_DESC(fb_defio, "Page fault detection of mmap writes");
1948module_param(shadow, bool, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); 1971module_param(shadow, bool, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP);
1949MODULE_PARM_DESC(shadow, "Shadow vid mem. Disable to save mem but lose perf"); 1972MODULE_PARM_DESC(shadow, "Shadow vid mem. Disable to save mem but lose perf");
1950 1973
1974module_param(pixel_limit, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP);
1975MODULE_PARM_DESC(pixel_limit, "Force limit on max mode (in x*y pixels)");
1976
1951MODULE_AUTHOR("Roberto De Ioris <roberto@unbit.it>, " 1977MODULE_AUTHOR("Roberto De Ioris <roberto@unbit.it>, "
1952 "Jaya Kumar <jayakumar.lkml@gmail.com>, " 1978 "Jaya Kumar <jayakumar.lkml@gmail.com>, "
1953 "Bernie Thompson <bernie@plugable.com>"); 1979 "Bernie Thompson <bernie@plugable.com>");