aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fbdev/udlfb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbdev/udlfb.c')
-rw-r--r--drivers/video/fbdev/udlfb.c231
1 files changed, 117 insertions, 114 deletions
diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c
index f0118c10b4ab..452a4207ac1b 100644
--- a/drivers/video/fbdev/udlfb.c
+++ b/drivers/video/fbdev/udlfb.c
@@ -16,8 +16,6 @@
* from Florian Echtler, Henrik Bjerregaard Pedersen, and others.
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -333,8 +331,8 @@ static int dlfb_ops_mmap(struct fb_info *info, struct vm_area_struct *vma)
pos = (unsigned long)info->fix.smem_start + offset;
- pr_notice("mmap() framebuffer addr:%lu size:%lu\n",
- pos, size);
+ dev_dbg(info->dev, "mmap() framebuffer addr:%lu size:%lu\n",
+ pos, size);
while (size > 0) {
page = vmalloc_to_pfn((void *)pos);
@@ -757,8 +755,7 @@ error:
static int dlfb_get_edid(struct dlfb_data *dlfb, char *edid, int len)
{
- int i;
- int ret;
+ int i, ret;
char *rbuf;
rbuf = kmalloc(2, GFP_KERNEL);
@@ -771,7 +768,8 @@ static int dlfb_get_edid(struct dlfb_data *dlfb, char *edid, int len)
(0x80 | (0x02 << 5)), i << 8, 0xA1,
rbuf, 2, USB_CTRL_GET_TIMEOUT);
if (ret < 2) {
- pr_err("Read EDID byte %d failed: %d\n", i, ret);
+ dev_err(&dlfb->udev->dev,
+ "Read EDID byte %d failed: %d\n", i, ret);
i--;
break;
}
@@ -905,8 +903,8 @@ static int dlfb_ops_open(struct fb_info *info, int user)
fb_deferred_io_init(info);
}
- pr_notice("open /dev/fb%d user=%d fb_info=%p count=%d\n",
- info->node, user, info, dlfb->fb_count);
+ dev_dbg(info->dev, "open, user=%d fb_info=%p count=%d\n",
+ user, info, dlfb->fb_count);
return 0;
}
@@ -984,8 +982,7 @@ static int dlfb_ops_release(struct fb_info *info, int user)
info->fbops->fb_mmap = dlfb_ops_mmap;
}
- pr_warn("released /dev/fb%d user=%d count=%d\n",
- info->node, user, dlfb->fb_count);
+ dev_dbg(info->dev, "release, user=%d count=%d\n", user, dlfb->fb_count);
kref_put(&dlfb->kref, dlfb_free);
@@ -996,19 +993,10 @@ static int dlfb_ops_release(struct fb_info *info, int user)
* Check whether a video mode is supported by the DisplayLink chip
* We start from monitor's modes, so don't need to filter that here
*/
-static int dlfb_is_valid_mode(struct fb_videomode *mode,
- struct fb_info *info)
+static int dlfb_is_valid_mode(struct fb_videomode *mode, struct dlfb_data *dlfb)
{
- struct dlfb_data *dlfb = info->par;
-
- if (mode->xres * mode->yres > dlfb->sku_pixel_limit) {
- pr_warn("%dx%d beyond chip capabilities\n",
- mode->xres, mode->yres);
+ if (mode->xres * mode->yres > dlfb->sku_pixel_limit)
return 0;
- }
-
- pr_info("%dx%d @ %d Hz valid mode\n", mode->xres, mode->yres,
- mode->refresh);
return 1;
}
@@ -1029,6 +1017,7 @@ static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
struct fb_videomode mode;
+ struct dlfb_data *dlfb = info->par;
/* TODO: support dynamically changing framebuffer size */
if ((var->xres * var->yres * 2) > info->fix.smem_len)
@@ -1039,7 +1028,7 @@ static int dlfb_ops_check_var(struct fb_var_screeninfo *var,
fb_var_to_videomode(&mode, var);
- if (!dlfb_is_valid_mode(&mode, info))
+ if (!dlfb_is_valid_mode(&mode, dlfb))
return -EINVAL;
return 0;
@@ -1093,8 +1082,8 @@ static int dlfb_ops_blank(int blank_mode, struct fb_info *info)
char *bufptr;
struct urb *urb;
- pr_debug("/dev/fb%d FB_BLANK mode %d --> %d\n",
- info->node, dlfb->blank_mode, blank_mode);
+ dev_dbg(info->dev, "blank, mode %d --> %d\n",
+ dlfb->blank_mode, blank_mode);
if ((dlfb->blank_mode == FB_BLANK_POWERDOWN) &&
(blank_mode != FB_BLANK_POWERDOWN)) {
@@ -1162,7 +1151,7 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info
*/
new_fb = vmalloc(new_len);
if (!new_fb) {
- pr_err("Virtual framebuffer alloc failed\n");
+ dev_err(info->dev, "Virtual framebuffer alloc failed\n");
goto error;
}
@@ -1185,7 +1174,8 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dlfb, struct fb_info *info
if (shadow)
new_back = vzalloc(new_len);
if (!new_back)
- pr_info("No shadow/backing buffer allocated\n");
+ dev_info(info->dev,
+ "No shadow/backing buffer allocated\n");
else {
vfree(dlfb->backing_buffer);
dlfb->backing_buffer = new_back;
@@ -1216,14 +1206,18 @@ static int dlfb_setup_modes(struct dlfb_data *dlfb,
struct fb_info *info,
char *default_edid, size_t default_edid_size)
{
- int i;
- const struct fb_videomode *default_vmode = NULL;
- int result = 0;
char *edid;
- int tries = 3;
+ int i, result = 0, tries = 3;
+ struct device *dev = info->device;
+ struct fb_videomode *mode;
+ const struct fb_videomode *default_vmode = NULL;
- if (info->dev) /* only use mutex if info has been registered */
+ if (info->dev) {
+ /* only use mutex if info has been registered */
mutex_lock(&info->lock);
+ /* parent device is used otherwise */
+ dev = info->dev;
+ }
edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
if (!edid) {
@@ -1255,13 +1249,12 @@ static int dlfb_setup_modes(struct dlfb_data *dlfb,
/* If that fails, use a previously returned EDID if available */
if (info->monspecs.modedb_len == 0) {
-
- pr_err("Unable to get valid EDID from device/display\n");
+ dev_err(dev, "Unable to get valid EDID from device/display\n");
if (dlfb->edid) {
fb_edid_to_monspecs(dlfb->edid, &info->monspecs);
if (info->monspecs.modedb_len > 0)
- pr_err("Using previously queried EDID\n");
+ dev_err(dev, "Using previously queried EDID\n");
}
}
@@ -1273,7 +1266,7 @@ static int dlfb_setup_modes(struct dlfb_data *dlfb,
memcpy(edid, default_edid, default_edid_size);
dlfb->edid = edid;
dlfb->edid_size = default_edid_size;
- pr_err("Using default/backup EDID\n");
+ dev_err(dev, "Using default/backup EDID\n");
}
}
}
@@ -1282,10 +1275,12 @@ static int dlfb_setup_modes(struct dlfb_data *dlfb,
if (info->monspecs.modedb_len > 0) {
for (i = 0; i < info->monspecs.modedb_len; i++) {
- if (dlfb_is_valid_mode(&info->monspecs.modedb[i], info))
- fb_add_videomode(&info->monspecs.modedb[i],
- &info->modelist);
- else {
+ mode = &info->monspecs.modedb[i];
+ if (dlfb_is_valid_mode(mode, dlfb)) {
+ fb_add_videomode(mode, &info->modelist);
+ } else {
+ dev_dbg(dev, "Specified mode %dx%d too big\n",
+ mode->xres, mode->yres);
if (i == 0)
/* if we've removed top/best mode */
info->monspecs.misc
@@ -1309,10 +1304,12 @@ static int dlfb_setup_modes(struct dlfb_data *dlfb,
* But at least the user has a chance to choose
*/
for (i = 0; i < VESA_MODEDB_SIZE; i++) {
- if (dlfb_is_valid_mode((struct fb_videomode *)
- &vesa_modes[i], info))
- fb_add_videomode(&vesa_modes[i],
- &info->modelist);
+ mode = (struct fb_videomode *)&vesa_modes[i];
+ if (dlfb_is_valid_mode(mode, dlfb))
+ fb_add_videomode(mode, &info->modelist);
+ else
+ dev_dbg(dev, "VESA mode %dx%d too big\n",
+ mode->xres, mode->yres);
}
/*
@@ -1492,7 +1489,7 @@ static int dlfb_select_std_channel(struct dlfb_data *dlfb)
}
static int dlfb_parse_vendor_descriptor(struct dlfb_data *dlfb,
- struct usb_interface *interface)
+ struct usb_interface *intf)
{
char *desc;
char *buf;
@@ -1504,20 +1501,21 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dlfb,
return false;
desc = buf;
- total_len = usb_get_descriptor(interface_to_usbdev(interface),
+ total_len = usb_get_descriptor(interface_to_usbdev(intf),
0x5f, /* vendor specific */
0, desc, MAX_VENDOR_DESCRIPTOR_SIZE);
/* if not found, look in configuration descriptor */
if (total_len < 0) {
- if (0 == usb_get_extra_descriptor(interface->cur_altsetting,
+ if (0 == usb_get_extra_descriptor(intf->cur_altsetting,
0x5f, &desc))
total_len = (int) desc[0];
}
if (total_len > 5) {
- pr_info("vendor descriptor length:%x data:%11ph\n", total_len,
- desc);
+ dev_info(&intf->dev,
+ "vendor descriptor length: %d data: %11ph\n",
+ total_len, desc);
if ((desc[0] != total_len) || /* descriptor length */
(desc[1] != 0x5f) || /* vendor descriptor type */
@@ -1542,8 +1540,9 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dlfb,
case 0x0200: { /* max_area */
u32 max_area;
max_area = le32_to_cpu(*((u32 *)desc));
- pr_warn("DL chip limited to %d pixel modes\n",
- max_area);
+ dev_warn(&intf->dev,
+ "DL chip limited to %d pixel modes\n",
+ max_area);
dlfb->sku_pixel_limit = max_area;
break;
}
@@ -1553,14 +1552,15 @@ static int dlfb_parse_vendor_descriptor(struct dlfb_data *dlfb,
desc += length;
}
} else {
- pr_info("vendor descriptor not available (%d)\n", total_len);
+ dev_info(&intf->dev, "vendor descriptor not available (%d)\n",
+ total_len);
}
goto success;
unrecognized:
/* allow udlfb to load for now even if firmware unrecognized */
- pr_err("Unrecognized vendor firmware descriptor\n");
+ dev_err(&intf->dev, "Unrecognized vendor firmware descriptor\n");
success:
kfree(buf);
@@ -1569,56 +1569,48 @@ success:
static void dlfb_init_framebuffer_work(struct work_struct *work);
-static int dlfb_usb_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
+static int dlfb_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
- struct usb_device *usbdev;
struct dlfb_data *dlfb;
int retval = -ENOMEM;
+ struct usb_device *usbdev = interface_to_usbdev(intf);
/* usb initialization */
-
- usbdev = interface_to_usbdev(interface);
-
dlfb = kzalloc(sizeof(*dlfb), GFP_KERNEL);
- if (dlfb == NULL) {
- dev_err(&interface->dev, "dlfb_usb_probe: failed alloc of dev struct\n");
+ if (!dlfb) {
+ dev_err(&intf->dev, "%s: failed to allocate dlfb\n", __func__);
goto error;
}
kref_init(&dlfb->kref); /* matching kref_put in usb .disconnect fn */
dlfb->udev = usbdev;
- usb_set_intfdata(interface, dlfb);
-
- pr_info("%s %s - serial #%s\n",
- usbdev->manufacturer, usbdev->product, usbdev->serial);
- pr_info("vid_%04x&pid_%04x&rev_%04x driver's dlfb_data struct at %p\n",
- le16_to_cpu(usbdev->descriptor.idVendor),
- le16_to_cpu(usbdev->descriptor.idProduct),
- le16_to_cpu(usbdev->descriptor.bcdDevice), dlfb);
- pr_info("console enable=%d\n", console);
- pr_info("fb_defio enable=%d\n", fb_defio);
- pr_info("shadow enable=%d\n", shadow);
+ usb_set_intfdata(intf, dlfb);
+
+ dev_dbg(&intf->dev, "console enable=%d\n", console);
+ dev_dbg(&intf->dev, "fb_defio enable=%d\n", fb_defio);
+ dev_dbg(&intf->dev, "shadow enable=%d\n", shadow);
dlfb->sku_pixel_limit = 2048 * 1152; /* default to maximum */
- if (!dlfb_parse_vendor_descriptor(dlfb, interface)) {
- pr_err("firmware not recognized. Assume incompatible device\n");
+ if (!dlfb_parse_vendor_descriptor(dlfb, intf)) {
+ dev_err(&intf->dev,
+ "firmware not recognized, incompatible device?\n");
goto error;
}
if (pixel_limit) {
- pr_warn("DL chip limit of %d overridden"
- " by module param to %d\n",
- dlfb->sku_pixel_limit, pixel_limit);
+ dev_warn(&intf->dev,
+ "DL chip limit of %d overridden to %d\n",
+ dlfb->sku_pixel_limit, pixel_limit);
dlfb->sku_pixel_limit = pixel_limit;
}
if (!dlfb_alloc_urb_list(dlfb, WRITES_IN_FLIGHT, MAX_TRANSFER)) {
retval = -ENOMEM;
- pr_err("dlfb_alloc_urb_list failed\n");
+ dev_err(&intf->dev, "unable to allocate urb list\n");
goto error;
}
@@ -1646,16 +1638,16 @@ error:
static void dlfb_init_framebuffer_work(struct work_struct *work)
{
+ int i, retval;
+ struct fb_info *info;
+ const struct device_attribute *attr;
struct dlfb_data *dlfb = container_of(work, struct dlfb_data,
init_framebuffer_work.work);
- struct fb_info *info;
- int retval;
- int i;
/* allocates framebuffer driver structure, not framebuffer memory */
info = framebuffer_alloc(0, &dlfb->udev->dev);
if (!info) {
- pr_err("framebuffer_alloc failed\n");
+ dev_err(&dlfb->udev->dev, "framebuffer_alloc failed\n");
goto error;
}
@@ -1666,7 +1658,7 @@ static void dlfb_init_framebuffer_work(struct work_struct *work)
retval = fb_alloc_cmap(&info->cmap, 256, 0);
if (retval < 0) {
- pr_err("fb_alloc_cmap failed %x\n", retval);
+ dev_err(info->device, "cmap allocation failed: %d\n", retval);
goto error;
}
@@ -1677,7 +1669,8 @@ static void dlfb_init_framebuffer_work(struct work_struct *work)
retval = dlfb_setup_modes(dlfb, info, NULL, 0);
if (retval != 0) {
- pr_err("unable to find common mode for display and adapter\n");
+ dev_err(info->device,
+ "unable to find common mode for display and adapter\n");
goto error;
}
@@ -1691,43 +1684,46 @@ static void dlfb_init_framebuffer_work(struct work_struct *work)
retval = register_framebuffer(info);
if (retval < 0) {
- pr_err("register_framebuffer failed %d\n", retval);
+ dev_err(info->device, "unable to register framebuffer: %d\n",
+ retval);
goto error;
}
for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) {
- retval = device_create_file(info->dev, &fb_device_attrs[i]);
- if (retval) {
- pr_warn("device_create_file failed %d\n", retval);
- }
+ attr = &fb_device_attrs[i];
+ retval = device_create_file(info->dev, attr);
+ if (retval)
+ dev_warn(info->device,
+ "failed to create '%s' attribute: %d\n",
+ attr->attr.name, retval);
}
retval = device_create_bin_file(info->dev, &edid_attr);
- if (retval) {
- pr_warn("device_create_bin_file failed %d\n", retval);
- }
-
- pr_info("DisplayLink USB device /dev/fb%d attached. %dx%d resolution."
- " Using %dK framebuffer memory\n", info->node,
- info->var.xres, info->var.yres,
- ((dlfb->backing_buffer) ?
- info->fix.smem_len * 2 : info->fix.smem_len) >> 10);
+ if (retval)
+ dev_warn(info->device, "failed to create '%s' attribute: %d\n",
+ edid_attr.attr.name, retval);
+
+ dev_info(info->device,
+ "%s is DisplayLink USB device (%dx%d, %dK framebuffer memory)\n",
+ dev_name(info->dev), info->var.xres, info->var.yres,
+ ((dlfb->backing_buffer) ?
+ info->fix.smem_len * 2 : info->fix.smem_len) >> 10);
return;
error:
dlfb_free_framebuffer(dlfb);
}
-static void dlfb_usb_disconnect(struct usb_interface *interface)
+static void dlfb_usb_disconnect(struct usb_interface *intf)
{
struct dlfb_data *dlfb;
struct fb_info *info;
int i;
- dlfb = usb_get_intfdata(interface);
+ dlfb = usb_get_intfdata(intf);
info = dlfb->info;
- pr_info("USB disconnect starting\n");
+ dev_dbg(&intf->dev, "USB disconnect starting\n");
/* we virtualize until all fb clients release. Then we free */
dlfb->virtualized = true;
@@ -1746,7 +1742,7 @@ static void dlfb_usb_disconnect(struct usb_interface *interface)
unlink_framebuffer(info);
}
- usb_set_intfdata(interface, NULL);
+ usb_set_intfdata(intf, NULL);
dlfb->udev = NULL;
/* if clients still have us open, will be freed on last close */
@@ -1774,15 +1770,21 @@ static void dlfb_urb_completion(struct urb *urb)
struct dlfb_data *dlfb = unode->dlfb;
unsigned long flags;
- /* sync/async unlink faults aren't errors */
- if (urb->status) {
- if (!(urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN)) {
- pr_err("%s - nonzero write bulk status received: %d\n",
- __func__, urb->status);
- atomic_set(&dlfb->lost_pixels, 1);
- }
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* sync/async unlink faults aren't errors */
+ break;
+ default:
+ dev_err(&dlfb->udev->dev,
+ "%s - nonzero write bulk status received: %d\n",
+ __func__, urb->status);
+ atomic_set(&dlfb->lost_pixels, 1);
+ break;
}
urb->transfer_buffer_length = dlfb->urbs.size; /* reset to actual */
@@ -1903,8 +1905,9 @@ static struct urb *dlfb_get_urb(struct dlfb_data *dlfb)
ret = down_timeout(&dlfb->urbs.limit_sem, GET_URB_TIMEOUT);
if (ret) {
atomic_set(&dlfb->lost_pixels, 1);
- pr_warn("wait for urb interrupted: %x available: %d\n",
- ret, dlfb->urbs.available);
+ dev_warn(&dlfb->udev->dev,
+ "wait for urb interrupted: %d available: %d\n",
+ ret, dlfb->urbs.available);
return NULL;
}
@@ -1932,7 +1935,7 @@ static int dlfb_submit_urb(struct dlfb_data *dlfb, struct urb *urb, size_t len)
if (ret) {
dlfb_urb_completion(urb); /* because no one else will */
atomic_set(&dlfb->lost_pixels, 1);
- pr_err("usb_submit_urb error %x\n", ret);
+ dev_err(&dlfb->udev->dev, "submit urb error: %d\n", ret);
}
return ret;
}