Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 219773
b: refs/heads/master
c: d5ed543
h: refs/heads/master
i:
  219771: 6987709
v: v3
  • Loading branch information
Bernie Thompson authored and Greg Kroah-Hartman committed Sep 5, 2010
1 parent 23a9ac7 commit 2020670
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 99 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8ef8cc4fca4a92e77c0b5aa7a852a6c3d2fba844
refs/heads/master: d5ed54322e54d48e5fa66dff0086b79211f1cde7
178 changes: 81 additions & 97 deletions trunk/drivers/staging/udlfb/udlfb.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,9 @@ static struct usb_device_id id_table[] = {
};
MODULE_DEVICE_TABLE(usb, id_table);

#ifndef CONFIG_FB_DEFERRED_IO
#warning Please set CONFIG_FB_DEFFERRED_IO option to support generic fbdev apps
#endif

#ifndef CONFIG_FB_SYS_IMAGEBLIT
#ifndef CONFIG_FB_SYS_IMAGEBLIT_MODULE
#warning Please set CONFIG_FB_SYS_IMAGEBLIT option to support fb console
#endif
#endif

#ifndef CONFIG_FB_MODE_HELPERS
#warning CONFIG_FB_MODE_HELPERS required. Expect build break
#endif
/* module options */
static int console; /* Optionally allow fbcon to consume first framebuffer */
static int fb_defio; /* Optionally enable experimental fb_defio mmap support */

/* dlfb keeps a list of urbs for efficient bulk transfers */
static void dlfb_urb_completion(struct urb *urb);
Expand Down Expand Up @@ -695,6 +685,68 @@ static void dlfb_ops_fillrect(struct fb_info *info,

}

#ifdef CONFIG_FB_DEFERRED_IO
/*
* NOTE: fb_defio.c is holding info->fbdefio.mutex
* Touching ANY framebuffer memory that triggers a page fault
* in fb_defio will cause a deadlock, when it also tries to
* grab the same mutex.
*/
static void dlfb_dpy_deferred_io(struct fb_info *info,
struct list_head *pagelist)
{
struct page *cur;
struct fb_deferred_io *fbdefio = info->fbdefio;
struct dlfb_data *dev = info->par;
struct urb *urb;
char *cmd;
cycles_t start_cycles, end_cycles;
int bytes_sent = 0;
int bytes_identical = 0;
int bytes_rendered = 0;

if (!fb_defio)
return;

if (!atomic_read(&dev->usb_active))
return;

start_cycles = get_cycles();

urb = dlfb_get_urb(dev);
if (!urb)
return;

cmd = urb->transfer_buffer;

/* walk the written page list and render each to device */
list_for_each_entry(cur, &fbdefio->pagelist, lru) {

dlfb_render_hline(dev, &urb, (char *) info->fix.smem_start,
&cmd, cur->index << PAGE_SHIFT,
PAGE_SIZE, &bytes_identical, &bytes_sent);
bytes_rendered += PAGE_SIZE;
}

if (cmd > (char *) urb->transfer_buffer) {
/* Send partial buffer remaining before exiting */
int len = cmd - (char *) urb->transfer_buffer;
dlfb_submit_urb(dev, urb, len);
bytes_sent += len;
} else
dlfb_urb_completion(urb);

atomic_add(bytes_sent, &dev->bytes_sent);
atomic_add(bytes_identical, &dev->bytes_identical);
atomic_add(bytes_rendered, &dev->bytes_rendered);
end_cycles = get_cycles();
atomic_add(((unsigned int) ((end_cycles - start_cycles)
>> 10)), /* Kcycles */
&dev->cpu_kcycles_used);
}

#endif

static int dlfb_get_edid(struct dlfb_data *dev, char *edid, int len)
{
int i;
Expand Down Expand Up @@ -758,8 +810,6 @@ static int dlfb_ops_ioctl(struct fb_info *info, unsigned int cmd,
if (area->y > info->var.yres)
area->y = info->var.yres;

atomic_set(&dev->use_defio, 0);

dlfb_handle_damage(dev, area->x, area->y, area->w, area->h,
info->screen_base);
}
Expand Down Expand Up @@ -803,9 +853,13 @@ static int dlfb_ops_open(struct fb_info *info, int user)
{
struct dlfb_data *dev = info->par;

/* if (user == 0)
* We could special case kernel mode clients (fbcon) here
*/
/*
* fbcon aggressively connects to first framebuffer it finds,
* preventing other clients (X) from working properly. Usually
* not what the user wants. Fail by default with option to enable.
*/
if ((user == 0) & (!console))
return -EBUSY;

/* If the USB device is gone, we don't accept new opens */
if (dev->virtualized)
Expand All @@ -816,7 +870,7 @@ static int dlfb_ops_open(struct fb_info *info, int user)
kref_get(&dev->kref);

#ifdef CONFIG_FB_DEFERRED_IO
if ((atomic_read(&dev->use_defio)) && (info->fbdefio == NULL)) {
if (fb_defio && (info->fbdefio == NULL)) {
/* enable defio */
info->fbdefio = &dlfb_defio;
fb_deferred_io_init(info);
Expand Down Expand Up @@ -1345,30 +1399,6 @@ static ssize_t metrics_reset_store(struct device *fbdev,
return count;
}

static ssize_t use_defio_show(struct device *fbdev,
struct device_attribute *a, char *buf) {
struct fb_info *fb_info = dev_get_drvdata(fbdev);
struct dlfb_data *dev = fb_info->par;
return snprintf(buf, PAGE_SIZE, "%d\n",
atomic_read(&dev->use_defio));
}

static ssize_t use_defio_store(struct device *fbdev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct fb_info *fb_info = dev_get_drvdata(fbdev);
struct dlfb_data *dev = fb_info->par;

if (count > 0) {
if (buf[0] == '0')
atomic_set(&dev->use_defio, 0);
if (buf[0] == '1')
atomic_set(&dev->use_defio, 1);
}
return count;
}

static struct bin_attribute edid_attr = {
.attr.name = "edid",
.attr.mode = 0666,
Expand All @@ -1383,60 +1413,9 @@ static struct device_attribute fb_device_attrs[] = {
__ATTR_RO(metrics_bytes_sent),
__ATTR_RO(metrics_cpu_kcycles_used),
__ATTR(metrics_reset, S_IWUGO, NULL, metrics_reset_store),
__ATTR_RW(use_defio),
};

#ifdef CONFIG_FB_DEFERRED_IO
static void dlfb_dpy_deferred_io(struct fb_info *info,
struct list_head *pagelist)
{
struct page *cur;
struct fb_deferred_io *fbdefio = info->fbdefio;
struct dlfb_data *dev = info->par;
struct urb *urb;
char *cmd;
cycles_t start_cycles, end_cycles;
int bytes_sent = 0;
int bytes_identical = 0;
int bytes_rendered = 0;

if (!atomic_read(&dev->use_defio))
return;

if (!atomic_read(&dev->usb_active))
return;

start_cycles = get_cycles();

urb = dlfb_get_urb(dev);
if (!urb)
return;
cmd = urb->transfer_buffer;

/* walk the written page list and render each to device */
list_for_each_entry(cur, &fbdefio->pagelist, lru) {
dlfb_render_hline(dev, &urb, (char *) info->fix.smem_start,
&cmd, cur->index << PAGE_SHIFT,
PAGE_SIZE, &bytes_identical, &bytes_sent);
bytes_rendered += PAGE_SIZE;
}

if (cmd > (char *) urb->transfer_buffer) {
/* Send partial buffer remaining before exiting */
int len = cmd - (char *) urb->transfer_buffer;
dlfb_submit_urb(dev, urb, len);
bytes_sent += len;
} else
dlfb_urb_completion(urb);

atomic_add(bytes_sent, &dev->bytes_sent);
atomic_add(bytes_identical, &dev->bytes_identical);
atomic_add(bytes_rendered, &dev->bytes_rendered);
end_cycles = get_cycles();
atomic_add(((unsigned int) ((end_cycles - start_cycles)
>> 10)), /* Kcycles */
&dev->cpu_kcycles_used);
}

static struct fb_deferred_io dlfb_defio = {
.delay = 5,
Expand Down Expand Up @@ -1563,6 +1542,8 @@ static int dlfb_usb_probe(struct usb_interface *interface,
dl_info("vid_%04x&pid_%04x&rev_%04x driver's dlfb_data struct at %p\n",
usbdev->descriptor.idVendor, usbdev->descriptor.idProduct,
usbdev->descriptor.bcdDevice, dev);
dl_info("console enable=%d\n", console);
dl_info("fb_defio enable=%d\n", fb_defio);

dev->sku_pixel_limit = 2048 * 1152; /* default to maximum */

Expand Down Expand Up @@ -1611,9 +1592,6 @@ static int dlfb_usb_probe(struct usb_interface *interface,

/* ready to begin using device */

#ifdef CONFIG_FB_DEFERRED_IO
atomic_set(&dev->use_defio, 1);
#endif
atomic_set(&dev->usb_active, 1);
dlfb_select_std_channel(dev);

Expand Down Expand Up @@ -1893,6 +1871,12 @@ static int dlfb_submit_urb(struct dlfb_data *dev, struct urb *urb, size_t len)
return ret;
}

module_param(console, bool, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP);
MODULE_PARM_DESC(console, "Allow fbcon to consume first framebuffer found");

module_param(fb_defio, bool, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP);
MODULE_PARM_DESC(fb_defio, "Enable fb_defio mmap support. *Experimental*");

MODULE_AUTHOR("Roberto De Ioris <roberto@unbit.it>, "
"Jaya Kumar <jayakumar.lkml@gmail.com>, "
"Bernie Thompson <bernie@plugable.com>");
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/staging/udlfb/udlfb.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ struct dlfb_data {
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 */
atomic_t use_defio; /* 0 = rely on ioctls and blit/copy/fill rects */
char *edid; /* null until we read edid from hw or get from sysfs */
size_t edid_size;
int sku_pixel_limit;
Expand Down

0 comments on commit 2020670

Please sign in to comment.