Skip to content

Commit b72018a

Browse files
committed
Merge tag 'fbdev-for-6.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev
Pull fbdev fixes from Helge Deller: "A use-after-free bugfix in the smscufx driver and various minor error path fixes, smaller build fixes, sysfs fixes and typos in comments in the stifb, sisfb, da8xxfb, xilinxfb, sm501fb, gbefb and cyber2000fb drivers" * tag 'fbdev-for-6.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/linux-fbdev: fbdev: cyber2000fb: fix missing pci_disable_device() fbdev: sisfb: use explicitly signed char fbdev: smscufx: Fix several use-after-free bugs fbdev: xilinxfb: Make xilinxfb_release() return void fbdev: sisfb: fix repeated word in comment fbdev: gbefb: Convert sysfs snprintf to sysfs_emit fbdev: sm501fb: Convert sysfs snprintf to sysfs_emit fbdev: stifb: Fall back to cfb_fillrect() on 32-bit HCRX cards fbdev: da8xx-fb: Fix error handling in .remove() fbdev: MIPS supports iomem addresses
2 parents 9f12754 + 3c6bf6b commit b72018a

File tree

11 files changed

+47
-38
lines changed

11 files changed

+47
-38
lines changed

drivers/usb/misc/sisusbvga/sisusb_struct.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ struct SiS_Ext {
9191
unsigned char VB_ExtTVYFilterIndex;
9292
unsigned char VB_ExtTVYFilterIndexROM661;
9393
unsigned char REFindex;
94-
char ROMMODEIDX661;
94+
signed char ROMMODEIDX661;
9595
};
9696

9797
struct SiS_Ext2 {

drivers/video/fbdev/cyber2000fb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,6 +1796,7 @@ static int cyberpro_pci_probe(struct pci_dev *dev,
17961796
failed_regions:
17971797
cyberpro_free_fb_info(cfb);
17981798
failed_release:
1799+
pci_disable_device(dev);
17991800
return err;
18001801
}
18011802

@@ -1812,6 +1813,7 @@ static void cyberpro_pci_remove(struct pci_dev *dev)
18121813
int_cfb_info = NULL;
18131814

18141815
pci_release_regions(dev);
1816+
pci_disable_device(dev);
18151817
}
18161818
}
18171819

drivers/video/fbdev/da8xx-fb.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,8 @@ static int fb_remove(struct platform_device *dev)
10761076
if (par->lcd_supply) {
10771077
ret = regulator_disable(par->lcd_supply);
10781078
if (ret)
1079-
return ret;
1079+
dev_warn(&dev->dev, "Failed to disable regulator (%pe)\n",
1080+
ERR_PTR(ret));
10801081
}
10811082

10821083
lcd_disable_raster(DA8XX_FRAME_WAIT);

drivers/video/fbdev/gbefb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,14 +1060,14 @@ static const struct fb_ops gbefb_ops = {
10601060

10611061
static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
10621062
{
1063-
return snprintf(buf, PAGE_SIZE, "%u\n", gbe_mem_size);
1063+
return sysfs_emit(buf, "%u\n", gbe_mem_size);
10641064
}
10651065

10661066
static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
10671067

10681068
static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
10691069
{
1070-
return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
1070+
return sysfs_emit(buf, "%d\n", gbe_revision);
10711071
}
10721072

10731073
static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);

drivers/video/fbdev/sis/sis_accel.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ SiS310SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x, int
202202
* and destination blitting areas overlap and
203203
* adapt the bitmap addresses synchronously
204204
* if the coordinates exceed the valid range.
205-
* The the areas do not overlap, we do our
205+
* The areas do not overlap, we do our
206206
* normal check.
207207
*/
208208
if((mymax - mymin) < height) {

drivers/video/fbdev/sis/vstruct.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ struct SiS_Ext {
148148
unsigned char VB_ExtTVYFilterIndex;
149149
unsigned char VB_ExtTVYFilterIndexROM661;
150150
unsigned char REFindex;
151-
char ROMMODEIDX661;
151+
signed char ROMMODEIDX661;
152152
};
153153

154154
struct SiS_Ext2 {

drivers/video/fbdev/sm501fb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1166,7 +1166,7 @@ static ssize_t sm501fb_crtsrc_show(struct device *dev,
11661166
ctrl = smc501_readl(info->regs + SM501_DC_CRT_CONTROL);
11671167
ctrl &= SM501_DC_CRT_CONTROL_SEL;
11681168

1169-
return snprintf(buf, PAGE_SIZE, "%s\n", ctrl ? "crt" : "panel");
1169+
return sysfs_emit(buf, "%s\n", ctrl ? "crt" : "panel");
11701170
}
11711171

11721172
/* sm501fb_crtsrc_show

drivers/video/fbdev/smscufx.c

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ struct ufx_data {
9797
struct kref kref;
9898
int fb_count;
9999
bool virtualized; /* true when physical usb device not present */
100-
struct delayed_work free_framebuffer_work;
101100
atomic_t usb_active; /* 0 = update virtual buffer, but no usb traffic */
102101
atomic_t lost_pixels; /* 1 = a render op failed. Need screen refresh */
103102
u8 *edid; /* null until we read edid from hw or get from sysfs */
@@ -1117,15 +1116,24 @@ static void ufx_free(struct kref *kref)
11171116
{
11181117
struct ufx_data *dev = container_of(kref, struct ufx_data, kref);
11191118

1120-
/* this function will wait for all in-flight urbs to complete */
1121-
if (dev->urbs.count > 0)
1122-
ufx_free_urb_list(dev);
1119+
kfree(dev);
1120+
}
11231121

1124-
pr_debug("freeing ufx_data %p", dev);
1122+
static void ufx_ops_destory(struct fb_info *info)
1123+
{
1124+
struct ufx_data *dev = info->par;
1125+
int node = info->node;
11251126

1126-
kfree(dev);
1127+
/* Assume info structure is freed after this point */
1128+
framebuffer_release(info);
1129+
1130+
pr_debug("fb_info for /dev/fb%d has been freed", node);
1131+
1132+
/* release reference taken by kref_init in probe() */
1133+
kref_put(&dev->kref, ufx_free);
11271134
}
11281135

1136+
11291137
static void ufx_release_urb_work(struct work_struct *work)
11301138
{
11311139
struct urb_node *unode = container_of(work, struct urb_node,
@@ -1134,14 +1142,9 @@ static void ufx_release_urb_work(struct work_struct *work)
11341142
up(&unode->dev->urbs.limit_sem);
11351143
}
11361144

1137-
static void ufx_free_framebuffer_work(struct work_struct *work)
1145+
static void ufx_free_framebuffer(struct ufx_data *dev)
11381146
{
1139-
struct ufx_data *dev = container_of(work, struct ufx_data,
1140-
free_framebuffer_work.work);
11411147
struct fb_info *info = dev->info;
1142-
int node = info->node;
1143-
1144-
unregister_framebuffer(info);
11451148

11461149
if (info->cmap.len != 0)
11471150
fb_dealloc_cmap(&info->cmap);
@@ -1153,11 +1156,6 @@ static void ufx_free_framebuffer_work(struct work_struct *work)
11531156

11541157
dev->info = NULL;
11551158

1156-
/* Assume info structure is freed after this point */
1157-
framebuffer_release(info);
1158-
1159-
pr_debug("fb_info for /dev/fb%d has been freed", node);
1160-
11611159
/* ref taken in probe() as part of registering framebfufer */
11621160
kref_put(&dev->kref, ufx_free);
11631161
}
@@ -1169,11 +1167,13 @@ static int ufx_ops_release(struct fb_info *info, int user)
11691167
{
11701168
struct ufx_data *dev = info->par;
11711169

1170+
mutex_lock(&disconnect_mutex);
1171+
11721172
dev->fb_count--;
11731173

11741174
/* We can't free fb_info here - fbmem will touch it when we return */
11751175
if (dev->virtualized && (dev->fb_count == 0))
1176-
schedule_delayed_work(&dev->free_framebuffer_work, HZ);
1176+
ufx_free_framebuffer(dev);
11771177

11781178
if ((dev->fb_count == 0) && (info->fbdefio)) {
11791179
fb_deferred_io_cleanup(info);
@@ -1186,6 +1186,8 @@ static int ufx_ops_release(struct fb_info *info, int user)
11861186

11871187
kref_put(&dev->kref, ufx_free);
11881188

1189+
mutex_unlock(&disconnect_mutex);
1190+
11891191
return 0;
11901192
}
11911193

@@ -1292,6 +1294,7 @@ static const struct fb_ops ufx_ops = {
12921294
.fb_blank = ufx_ops_blank,
12931295
.fb_check_var = ufx_ops_check_var,
12941296
.fb_set_par = ufx_ops_set_par,
1297+
.fb_destroy = ufx_ops_destory,
12951298
};
12961299

12971300
/* Assumes &info->lock held by caller
@@ -1673,9 +1676,6 @@ static int ufx_usb_probe(struct usb_interface *interface,
16731676
goto destroy_modedb;
16741677
}
16751678

1676-
INIT_DELAYED_WORK(&dev->free_framebuffer_work,
1677-
ufx_free_framebuffer_work);
1678-
16791679
retval = ufx_reg_read(dev, 0x3000, &id_rev);
16801680
check_warn_goto_error(retval, "error %d reading 0x3000 register from device", retval);
16811681
dev_dbg(dev->gdev, "ID_REV register value 0x%08x", id_rev);
@@ -1748,10 +1748,12 @@ static int ufx_usb_probe(struct usb_interface *interface,
17481748
static void ufx_usb_disconnect(struct usb_interface *interface)
17491749
{
17501750
struct ufx_data *dev;
1751+
struct fb_info *info;
17511752

17521753
mutex_lock(&disconnect_mutex);
17531754

17541755
dev = usb_get_intfdata(interface);
1756+
info = dev->info;
17551757

17561758
pr_debug("USB disconnect starting\n");
17571759

@@ -1765,12 +1767,15 @@ static void ufx_usb_disconnect(struct usb_interface *interface)
17651767

17661768
/* if clients still have us open, will be freed on last close */
17671769
if (dev->fb_count == 0)
1768-
schedule_delayed_work(&dev->free_framebuffer_work, 0);
1770+
ufx_free_framebuffer(dev);
17691771

1770-
/* release reference taken by kref_init in probe() */
1771-
kref_put(&dev->kref, ufx_free);
1772+
/* this function will wait for all in-flight urbs to complete */
1773+
if (dev->urbs.count > 0)
1774+
ufx_free_urb_list(dev);
17721775

1773-
/* consider ufx_data freed */
1776+
pr_debug("freeing ufx_data %p", dev);
1777+
1778+
unregister_framebuffer(info);
17741779

17751780
mutex_unlock(&disconnect_mutex);
17761781
}

drivers/video/fbdev/stifb.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,8 @@ stifb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
10551055
{
10561056
struct stifb_info *fb = container_of(info, struct stifb_info, info);
10571057

1058-
if (rect->rop != ROP_COPY)
1058+
if (rect->rop != ROP_COPY ||
1059+
(fb->id == S9000_ID_HCRX && fb->info.var.bits_per_pixel == 32))
10591060
return cfb_fillrect(info, rect);
10601061

10611062
SETUP_HW(fb);

drivers/video/fbdev/xilinxfb.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ static int xilinxfb_assign(struct platform_device *pdev,
376376
return rc;
377377
}
378378

379-
static int xilinxfb_release(struct device *dev)
379+
static void xilinxfb_release(struct device *dev)
380380
{
381381
struct xilinxfb_drvdata *drvdata = dev_get_drvdata(dev);
382382

@@ -402,8 +402,6 @@ static int xilinxfb_release(struct device *dev)
402402
if (!(drvdata->flags & BUS_ACCESS_FLAG))
403403
dcr_unmap(drvdata->dcr_host, drvdata->dcr_len);
404404
#endif
405-
406-
return 0;
407405
}
408406

409407
/* ---------------------------------------------------------------------
@@ -480,7 +478,9 @@ static int xilinxfb_of_probe(struct platform_device *pdev)
480478

481479
static int xilinxfb_of_remove(struct platform_device *op)
482480
{
483-
return xilinxfb_release(&op->dev);
481+
xilinxfb_release(&op->dev);
482+
483+
return 0;
484484
}
485485

486486
/* Match table for of_platform binding */

0 commit comments

Comments
 (0)