fbdev changes for v4.21:

- fix fbcon to not cause crash on unregister_framebuffer()
   when there is more than one framebuffer (Noralf Trønnes)
 
 - improve support for small rotated displays (Peter Rosin)
 
 - fix probe failure handling in udlfb driver (Dan Carpenter)
 
 - add config option to center the bootup logo (Peter Rosin)
 
 - make FB_BACKLIGHT config option tristate (Rob Clark)
 
 - remove superfluous HAS_DMA dependency for goldfishfb driver
   (Geert Uytterhoeven)
 
 - misc fixes (Alexey Khoroshilov, YueHaibing, Colin Ian King,
   Lubomir Rintel)
 
 - misc cleanups (Yangtao Li, Wen Yang)
 
 also there is DRM's nouveau driver fix for wrong FB_BACKLIGHT
 config option usage (FB_BACKLIGHT is for internal fbdev
 subsystem use only)
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCAAGBQJcL0mpAAoJEH4ztj+gR8ILCikP/iXITim75hV2VU3EIB2xQ6B8
 oRpksZ2NnkS+TKQD7RbbweytBUIPtC3awd7uck6MNoiROmkZVqEl9jXsM84yU9XL
 1t+CQHtLQbnN84RTSBtA5G75PViRK9k39y2uKagJeANlaMVK8dRxR+6QFwnxlWnx
 zWbP70GyTQba+d2uJIEyVuZBRzhNyjoK9KjwidMvVqthlmRQKTHuAkZnuVUbt9l1
 xhO8YxMj8zdc9DPsUGB4tsPwJ6q+qq4FihC7tamcJeWRW6sxBmYTWWnfYuYQrRN1
 izp5xnGoeGr+s9pfOxLno2IMFDxOlZpF7aZg22pB9joMciqvy58OyPzKckdgLveq
 VIjx8l+dffgq12z6adPkLYHxHp7U4D5EFQg5WRKcImHAPTtea3+vS2C2aZhadEgK
 0EcJrcIWO4cUijtH8aelur/I87iVrn81G34mSOvR45/RlKqcn569hlANPAGp8Gop
 R6WSq16xY67eb3oRLbeK5W46cNd36L/9UOJOvxAMlo/Or3zyrgQn9z4Zj0IKJjXZ
 ixR+AL4nKlhZDkNdK8cmUTLFyN9JsbOjjW3GKgw9hz/BST6Z+Rk8L8OxhyyAahVk
 9wuupyHdpHdhuWWzzOLrmRcpNE3l1w79j79dHfbqrzQn/Uql0P5u0Hyrc5f8Fy4W
 bslNoVbRMXtlktacxv4X
 =rd5j
 -----END PGP SIGNATURE-----

Merge tag 'fbdev-v4.21' of git://github.com/bzolnier/linux

Pull fbdev updates from Bartlomiej Zolnierkiewicz:
 "This time the pull request is really small.

  The most notable changes are fixing fbcon to not cause crash on
  unregister_framebuffer() operation when there is more than one
  framebuffer, adding config option to center the bootup logo and making
  FB_BACKLIGHT config option tristate (which in turn uncovered incorrect
  FB_BACKLIGHT usage by DRM's nouveau driver).

  Summary:

   - fix fbcon to not cause crash on unregister_framebuffer() when there
     is more than one framebuffer (Noralf Trønnes)

   - improve support for small rotated displays (Peter Rosin)

   - fix probe failure handling in udlfb driver (Dan Carpenter)

   - add config option to center the bootup logo (Peter Rosin)

   - make FB_BACKLIGHT config option tristate (Rob Clark)

   - remove superfluous HAS_DMA dependency for goldfishfb driver (Geert
     Uytterhoeven)

   - misc fixes (Alexey Khoroshilov, YueHaibing, Colin Ian King, Lubomir
     Rintel)

   - misc cleanups (Yangtao Li, Wen Yang)

  also there is DRM's nouveau driver fix for wrong FB_BACKLIGHT config
  option usage (FB_BACKLIGHT is for internal fbdev subsystem use only)"

* tag 'fbdev-v4.21' of git://github.com/bzolnier/linux:
  drm/nouveau: fix incorrect FB_BACKLIGHT usage in Kconfig
  fbdev: fbcon: Fix unregister crash when more than one framebuffer
  fbdev: Remove depends on HAS_DMA in case of platform dependency
  pxa168fb: trivial typo fix
  fbdev: fsl-diu: remove redundant null check on cmap
  fbdev: omap2: omapfb: convert to DEFINE_SHOW_ATTRIBUTE
  fbdev: uvesafb: fix spelling mistake "memoery" -> "memory"
  fbdev: fbmem: add config option to center the bootup logo
  fbdev: fbmem: make fb_show_logo_line return the end instead of the height
  video: fbdev: pxafb: Fix "WARNING: invalid free of devm_ allocated data"
  fbdev: fbmem: behave better with small rotated displays and many CPUs
  video: clps711x-fb: release disp device node in probe()
  fbdev: make FB_BACKLIGHT a tristate
  udlfb: fix some inconsistent NULL checking
This commit is contained in:
Linus Torvalds 2019-01-05 18:15:37 -08:00
commit a8a6b1186b
15 changed files with 71 additions and 47 deletions

View File

@ -4,7 +4,8 @@ config DRM_NOUVEAU
select FW_LOADER select FW_LOADER
select DRM_KMS_HELPER select DRM_KMS_HELPER
select DRM_TTM select DRM_TTM
select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT select BACKLIGHT_CLASS_DEVICE if DRM_NOUVEAU_BACKLIGHT
select BACKLIGHT_LCD_SUPPORT if DRM_NOUVEAU_BACKLIGHT
select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && INPUT select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && INPUT
select X86_PLATFORM_DEVICES if ACPI && X86 select X86_PLATFORM_DEVICES if ACPI && X86
select ACPI_WMI if ACPI && X86 select ACPI_WMI if ACPI && X86

View File

@ -184,7 +184,7 @@ config FB_MACMODES
depends on FB depends on FB
config FB_BACKLIGHT config FB_BACKLIGHT
bool tristate
depends on FB depends on FB
select BACKLIGHT_LCD_SUPPORT select BACKLIGHT_LCD_SUPPORT
select BACKLIGHT_CLASS_DEVICE select BACKLIGHT_CLASS_DEVICE
@ -2037,7 +2037,8 @@ config FB_XILINX
config FB_GOLDFISH config FB_GOLDFISH
tristate "Goldfish Framebuffer" tristate "Goldfish Framebuffer"
depends on FB && HAS_DMA && (GOLDFISH || COMPILE_TEST) depends on FB
depends on GOLDFISH || COMPILE_TEST
select FB_CFB_FILLRECT select FB_CFB_FILLRECT
select FB_CFB_COPYAREA select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT select FB_CFB_IMAGEBLIT

View File

@ -287,14 +287,17 @@ static int clps711x_fb_probe(struct platform_device *pdev)
} }
ret = of_get_fb_videomode(disp, &cfb->mode, OF_USE_NATIVE_MODE); ret = of_get_fb_videomode(disp, &cfb->mode, OF_USE_NATIVE_MODE);
if (ret) if (ret) {
of_node_put(disp);
goto out_fb_release; goto out_fb_release;
}
of_property_read_u32(disp, "ac-prescale", &cfb->ac_prescale); of_property_read_u32(disp, "ac-prescale", &cfb->ac_prescale);
cfb->cmap_invert = of_property_read_bool(disp, "cmap-invert"); cfb->cmap_invert = of_property_read_bool(disp, "cmap-invert");
ret = of_property_read_u32(disp, "bits-per-pixel", ret = of_property_read_u32(disp, "bits-per-pixel",
&info->var.bits_per_pixel); &info->var.bits_per_pixel);
of_node_put(disp);
if (ret) if (ret)
goto out_fb_release; goto out_fb_release;

View File

@ -3064,7 +3064,7 @@ static int fbcon_fb_unbind(int idx)
for (i = first_fb_vc; i <= last_fb_vc; i++) { for (i = first_fb_vc; i <= last_fb_vc; i++) {
if (con2fb_map[i] != idx && if (con2fb_map[i] != idx &&
con2fb_map[i] != -1) { con2fb_map[i] != -1) {
new_idx = i; new_idx = con2fb_map[i];
break; break;
} }
} }

View File

@ -436,7 +436,9 @@ static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
image->dx += image->width + 8; image->dx += image->width + 8;
} }
} else if (rotate == FB_ROTATE_UD) { } else if (rotate == FB_ROTATE_UD) {
for (x = 0; x < num; x++) { u32 dx = image->dx;
for (x = 0; x < num && image->dx <= dx; x++) {
info->fbops->fb_imageblit(info, image); info->fbops->fb_imageblit(info, image);
image->dx -= image->width + 8; image->dx -= image->width + 8;
} }
@ -448,7 +450,9 @@ static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
image->dy += image->height + 8; image->dy += image->height + 8;
} }
} else if (rotate == FB_ROTATE_CCW) { } else if (rotate == FB_ROTATE_CCW) {
for (x = 0; x < num; x++) { u32 dy = image->dy;
for (x = 0; x < num && image->dy <= dy; x++) {
info->fbops->fb_imageblit(info, image); info->fbops->fb_imageblit(info, image);
image->dy -= image->height + 8; image->dy -= image->height + 8;
} }
@ -502,8 +506,25 @@ static int fb_show_logo_line(struct fb_info *info, int rotate,
fb_set_logo(info, logo, logo_new, fb_logo.depth); fb_set_logo(info, logo, logo_new, fb_logo.depth);
} }
#ifdef CONFIG_FB_LOGO_CENTER
{
int xres = info->var.xres;
int yres = info->var.yres;
if (rotate == FB_ROTATE_CW || rotate == FB_ROTATE_CCW) {
xres = info->var.yres;
yres = info->var.xres;
}
while (n && (n * (logo->width + 8) - 8 > xres))
--n;
image.dx = (xres - n * (logo->width + 8) - 8) / 2;
image.dy = y ?: (yres - logo->height) / 2;
}
#else
image.dx = 0; image.dx = 0;
image.dy = y; image.dy = y;
#endif
image.width = logo->width; image.width = logo->width;
image.height = logo->height; image.height = logo->height;
@ -521,7 +542,7 @@ static int fb_show_logo_line(struct fb_info *info, int rotate,
info->pseudo_palette = saved_pseudo_palette; info->pseudo_palette = saved_pseudo_palette;
kfree(logo_new); kfree(logo_new);
kfree(logo_rotate); kfree(logo_rotate);
return logo->height; return image.dy + logo->height;
} }
@ -573,8 +594,8 @@ static int fb_show_extra_logos(struct fb_info *info, int y, int rotate)
unsigned int i; unsigned int i;
for (i = 0; i < fb_logo_ex_num; i++) for (i = 0; i < fb_logo_ex_num; i++)
y += fb_show_logo_line(info, rotate, y = fb_show_logo_line(info, rotate,
fb_logo_ex[i].logo, y, fb_logo_ex[i].n); fb_logo_ex[i].logo, y, fb_logo_ex[i].n);
return y; return y;
} }
@ -600,6 +621,7 @@ int fb_prepare_logo(struct fb_info *info, int rotate)
{ {
int depth = fb_get_color_depth(&info->var, &info->fix); int depth = fb_get_color_depth(&info->var, &info->fix);
unsigned int yres; unsigned int yres;
int height;
memset(&fb_logo, 0, sizeof(struct logo_data)); memset(&fb_logo, 0, sizeof(struct logo_data));
@ -661,7 +683,12 @@ int fb_prepare_logo(struct fb_info *info, int rotate)
} }
} }
return fb_prepare_extra_logos(info, fb_logo.logo->height, yres); height = fb_logo.logo->height;
#ifdef CONFIG_FB_LOGO_CENTER
height += (yres - fb_logo.logo->height) / 2;
#endif
return fb_prepare_extra_logos(info, height, yres);
} }
int fb_show_logo(struct fb_info *info, int rotate) int fb_show_logo(struct fb_info *info, int rotate)

View File

@ -60,7 +60,7 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
info->device = dev; info->device = dev;
info->fbcon_rotate_hint = -1; info->fbcon_rotate_hint = -1;
#ifdef CONFIG_FB_BACKLIGHT #if IS_ENABLED(CONFIG_FB_BACKLIGHT)
mutex_init(&info->bl_curve_mutex); mutex_init(&info->bl_curve_mutex);
#endif #endif
@ -429,7 +429,7 @@ static ssize_t show_fbstate(struct device *device,
return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state); return snprintf(buf, PAGE_SIZE, "%d\n", fb_info->state);
} }
#ifdef CONFIG_FB_BACKLIGHT #if IS_ENABLED(CONFIG_FB_BACKLIGHT)
static ssize_t store_bl_curve(struct device *device, static ssize_t store_bl_curve(struct device *device,
struct device_attribute *attr, struct device_attribute *attr,
const char *buf, size_t count) const char *buf, size_t count)
@ -510,7 +510,7 @@ static struct device_attribute device_attrs[] = {
__ATTR(stride, S_IRUGO, show_stride, NULL), __ATTR(stride, S_IRUGO, show_stride, NULL),
__ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate), __ATTR(rotate, S_IRUGO|S_IWUSR, show_rotate, store_rotate),
__ATTR(state, S_IRUGO|S_IWUSR, show_fbstate, store_fbstate), __ATTR(state, S_IRUGO|S_IWUSR, show_fbstate, store_fbstate),
#ifdef CONFIG_FB_BACKLIGHT #if IS_ENABLED(CONFIG_FB_BACKLIGHT)
__ATTR(bl_curve, S_IRUGO|S_IWUSR, show_bl_curve, store_bl_curve), __ATTR(bl_curve, S_IRUGO|S_IWUSR, show_bl_curve, store_bl_curve),
#endif #endif
}; };
@ -551,7 +551,7 @@ void fb_cleanup_device(struct fb_info *fb_info)
} }
} }
#ifdef CONFIG_FB_BACKLIGHT #if IS_ENABLED(CONFIG_FB_BACKLIGHT)
/* This function generates a linear backlight curve /* This function generates a linear backlight curve
* *
* 0: off * 0: off

View File

@ -1575,8 +1575,7 @@ static void uninstall_fb(struct fb_info *info)
unregister_framebuffer(info); unregister_framebuffer(info);
unmap_video_memory(info); unmap_video_memory(info);
if (&info->cmap) fb_dealloc_cmap(&info->cmap);
fb_dealloc_cmap(&info->cmap);
mfbi->registered = 0; mfbi->registered = 0;
} }

View File

@ -99,24 +99,14 @@ int dss_set_min_bus_tput(struct device *dev, unsigned long tput)
} }
#if defined(CONFIG_FB_OMAP2_DSS_DEBUGFS) #if defined(CONFIG_FB_OMAP2_DSS_DEBUGFS)
static int dss_debug_show(struct seq_file *s, void *unused) static int dss_show(struct seq_file *s, void *unused)
{ {
void (*func)(struct seq_file *) = s->private; void (*func)(struct seq_file *) = s->private;
func(s); func(s);
return 0; return 0;
} }
static int dss_debug_open(struct inode *inode, struct file *file) DEFINE_SHOW_ATTRIBUTE(dss);
{
return single_open(file, dss_debug_show, inode->i_private);
}
static const struct file_operations dss_debug_fops = {
.open = dss_debug_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static struct dentry *dss_debugfs_dir; static struct dentry *dss_debugfs_dir;
@ -130,7 +120,7 @@ static int dss_initialize_debugfs(void)
} }
debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
&dss_debug_dump_clocks, &dss_debug_fops); &dss_debug_dump_clocks, &dss_fops);
return 0; return 0;
} }
@ -145,7 +135,7 @@ int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
struct dentry *d; struct dentry *d;
d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir, d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir,
write, &dss_debug_fops); write, &dss_fops);
return PTR_ERR_OR_ZERO(d); return PTR_ERR_OR_ZERO(d);
} }

View File

@ -279,7 +279,7 @@ static void set_clock_divider(struct pxa168fb_info *fbi,
/* check whether divisor is too small. */ /* check whether divisor is too small. */
if (divider_int < 2) { if (divider_int < 2) {
dev_warn(fbi->dev, "Warning: clock source is too slow." dev_warn(fbi->dev, "Warning: clock source is too slow. "
"Try smaller resolution\n"); "Try smaller resolution\n");
divider_int = 2; divider_int = 2;
} }

View File

@ -2234,10 +2234,8 @@ static struct pxafb_mach_info *of_pxafb_of_mach_info(struct device *dev)
if (!info) if (!info)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
ret = of_get_pxafb_mode_info(dev, info); ret = of_get_pxafb_mode_info(dev, info);
if (ret) { if (ret)
kfree(info->modes);
return ERR_PTR(ret); return ERR_PTR(ret);
}
/* /*
* On purpose, neither lccrX registers nor video memory size can be * On purpose, neither lccrX registers nor video memory size can be

View File

@ -1598,7 +1598,7 @@ static int dlfb_usb_probe(struct usb_interface *intf,
dlfb = kzalloc(sizeof(*dlfb), GFP_KERNEL); dlfb = kzalloc(sizeof(*dlfb), GFP_KERNEL);
if (!dlfb) { if (!dlfb) {
dev_err(&intf->dev, "%s: failed to allocate dlfb\n", __func__); dev_err(&intf->dev, "%s: failed to allocate dlfb\n", __func__);
goto error; return -ENOMEM;
} }
INIT_LIST_HEAD(&dlfb->deferred_free); INIT_LIST_HEAD(&dlfb->deferred_free);
@ -1703,7 +1703,7 @@ static int dlfb_usb_probe(struct usb_interface *intf,
error: error:
if (dlfb->info) { if (dlfb->info) {
dlfb_ops_destroy(dlfb->info); dlfb_ops_destroy(dlfb->info);
} else if (dlfb) { } else {
usb_put_dev(dlfb->udev); usb_put_dev(dlfb->udev);
kfree(dlfb); kfree(dlfb);
} }
@ -1730,12 +1730,10 @@ static void dlfb_usb_disconnect(struct usb_interface *intf)
/* this function will wait for all in-flight urbs to complete */ /* this function will wait for all in-flight urbs to complete */
dlfb_free_urb_list(dlfb); dlfb_free_urb_list(dlfb);
if (info) { /* remove udlfb's sysfs interfaces */
/* remove udlfb's sysfs interfaces */ for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++)
for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) device_remove_file(info->dev, &fb_device_attrs[i]);
device_remove_file(info->dev, &fb_device_attrs[i]); device_remove_bin_file(info->dev, &edid_attr);
device_remove_bin_file(info->dev, &edid_attr);
}
unregister_framebuffer(info); unregister_framebuffer(info);
} }

View File

@ -1979,7 +1979,7 @@ MODULE_PARM_DESC(noedid,
module_param(vram_remap, uint, 0); module_param(vram_remap, uint, 0);
MODULE_PARM_DESC(vram_remap, "Set amount of video memory to be used [MiB]"); MODULE_PARM_DESC(vram_remap, "Set amount of video memory to be used [MiB]");
module_param(vram_total, uint, 0); module_param(vram_total, uint, 0);
MODULE_PARM_DESC(vram_total, "Set total amount of video memoery [MiB]"); MODULE_PARM_DESC(vram_total, "Set total amount of video memory [MiB]");
module_param(maxclk, ushort, 0); module_param(maxclk, ushort, 0);
MODULE_PARM_DESC(maxclk, "Maximum pixelclock [MHz], overrides EDID data"); MODULE_PARM_DESC(maxclk, "Maximum pixelclock [MHz], overrides EDID data");
module_param(maxhf, ushort, 0); module_param(maxhf, ushort, 0);

View File

@ -10,6 +10,15 @@ menuconfig LOGO
if LOGO if LOGO
config FB_LOGO_CENTER
bool "Center the logo"
depends on FB=y
help
When this option is selected, the bootup logo is centered both
horizontally and vertically. If more than one logo is displayed
due to multiple CPUs, the collected line of logos is centered
as a whole.
config FB_LOGO_EXTRA config FB_LOGO_EXTRA
bool bool
depends on FB=y depends on FB=y

View File

@ -485,7 +485,7 @@ struct fb_info {
struct list_head modelist; /* mode list */ struct list_head modelist; /* mode list */
struct fb_videomode *mode; /* current mode */ struct fb_videomode *mode; /* current mode */
#ifdef CONFIG_FB_BACKLIGHT #if IS_ENABLED(CONFIG_FB_BACKLIGHT)
/* assigned backlight device */ /* assigned backlight device */
/* set before framebuffer registration, /* set before framebuffer registration,
remove after unregister */ remove after unregister */

View File

@ -393,11 +393,9 @@ struct fb_cursor {
struct fb_image image; /* Cursor image */ struct fb_image image; /* Cursor image */
}; };
#ifdef CONFIG_FB_BACKLIGHT
/* Settings for the generic backlight code */ /* Settings for the generic backlight code */
#define FB_BACKLIGHT_LEVELS 128 #define FB_BACKLIGHT_LEVELS 128
#define FB_BACKLIGHT_MAX 0xFF #define FB_BACKLIGHT_MAX 0xFF
#endif
#endif /* _UAPI_LINUX_FB_H */ #endif /* _UAPI_LINUX_FB_H */