From 214b0dd591abfde8cbc5536cd0a6b996a659c23e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:32 +0200 Subject: dummycon: Sprinkle locking checks As part of trying to understand the locking (or lack thereof) in the fbcon/vt/fbdev maze, annotate everything. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Bartlomiej Zolnierkiewicz Cc: Hans de Goede Cc: Daniel Vetter Cc: Greg Kroah-Hartman Cc: Kees Cook Cc: Nicolas Pitre Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-2-daniel.vetter@ffwll.ch --- drivers/video/console/dummycon.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index ff886e99104b..2a0d0bda7faa 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -34,6 +34,8 @@ static bool dummycon_putc_called; void dummycon_register_output_notifier(struct notifier_block *nb) { + WARN_CONSOLE_UNLOCKED(); + raw_notifier_chain_register(&dummycon_output_nh, nb); if (dummycon_putc_called) @@ -42,11 +44,15 @@ void dummycon_register_output_notifier(struct notifier_block *nb) void dummycon_unregister_output_notifier(struct notifier_block *nb) { + WARN_CONSOLE_UNLOCKED(); + raw_notifier_chain_unregister(&dummycon_output_nh, nb); } static void dummycon_putc(struct vc_data *vc, int c, int ypos, int xpos) { + WARN_CONSOLE_UNLOCKED(); + dummycon_putc_called = true; raw_notifier_call_chain(&dummycon_output_nh, 0, NULL); } -- cgit From 7076404f7c8d3fc01e8cb8ea259c7552b2061ae0 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:33 +0200 Subject: fbdev: locking check for fb_set_suspend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Just drive-by, nothing systematic yet. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: "Michał Mirosław" Cc: Peter Rosin Cc: Hans de Goede Cc: Thomas Zimmermann Cc: Manfred Schlaegl Cc: Mikulas Patocka Cc: Kees Cook Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-3-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbmem.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index d1949c92be98..8ba674ffb3c9 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1985,6 +1985,8 @@ void fb_set_suspend(struct fb_info *info, int state) { struct fb_event event; + WARN_CONSOLE_UNLOCKED(); + event.info = info; if (state) { fb_notifier_call_chain(FB_EVENT_SUSPEND, &event); -- cgit From a135513c0b579be55c534b35e628be55578576b2 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:34 +0200 Subject: vt: might_sleep() annotation for do_blank_screen For symmetry reasons with do_unblank_screen, except without the oops_in_progress special case. Just a drive-by annotation while I'm trying to untangle the fbcon vs. fbdev screen blank/unblank maze. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Acked-by: Greg Kroah-Hartman Reviewed-by: Maarten Lankhorst Cc: Greg Kroah-Hartman Cc: Nicolas Pitre Cc: Adam Borowski Cc: Martin Hostettler Cc: Daniel Vetter Cc: Mikulas Patocka Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-4-daniel.vetter@ffwll.ch --- drivers/tty/vt/vt.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 5c0ca1c24b6f..30d29a04bfee 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -4166,6 +4166,8 @@ void do_blank_screen(int entering_gfx) struct vc_data *vc = vc_cons[fg_console].d; int i; + might_sleep(); + WARN_CONSOLE_UNLOCKED(); if (console_blanked) { -- cgit From ddde3c18b70061cc09b84a52624909349c212822 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:35 +0200 Subject: vt: More locking checks I honestly have no idea what the subtle differences between con_is_visible, con_is_fg (internal to vt.c) and con_is_bound are. But it looks like both vc->vc_display_fg and con_driver_map are protected by the console_lock, so probably better if we hold that when checking this. To do that I had to deinline the con_is_visible function. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Acked-by: Greg Kroah-Hartman Reviewed-by: Maarten Lankhorst Cc: Greg Kroah-Hartman Cc: Nicolas Pitre Cc: Martin Hostettler Cc: Adam Borowski Cc: Daniel Vetter Cc: Mikulas Patocka Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-5-daniel.vetter@ffwll.ch --- drivers/tty/vt/vt.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 30d29a04bfee..ec92f36ab5c4 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -3822,6 +3822,8 @@ int con_is_bound(const struct consw *csw) { int i, bound = 0; + WARN_CONSOLE_UNLOCKED(); + for (i = 0; i < MAX_NR_CONSOLES; i++) { if (con_driver_map[i] == csw) { bound = 1; @@ -3833,6 +3835,20 @@ int con_is_bound(const struct consw *csw) } EXPORT_SYMBOL(con_is_bound); +/** + * con_is_visible - checks whether the current console is visible + * @vc: virtual console + * + * RETURNS: zero if not visible, nonzero if visible + */ +bool con_is_visible(const struct vc_data *vc) +{ + WARN_CONSOLE_UNLOCKED(); + + return *vc->vc_display_fg == vc; +} +EXPORT_SYMBOL(con_is_visible); + /** * con_debug_enter - prepare the console for the kernel debugger * @sw: console driver -- cgit From 390e5de11284a1615662a2773c73b71884310dbe Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:36 +0200 Subject: fbdev/sa1100fb: Remove dead code Motivated because it contains a struct display, which is a fbcon internal data structure that I want to rename. It seems to have been formerly used in drivers, but that's very long time ago. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-6-daniel.vetter@ffwll.ch --- drivers/video/fbdev/sa1100fb.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c index 15ae50063296..f7f8dee044b1 100644 --- a/drivers/video/fbdev/sa1100fb.c +++ b/drivers/video/fbdev/sa1100fb.c @@ -974,35 +974,10 @@ static void sa1100fb_task(struct work_struct *w) */ static unsigned int sa1100fb_min_dma_period(struct sa1100fb_info *fbi) { -#if 0 - unsigned int min_period = (unsigned int)-1; - int i; - - for (i = 0; i < MAX_NR_CONSOLES; i++) { - struct display *disp = &fb_display[i]; - unsigned int period; - - /* - * Do we own this display? - */ - if (disp->fb_info != &fbi->fb) - continue; - - /* - * Ok, calculate its DMA period - */ - period = sa1100fb_display_dma_period(&disp->var); - if (period < min_period) - min_period = period; - } - - return min_period; -#else /* * FIXME: we need to verify _all_ consoles. */ return sa1100fb_display_dma_period(&fbi->fb.var); -#endif } /* -- cgit From 561f1f6e023bd548f1d24f80502eb6c075f2a467 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:37 +0200 Subject: fbdev/cyber2000: Remove struct display Entirely unused. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Russell King Cc: linux-arm-kernel@lists.infradead.org Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-7-daniel.vetter@ffwll.ch --- drivers/video/fbdev/cyber2000fb.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c index 9a5751cb4e16..452ef07b3a06 100644 --- a/drivers/video/fbdev/cyber2000fb.c +++ b/drivers/video/fbdev/cyber2000fb.c @@ -61,7 +61,6 @@ struct cfb_info { struct fb_info fb; struct display_switch *dispsw; - struct display *display; unsigned char __iomem *region; unsigned char __iomem *regs; u_int id; -- cgit From 127cd8d33ec75637a29fec75b14605e6b1b871a4 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:38 +0200 Subject: fbdev/aty128fb: Remove dead code Motivated because it contains a struct display, which is a fbcon internal data structure that I want to rename. It seems to have been formerly used in drivers, but that's very long time ago. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Paul Mackerras Cc: linux-fbdev@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-8-daniel.vetter@ffwll.ch --- drivers/video/fbdev/aty/aty128fb.c | 64 -------------------------------------- 1 file changed, 64 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c index 794434891291..b02e67528a99 100644 --- a/drivers/video/fbdev/aty/aty128fb.c +++ b/drivers/video/fbdev/aty/aty128fb.c @@ -2350,70 +2350,6 @@ static int aty128fb_ioctl(struct fb_info *info, u_int cmd, u_long arg) return -EINVAL; } -#if 0 - /* - * Accelerated functions - */ - -static inline void aty128_rectcopy(int srcx, int srcy, int dstx, int dsty, - u_int width, u_int height, - struct fb_info_aty128 *par) -{ - u32 save_dp_datatype, save_dp_cntl, dstval; - - if (!width || !height) - return; - - dstval = depth_to_dst(par->current_par.crtc.depth); - if (dstval == DST_24BPP) { - srcx *= 3; - dstx *= 3; - width *= 3; - } else if (dstval == -EINVAL) { - printk("aty128fb: invalid depth or RGBA\n"); - return; - } - - wait_for_fifo(2, par); - save_dp_datatype = aty_ld_le32(DP_DATATYPE); - save_dp_cntl = aty_ld_le32(DP_CNTL); - - wait_for_fifo(6, par); - aty_st_le32(SRC_Y_X, (srcy << 16) | srcx); - aty_st_le32(DP_MIX, ROP3_SRCCOPY | DP_SRC_RECT); - aty_st_le32(DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); - aty_st_le32(DP_DATATYPE, save_dp_datatype | dstval | SRC_DSTCOLOR); - - aty_st_le32(DST_Y_X, (dsty << 16) | dstx); - aty_st_le32(DST_HEIGHT_WIDTH, (height << 16) | width); - - par->blitter_may_be_busy = 1; - - wait_for_fifo(2, par); - aty_st_le32(DP_DATATYPE, save_dp_datatype); - aty_st_le32(DP_CNTL, save_dp_cntl); -} - - - /* - * Text mode accelerated functions - */ - -static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, - int dx, int height, int width) -{ - sx *= fontwidth(p); - sy *= fontheight(p); - dx *= fontwidth(p); - dy *= fontheight(p); - width *= fontwidth(p); - height *= fontheight(p); - - aty128_rectcopy(sx, sy, dx, dy, width, height, - (struct fb_info_aty128 *)p->fb_info); -} -#endif /* 0 */ - static void aty128_set_suspend(struct aty128fb_par *par, int suspend) { u32 pmgt; -- cgit From 50233393f0cf9babe1361ed5afe86fcabb32f648 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:39 +0200 Subject: fbcon: s/struct display/struct fbcon_display/ This was formerly used in fbdev drivers (not sure why, predates most git history), but now it's entirely an fbcon internal thing. Give it a more specific name. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: Hans de Goede Cc: Greg Kroah-Hartman Cc: Kees Cook Cc: Prarit Bhargava Cc: Konstantin Khorenko Cc: Peter Rosin Cc: Yisheng Xie Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-9-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbcon.c | 74 ++++++++++++++++++++-------------------- drivers/video/fbdev/core/fbcon.h | 6 ++-- 2 files changed, 40 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index a9c69ae30878..b4465cf55cdc 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -93,7 +93,7 @@ enum { FBCON_LOGO_DONTSHOW = -3 /* do not show the logo */ }; -static struct display fb_display[MAX_NR_CONSOLES]; +static struct fbcon_display fb_display[MAX_NR_CONSOLES]; static signed char con2fb_map[MAX_NR_CONSOLES]; static signed char con2fb_map_boot[MAX_NR_CONSOLES]; @@ -185,11 +185,11 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count); static __inline__ void ywrap_down(struct vc_data *vc, int count); static __inline__ void ypan_up(struct vc_data *vc, int count); static __inline__ void ypan_down(struct vc_data *vc, int count); -static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, +static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx, int dy, int dx, int height, int width, u_int y_break); static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, int unit); -static void fbcon_redraw_move(struct vc_data *vc, struct display *p, +static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p, int line, int count, int dy); static void fbcon_modechanged(struct fb_info *info); static void fbcon_set_all_vcs(struct fb_info *info); @@ -220,7 +220,7 @@ static void fbcon_rotate(struct fb_info *info, u32 rotate) fb_info = registered_fb[con2fb_map[ops->currcon]]; if (info == fb_info) { - struct display *p = &fb_display[ops->currcon]; + struct fbcon_display *p = &fb_display[ops->currcon]; if (rotate < 4) p->con_rotate = rotate; @@ -235,7 +235,7 @@ static void fbcon_rotate_all(struct fb_info *info, u32 rotate) { struct fbcon_ops *ops = info->fbcon_par; struct vc_data *vc; - struct display *p; + struct fbcon_display *p; int i; if (!ops || ops->currcon < 0 || rotate > 3) @@ -900,7 +900,7 @@ static int set_con2fb_map(int unit, int newidx, int user) * Low Level Operations */ /* NOTE: fbcon cannot be __init: it may be called from do_take_over_console later */ -static int var_to_display(struct display *disp, +static int var_to_display(struct fbcon_display *disp, struct fb_var_screeninfo *var, struct fb_info *info) { @@ -925,7 +925,7 @@ static int var_to_display(struct display *disp, } static void display_to_var(struct fb_var_screeninfo *var, - struct display *disp) + struct fbcon_display *disp) { fb_videomode_to_var(var, disp->mode); var->xres_virtual = disp->xres_virtual; @@ -946,7 +946,7 @@ static void display_to_var(struct fb_var_screeninfo *var, static const char *fbcon_startup(void) { const char *display_desc = "frame buffer device"; - struct display *p = &fb_display[fg_console]; + struct fbcon_display *p = &fb_display[fg_console]; struct vc_data *vc = vc_cons[fg_console].d; const struct font_desc *font = NULL; struct module *owner; @@ -1060,7 +1060,7 @@ static void fbcon_init(struct vc_data *vc, int init) struct fbcon_ops *ops; struct vc_data **default_mode = vc->vc_display_fg; struct vc_data *svc = *default_mode; - struct display *t, *p = &fb_display[vc->vc_num]; + struct fbcon_display *t, *p = &fb_display[vc->vc_num]; int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; int cap, ret; @@ -1203,7 +1203,7 @@ static void fbcon_init(struct vc_data *vc, int init) ops->p = &fb_display[fg_console]; } -static void fbcon_free_font(struct display *p, bool freefont) +static void fbcon_free_font(struct fbcon_display *p, bool freefont) { if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); @@ -1215,7 +1215,7 @@ static void set_vc_hi_font(struct vc_data *vc, bool set); static void fbcon_deinit(struct vc_data *vc) { - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; struct fb_info *info; struct fbcon_ops *ops; int idx; @@ -1288,7 +1288,7 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; u_int y_break; if (fbcon_is_inactive(vc, info)) @@ -1324,7 +1324,7 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, int count, int ypos, int xpos) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; struct fbcon_ops *ops = info->fbcon_par; if (!fbcon_is_inactive(vc, info)) @@ -1388,7 +1388,7 @@ static int scrollback_current = 0; static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, int unit) { - struct display *p, *t; + struct fbcon_display *p, *t; struct vc_data **default_mode, *vc; struct vc_data *svc; struct fbcon_ops *ops = info->fbcon_par; @@ -1457,7 +1457,7 @@ static __inline__ void ywrap_up(struct vc_data *vc, int count) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; p->yscroll += count; if (p->yscroll >= p->vrows) /* Deal with wrap */ @@ -1476,7 +1476,7 @@ static __inline__ void ywrap_down(struct vc_data *vc, int count) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; p->yscroll -= count; if (p->yscroll < 0) /* Deal with wrap */ @@ -1494,7 +1494,7 @@ static __inline__ void ywrap_down(struct vc_data *vc, int count) static __inline__ void ypan_up(struct vc_data *vc, int count) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; struct fbcon_ops *ops = info->fbcon_par; p->yscroll += count; @@ -1519,7 +1519,7 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; p->yscroll += count; @@ -1542,7 +1542,7 @@ static __inline__ void ypan_up_redraw(struct vc_data *vc, int t, int count) static __inline__ void ypan_down(struct vc_data *vc, int count) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; struct fbcon_ops *ops = info->fbcon_par; p->yscroll -= count; @@ -1567,7 +1567,7 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; p->yscroll -= count; @@ -1587,7 +1587,7 @@ static __inline__ void ypan_down_redraw(struct vc_data *vc, int t, int count) scrollback_current = 0; } -static void fbcon_redraw_softback(struct vc_data *vc, struct display *p, +static void fbcon_redraw_softback(struct vc_data *vc, struct fbcon_display *p, long delta) { int count = vc->vc_rows; @@ -1680,7 +1680,7 @@ static void fbcon_redraw_softback(struct vc_data *vc, struct display *p, } } -static void fbcon_redraw_move(struct vc_data *vc, struct display *p, +static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p, int line, int count, int dy) { unsigned short *s = (unsigned short *) @@ -1715,7 +1715,7 @@ static void fbcon_redraw_move(struct vc_data *vc, struct display *p, } static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info, - struct display *p, int line, int count, int ycount) + struct fbcon_display *p, int line, int count, int ycount) { int offset = ycount * vc->vc_cols; unsigned short *d = (unsigned short *) @@ -1764,7 +1764,7 @@ static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info, } } -static void fbcon_redraw(struct vc_data *vc, struct display *p, +static void fbcon_redraw(struct vc_data *vc, struct fbcon_display *p, int line, int count, int offset) { unsigned short *d = (unsigned short *) @@ -1848,7 +1848,7 @@ static bool fbcon_scroll(struct vc_data *vc, unsigned int t, unsigned int b, enum con_scroll dir, unsigned int count) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK; if (fbcon_is_inactive(vc, info)) @@ -2052,7 +2052,7 @@ static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, int height, int width) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; if (fbcon_is_inactive(vc, info)) return; @@ -2071,7 +2071,7 @@ static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, p->vrows - p->yscroll); } -static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, +static void fbcon_bmove_rec(struct vc_data *vc, struct fbcon_display *p, int sy, int sx, int dy, int dx, int height, int width, u_int y_break) { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; @@ -2113,7 +2113,7 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s height, width); } -static void updatescrollmode(struct display *p, +static void updatescrollmode(struct fbcon_display *p, struct fb_info *info, struct vc_data *vc) { @@ -2165,7 +2165,7 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width, { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; struct fb_var_screeninfo var = info->var; int x_diff, y_diff, virt_w, virt_h, virt_fw, virt_fh; @@ -2210,7 +2210,7 @@ static int fbcon_switch(struct vc_data *vc) { struct fb_info *info, *old_info = NULL; struct fbcon_ops *ops; - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; struct fb_var_screeninfo var; int i, ret, prev_console, charcnt = 256; @@ -2553,7 +2553,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; - struct display *p = &fb_display[vc->vc_num]; + struct fbcon_display *p = &fb_display[vc->vc_num]; int resize; int cnt; char *old_data = NULL; @@ -2601,7 +2601,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, static int fbcon_copy_font(struct vc_data *vc, int con) { - struct display *od = &fb_display[con]; + struct fbcon_display *od = &fb_display[con]; struct console_font *f = &vc->vc_font; if (od->fontdata == f->data) @@ -2826,7 +2826,7 @@ static void fbcon_scrolldelta(struct vc_data *vc, int lines) { struct fb_info *info = registered_fb[con2fb_map[fg_console]]; struct fbcon_ops *ops = info->fbcon_par; - struct display *disp = &fb_display[fg_console]; + struct fbcon_display *disp = &fb_display[fg_console]; int offset, limit, scrollback_old; if (softback_top) { @@ -2947,7 +2947,7 @@ static void fbcon_modechanged(struct fb_info *info) { struct fbcon_ops *ops = info->fbcon_par; struct vc_data *vc; - struct display *p; + struct fbcon_display *p; int rows, cols; if (!ops || ops->currcon < 0) @@ -2987,7 +2987,7 @@ static void fbcon_set_all_vcs(struct fb_info *info) { struct fbcon_ops *ops = info->fbcon_par; struct vc_data *vc; - struct display *p; + struct fbcon_display *p; int i, rows, cols, fg = -1; if (!ops || ops->currcon < 0) @@ -3022,7 +3022,7 @@ static int fbcon_mode_deleted(struct fb_info *info, struct fb_videomode *mode) { struct fb_info *fb_info; - struct display *p; + struct fbcon_display *p; int i, j, found = 0; /* before deletion, ensure that mode is not in use */ @@ -3294,7 +3294,7 @@ static void fbcon_get_requirement(struct fb_info *info, struct fb_blit_caps *caps) { struct vc_data *vc; - struct display *p; + struct fbcon_display *p; if (caps->flags) { int i, charcnt; diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h index 21912a3ba32f..20dea853765f 100644 --- a/drivers/video/fbdev/core/fbcon.h +++ b/drivers/video/fbdev/core/fbcon.h @@ -25,7 +25,7 @@ * low-level frame buffer device */ -struct display { +struct fbcon_display { /* Filled in by the low-level console driver */ const u_char *fontdata; int userfont; /* != 0 if fontdata kmalloc()ed */ @@ -68,7 +68,7 @@ struct fbcon_ops { struct fb_var_screeninfo var; /* copy of the current fb_var_screeninfo */ struct timer_list cursor_timer; /* Cursor timer */ struct fb_cursor cursor_state; - struct display *p; + struct fbcon_display *p; struct fb_info *info; int currcon; /* Current VC. */ int cur_blink_jiffies; @@ -225,7 +225,7 @@ extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor); #define FBCON_ATTRIBUTE_REVERSE 2 #define FBCON_ATTRIBUTE_BOLD 4 -static inline int real_y(struct display *p, int ypos) +static inline int real_y(struct fbcon_display *p, int ypos) { int rows = p->vrows; -- cgit From 1f4ed2fb01f80faa722f71efd3791e1d1f337010 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:40 +0200 Subject: fbcon: Remove fbcon_has_exited MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is unused code since commit 6104c37094e729f3d4ce65797002112735d49cd1 Author: Daniel Vetter Date: Tue Aug 1 17:32:07 2017 +0200 fbcon: Make fbcon a built-time depency for fbdev when fbcon was made a compile-time static dependency of fbdev. We can't exit fbcon anymore without exiting fbdev first, which only works if all fbdev drivers have unloaded already. Hence this is all dead code. v2: I missed that fbcon_exit is also called from con_deinit stuff, and there fbcon_has_exited prevents double-cleanup. But we can fix that by properly resetting con2fb_map[] to all -1, which is used everywhere else to indicate "no fb_info allocate to this console". With that change the double-cleanup (which resulted in a module refcount underflow, among other things) is prevented. Aside: con2fb_map is a signed char, so don't register more than 128 fb_info or hilarity will ensue. v3: CI showed me that I still didn't fully understand what's going on here. The leaked references in con2fb_map have been used upon rebinding the fb console in fbcon_init. It worked because fbdev unregistering still cleaned out con2fb_map, and reset it to info_idx. If the last fbdev driver unregistered, then it also reset info_idx, and unregistered the fbcon driver. Imo that's all a bit fragile, so let's keep the con2fb_map reset to -1, and in fbcon_init pick info_idx if we're starting fresh. That means unbinding and rebinding will cleanse the mapping, but why are you doing that if you want to retain the mapping, so should be fine. Also, I think info_idx == -1 is impossible in fbcon_init - we unregister the fbcon in that case. So catch&warn about that. v4: Drop unecessary assignment - I forgot to delete the first assignment of info in fbcon_init. Cc: Sam Ravnborg Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Signed-off-by: Daniel Vetter Cc: Maarten Lankhorst Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: Hans de Goede Cc: "Noralf Trønnes" Cc: Yisheng Xie Cc: Konstantin Khorenko Cc: Prarit Bhargava Cc: Kees Cook Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-10-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbcon.c | 41 +++++++--------------------------------- 1 file changed, 7 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index b4465cf55cdc..9c14eab77d99 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -112,7 +112,6 @@ static int softback_lines; static int first_fb_vc; static int last_fb_vc = MAX_NR_CONSOLES - 1; static int fbcon_is_default = 1; -static int fbcon_has_exited; static int primary_device = -1; static int fbcon_has_console_bind; @@ -1050,13 +1049,12 @@ static const char *fbcon_startup(void) info->var.bits_per_pixel); fbcon_add_cursor_timer(info); - fbcon_has_exited = 0; return display_desc; } static void fbcon_init(struct vc_data *vc, int init) { - struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; + struct fb_info *info; struct fbcon_ops *ops; struct vc_data **default_mode = vc->vc_display_fg; struct vc_data *svc = *default_mode; @@ -1064,9 +1062,13 @@ static void fbcon_init(struct vc_data *vc, int init) int logo = 1, new_rows, new_cols, rows, cols, charcnt = 256; int cap, ret; - if (info_idx == -1 || info == NULL) + if (WARN_ON(info_idx == -1)) return; + if (con2fb_map[vc->vc_num] == -1) + con2fb_map[vc->vc_num] = info_idx; + + info = registered_fb[con2fb_map[vc->vc_num]]; cap = info->flags; if (logo_shown < 0 && console_loglevel <= CONSOLE_LOGLEVEL_QUIET) @@ -3336,14 +3338,6 @@ static int fbcon_event_notify(struct notifier_block *self, struct fb_blit_caps *caps; int idx, ret = 0; - /* - * ignore all events except driver registration and deregistration - * if fbcon is not active - */ - if (fbcon_has_exited && !(action == FB_EVENT_FB_REGISTERED || - action == FB_EVENT_FB_UNREGISTERED)) - goto done; - switch(action) { case FB_EVENT_SUSPEND: fbcon_suspended(info); @@ -3396,7 +3390,6 @@ static int fbcon_event_notify(struct notifier_block *self, fbcon_remap_all(idx); break; } -done: return ret; } @@ -3443,9 +3436,6 @@ static ssize_t store_rotate(struct device *device, int rotate, idx; char **last = NULL; - if (fbcon_has_exited) - return count; - console_lock(); idx = con2fb_map[fg_console]; @@ -3468,9 +3458,6 @@ static ssize_t store_rotate_all(struct device *device, int rotate, idx; char **last = NULL; - if (fbcon_has_exited) - return count; - console_lock(); idx = con2fb_map[fg_console]; @@ -3491,9 +3478,6 @@ static ssize_t show_rotate(struct device *device, struct fb_info *info; int rotate = 0, idx; - if (fbcon_has_exited) - return 0; - console_lock(); idx = con2fb_map[fg_console]; @@ -3514,9 +3498,6 @@ static ssize_t show_cursor_blink(struct device *device, struct fbcon_ops *ops; int idx, blink = -1; - if (fbcon_has_exited) - return 0; - console_lock(); idx = con2fb_map[fg_console]; @@ -3543,9 +3524,6 @@ static ssize_t store_cursor_blink(struct device *device, int blink, idx; char **last = NULL; - if (fbcon_has_exited) - return count; - console_lock(); idx = con2fb_map[fg_console]; @@ -3668,9 +3646,6 @@ static void fbcon_exit(void) struct fb_info *info; int i, j, mapped; - if (fbcon_has_exited) - return; - #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER if (deferred_takeover) { dummycon_unregister_output_notifier(&fbcon_output_nb); @@ -3695,7 +3670,7 @@ static void fbcon_exit(void) for (j = first_fb_vc; j <= last_fb_vc; j++) { if (con2fb_map[j] == i) { mapped = 1; - break; + con2fb_map[j] = -1; } } @@ -3718,8 +3693,6 @@ static void fbcon_exit(void) info->queue.func = NULL; } } - - fbcon_has_exited = 1; } void __init fb_console_init(void) -- cgit From 97b67986f1451c772b488d597310f95c14547cce Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:41 +0200 Subject: fbcon: call fbcon_fb_(un)registered directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With commit 6104c37094e729f3d4ce65797002112735d49cd1 Author: Daniel Vetter Date: Tue Aug 1 17:32:07 2017 +0200 fbcon: Make fbcon a built-time depency for fbdev we have a static dependency between fbcon and fbdev, and we can replace the indirection through the notifier chain with a function call. v2: Sam Ravnborg noticed that mach-pxa/am200epd.c has a notifier too, and listens to this. ... Looking at the code it seems to wait for some fb to show up, so that it can get the framebuffer base address from the fb_info struct. I suspect his is some firmware fbdev. Then it uses that information to let the real fbdev driver (metronomefb.c by the looks) get at the framebuffer memory. This doesn't looke like it's easy to fix (except by deleting the entire thing, seems untouched since 2008, we might be able to get away with that), so let's just stuff a few #ifdef into fb.h and fbmem.c and cry over them for a bit. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: Hans de Goede Cc: Greg Kroah-Hartman Cc: "Noralf Trønnes" Cc: Yisheng Xie Cc: Peter Rosin Cc: "Michał Mirosław" Cc: Thomas Zimmermann Cc: Mikulas Patocka Cc: linux-fbdev@vger.kernel.org Cc: Daniel Mack Cc: Haojian Zhuang Cc: Robert Jarzmik Cc: Konstantin Khorenko Cc: Prarit Bhargava Cc: Gerd Hoffmann Cc: Steve Sakoman Cc: Steve Sakoman Cc: linux-arm-kernel@lists.infradead.org Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-11-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbcon.c | 14 +++----------- drivers/video/fbdev/core/fbmem.c | 24 +++++++++++++++++------- 2 files changed, 20 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 9c14eab77d99..c12fc98035e0 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -3119,14 +3119,14 @@ static int fbcon_fb_unbind(int idx) } /* called with console_lock held */ -static int fbcon_fb_unregistered(struct fb_info *info) +void fbcon_fb_unregistered(struct fb_info *info) { int i, idx; WARN_CONSOLE_UNLOCKED(); if (deferred_takeover) - return 0; + return; idx = info->node; for (i = first_fb_vc; i <= last_fb_vc; i++) { @@ -3155,8 +3155,6 @@ static int fbcon_fb_unregistered(struct fb_info *info) if (!num_registered_fb) do_unregister_con_driver(&fb_con); - - return 0; } /* called with console_lock held */ @@ -3215,7 +3213,7 @@ static inline void fbcon_select_primary(struct fb_info *info) #endif /* CONFIG_FRAMEBUFFER_DETECT_PRIMARY */ /* called with console_lock held */ -static int fbcon_fb_registered(struct fb_info *info) +int fbcon_fb_registered(struct fb_info *info) { int ret = 0, i, idx; @@ -3359,12 +3357,6 @@ static int fbcon_event_notify(struct notifier_block *self, idx = info->node; ret = fbcon_fb_unbind(idx); break; - case FB_EVENT_FB_REGISTERED: - ret = fbcon_fb_registered(info); - break; - case FB_EVENT_FB_UNREGISTERED: - ret = fbcon_fb_unregistered(info); - break; case FB_EVENT_SET_CONSOLE_MAP: /* called with console lock held */ con2fb = event->data; diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 8ba674ffb3c9..bed7698ad18a 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1660,7 +1660,6 @@ MODULE_PARM_DESC(lockless_register_fb, static int do_register_framebuffer(struct fb_info *fb_info) { int i, ret; - struct fb_event event; struct fb_videomode mode; if (fb_check_foreignness(fb_info)) @@ -1723,7 +1722,14 @@ static int do_register_framebuffer(struct fb_info *fb_info) fb_add_videomode(&mode, &fb_info->modelist); registered_fb[i] = fb_info; - event.info = fb_info; +#ifdef CONFIG_GUMSTIX_AM200EPD + { + struct fb_event event; + event.info = fb_info; + fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); + } +#endif + if (!lockless_register_fb) console_lock(); else @@ -1732,9 +1738,8 @@ static int do_register_framebuffer(struct fb_info *fb_info) ret = -ENODEV; goto unlock_console; } - ret = 0; - fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); + ret = fbcon_fb_registered(fb_info); unlock_fb_info(fb_info); unlock_console: if (!lockless_register_fb) @@ -1771,7 +1776,6 @@ static int __unlink_framebuffer(struct fb_info *fb_info); static int do_unregister_framebuffer(struct fb_info *fb_info) { - struct fb_event event; int ret; ret = unbind_console(fb_info); @@ -1789,9 +1793,15 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) registered_fb[fb_info->node] = NULL; num_registered_fb--; fb_cleanup_device(fb_info); - event.info = fb_info; +#ifdef CONFIG_GUMSTIX_AM200EPD + { + struct fb_event event; + event.info = fb_info; + fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); + } +#endif console_lock(); - fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); + fbcon_fb_unregistered(fb_info); console_unlock(); /* this may free fb info */ -- cgit From 0fe66f327c464943a969ac3ad5f7a07a7cd4674e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:42 +0200 Subject: fbdev/sh_mobile: remove sh_mobile_lcdc_display_notify It's dead code, and removing it avoids me having to understand what it's doing with lock_fb_info. v2: Also remove sh_mobile_lcdc_must_reconfigure, now unused (Sam). Signed-off-by: Daniel Vetter Reviewed-by: Geert Uytterhoeven (v1) Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Geert Uytterhoeven Cc: Daniel Vetter Cc: Sam Ravnborg Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-12-daniel.vetter@ffwll.ch --- drivers/video/fbdev/sh_mobile_lcdcfb.c | 82 ---------------------------------- drivers/video/fbdev/sh_mobile_lcdcfb.h | 5 --- 2 files changed, 87 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c index dc46be38c970..1437695415c9 100644 --- a/drivers/video/fbdev/sh_mobile_lcdcfb.c +++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c @@ -534,89 +534,9 @@ static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch) ch->tx_dev->ops->display_off(ch->tx_dev); } -static bool -sh_mobile_lcdc_must_reconfigure(struct sh_mobile_lcdc_chan *ch, - const struct fb_videomode *new_mode) -{ - dev_dbg(ch->info->dev, "Old %ux%u, new %ux%u\n", - ch->display.mode.xres, ch->display.mode.yres, - new_mode->xres, new_mode->yres); - - /* It can be a different monitor with an equal video-mode */ - if (fb_mode_is_equal(&ch->display.mode, new_mode)) - return false; - - dev_dbg(ch->info->dev, "Switching %u -> %u lines\n", - ch->display.mode.yres, new_mode->yres); - ch->display.mode = *new_mode; - - return true; -} - static int sh_mobile_lcdc_check_var(struct fb_var_screeninfo *var, struct fb_info *info); -static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch, - enum sh_mobile_lcdc_entity_event event, - const struct fb_videomode *mode, - const struct fb_monspecs *monspec) -{ - struct fb_info *info = ch->info; - struct fb_var_screeninfo var; - int ret = 0; - - switch (event) { - case SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT: - /* HDMI plug in */ - console_lock(); - if (lock_fb_info(info)) { - - - ch->display.width = monspec->max_x * 10; - ch->display.height = monspec->max_y * 10; - - if (!sh_mobile_lcdc_must_reconfigure(ch, mode) && - info->state == FBINFO_STATE_RUNNING) { - /* First activation with the default monitor. - * Just turn on, if we run a resume here, the - * logo disappears. - */ - info->var.width = ch->display.width; - info->var.height = ch->display.height; - sh_mobile_lcdc_display_on(ch); - } else { - /* New monitor or have to wake up */ - fb_set_suspend(info, 0); - } - - - unlock_fb_info(info); - } - console_unlock(); - break; - - case SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT: - /* HDMI disconnect */ - console_lock(); - if (lock_fb_info(info)) { - fb_set_suspend(info, 1); - unlock_fb_info(info); - } - console_unlock(); - break; - - case SH_MOBILE_LCDC_EVENT_DISPLAY_MODE: - /* Validate a proposed new mode */ - fb_videomode_to_var(&var, mode); - var.bits_per_pixel = info->var.bits_per_pixel; - var.grayscale = info->var.grayscale; - ret = sh_mobile_lcdc_check_var(&var, info); - break; - } - - return ret; -} - /* ----------------------------------------------------------------------------- * Format helpers */ @@ -2540,8 +2460,6 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch) unsigned int max_size; unsigned int i; - ch->notify = sh_mobile_lcdc_display_notify; - /* Validate the format. */ format = sh_mobile_format_info(cfg->fourcc); if (format == NULL) { diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.h b/drivers/video/fbdev/sh_mobile_lcdcfb.h index b8e47a8bd8ab..589400372098 100644 --- a/drivers/video/fbdev/sh_mobile_lcdcfb.h +++ b/drivers/video/fbdev/sh_mobile_lcdcfb.h @@ -87,11 +87,6 @@ struct sh_mobile_lcdc_chan { unsigned long base_addr_c; unsigned int line_size; - int (*notify)(struct sh_mobile_lcdc_chan *ch, - enum sh_mobile_lcdc_entity_event event, - const struct fb_videomode *mode, - const struct fb_monspecs *monspec); - /* Backlight */ struct backlight_device *bl; unsigned int bl_brightness; -- cgit From 1e16eaebe2ea777a19b13cd1916992b544874d42 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:43 +0200 Subject: fbdev/omap: sysfs files can't disappear before the device is gone Which means lock_fb_info can never fail. Remove the error handling. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-13-daniel.vetter@ffwll.ch --- drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c index 8087a009c54f..bd0d20283372 100644 --- a/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c @@ -60,8 +60,7 @@ static ssize_t store_rotate_type(struct device *dev, if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB) return -EINVAL; - if (!lock_fb_info(fbi)) - return -ENODEV; + lock_fb_info(fbi); r = 0; if (rot_type == ofbi->rotation_type) @@ -112,8 +111,7 @@ static ssize_t store_mirror(struct device *dev, if (r) return r; - if (!lock_fb_info(fbi)) - return -ENODEV; + lock_fb_info(fbi); ofbi->mirror = mirror; @@ -149,8 +147,7 @@ static ssize_t show_overlays(struct device *dev, ssize_t l = 0; int t; - if (!lock_fb_info(fbi)) - return -ENODEV; + lock_fb_info(fbi); omapfb_lock(fbdev); for (t = 0; t < ofbi->num_overlays; t++) { @@ -208,8 +205,7 @@ static ssize_t store_overlays(struct device *dev, struct device_attribute *attr, if (buf[len - 1] == '\n') len = len - 1; - if (!lock_fb_info(fbi)) - return -ENODEV; + lock_fb_info(fbi); omapfb_lock(fbdev); if (len > 0) { @@ -340,8 +336,7 @@ static ssize_t show_overlays_rotate(struct device *dev, ssize_t l = 0; int t; - if (!lock_fb_info(fbi)) - return -ENODEV; + lock_fb_info(fbi); for (t = 0; t < ofbi->num_overlays; t++) { l += snprintf(buf + l, PAGE_SIZE - l, "%s%d", @@ -369,8 +364,7 @@ static ssize_t store_overlays_rotate(struct device *dev, if (buf[len - 1] == '\n') len = len - 1; - if (!lock_fb_info(fbi)) - return -ENODEV; + lock_fb_info(fbi); if (len > 0) { char *p = (char *)buf; @@ -453,8 +447,7 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr, size = PAGE_ALIGN(size); - if (!lock_fb_info(fbi)) - return -ENODEV; + lock_fb_info(fbi); if (display && display->driver->sync) display->driver->sync(display); -- cgit From 34f31f14c477f3c27e0fa0899db1bb6648cf53ca Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:44 +0200 Subject: fbdev: sysfs files can't disappear before the device is gone Which means lock_fb_info can never fail. Remove the error handling. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Daniel Vetter Cc: Bartlomiej Zolnierkiewicz Cc: Rob Clark Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-14-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbsysfs.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c index 954ed99e80da..f80d5b3a7797 100644 --- a/drivers/video/fbdev/core/fbsysfs.c +++ b/drivers/video/fbdev/core/fbsysfs.c @@ -175,10 +175,7 @@ static ssize_t store_modes(struct device *device, return -EINVAL; console_lock(); - if (!lock_fb_info(fb_info)) { - console_unlock(); - return -ENODEV; - } + lock_fb_info(fb_info); list_splice(&fb_info->modelist, &old_list); fb_videomode_to_modelist((const struct fb_videomode *)buf, i, @@ -405,10 +402,7 @@ static ssize_t store_fbstate(struct device *device, state = simple_strtoul(buf, &last, 0); console_lock(); - if (!lock_fb_info(fb_info)) { - console_unlock(); - return -ENODEV; - } + lock_fb_info(fb_info); fb_set_suspend(fb_info, (int)state); -- cgit From 9ef373923756b96680853d5b93578986dd07169a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:45 +0200 Subject: staging/olpc: lock_fb_info can't fail Simply because olpc never unregisters the damn thing. It also registers the framebuffer directly by poking around in fbdev core internals, so it's all around rather broken. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Acked-by: Greg Kroah-Hartman Reviewed-by: Maarten Lankhorst Cc: Greg Kroah-Hartman Cc: Jens Frederich Cc: Daniel Drake Cc: Jon Nettleton Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-15-daniel.vetter@ffwll.ch --- drivers/staging/olpc_dcon/olpc_dcon.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 6b714f740ac3..a254238be181 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -250,11 +250,7 @@ static bool dcon_blank_fb(struct dcon_priv *dcon, bool blank) int err; console_lock(); - if (!lock_fb_info(dcon->fbinfo)) { - console_unlock(); - dev_err(&dcon->client->dev, "unable to lock framebuffer\n"); - return false; - } + lock_fb_info(dcon->fbinfo); dcon->ignore_fb_events = true; err = fb_blank(dcon->fbinfo, -- cgit From cd90b5fdfad5b1c41f3a87fd3a928f574bc60933 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:46 +0200 Subject: fbdev/atyfb: lock_fb_info can't fail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's properly protected by reboot_lock. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Mikulas Patocka Cc: "David S. Miller" Cc: "Ville Syrjälä" Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-16-daniel.vetter@ffwll.ch --- drivers/video/fbdev/aty/atyfb_base.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index b6fe103df145..eebb62d82a23 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -3916,8 +3916,7 @@ static int atyfb_reboot_notify(struct notifier_block *nb, if (!reboot_info) goto out; - if (!lock_fb_info(reboot_info)) - goto out; + lock_fb_info(reboot_info); par = reboot_info->par; -- cgit From cf4a3ae4ef3399179166a464af1d6b172225bef4 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:47 +0200 Subject: fbdev: lock_fb_info cannot fail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ever since commit c47747fde931c02455683bd00ea43eaa62f35b0e Author: Linus Torvalds Date: Wed May 11 14:58:34 2011 -0700 fbmem: make read/write/ioctl use the frame buffer at open time fbdev has gained proper refcounting for the fbinfo attached to any open files, which means that the backing driver (stored in fb_info->fbops) cannot untimely disappear anymore. The only thing that can happen is that the entire device just outright disappears and gets unregistered, but file_fb_info does check for that. Except that it's racy - it only checks once at the start of a file_ops, there's no guarantee that the underlying fbdev won't untimely disappear. Aside: A proper way to fix that race is probably to replicate the srcu trickery we've rolled out in drm. But given that this race has existed since forever it's probably not one we need to fix right away. do_unregister_framebuffer also nowhere clears fb_info->fbops, hence the check in lock_fb_info can't possible catch a disappearing fbdev later on. Long story short: Ever since the above commit the fb_info->fbops checks have essentially become dead code. Remove this all. Aside from the file_ops callbacks, and stuff called from there there's only register/unregister code left. If that goes wrong a driver managed to register/unregister a device instance twice or in the wrong order. That's just a driver bug. v2: - fb_mmap had an open-coded version of the fbinfo->fops check, because it doesn't need the fbinfo->lock. Delete that too. - Use the wrapper function in fb_open/release now, since no difference anymore. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: Hans de Goede Cc: Yisheng Xie Cc: Sergey Senozhatsky Cc: "Noralf Trønnes" Cc: Peter Rosin Cc: "Michał Mirosław" Cc: Mikulas Patocka Cc: "Gustavo A. R. Silva" Cc: linux-fbdev@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-17-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbcmap.c | 6 +--- drivers/video/fbdev/core/fbcon.c | 3 +- drivers/video/fbdev/core/fbmem.c | 73 +++++++++------------------------------ 3 files changed, 19 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c index 2811c4afde01..e5ae33c1a8e8 100644 --- a/drivers/video/fbdev/core/fbcmap.c +++ b/drivers/video/fbdev/core/fbcmap.c @@ -285,11 +285,7 @@ int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) goto out; } umap.start = cmap->start; - if (!lock_fb_info(info)) { - rc = -ENODEV; - goto out; - } - + lock_fb_info(info); rc = fb_set_cmap(&umap, info); unlock_fb_info(info); out: diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index c12fc98035e0..f7f3eb0f1893 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2364,8 +2364,7 @@ static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info, } - if (!lock_fb_info(info)) - return; + lock_fb_info(info); event.info = info; event.data = ␣ fb_notifier_call_chain(FB_EVENT_CONBLANK, &event); diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index bed7698ad18a..d73762324ca2 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -80,17 +80,6 @@ static void put_fb_info(struct fb_info *fb_info) fb_info->fbops->fb_destroy(fb_info); } -int lock_fb_info(struct fb_info *info) -{ - mutex_lock(&info->lock); - if (!info->fbops) { - mutex_unlock(&info->lock); - return 0; - } - return 1; -} -EXPORT_SYMBOL(lock_fb_info); - /* * Helpers */ @@ -1121,8 +1110,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, switch (cmd) { case FBIOGET_VSCREENINFO: - if (!lock_fb_info(info)) - return -ENODEV; + lock_fb_info(info); var = info->var; unlock_fb_info(info); @@ -1132,10 +1120,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, if (copy_from_user(&var, argp, sizeof(var))) return -EFAULT; console_lock(); - if (!lock_fb_info(info)) { - console_unlock(); - return -ENODEV; - } + lock_fb_info(info); info->flags |= FBINFO_MISC_USEREVENT; ret = fb_set_var(info, &var); info->flags &= ~FBINFO_MISC_USEREVENT; @@ -1145,8 +1130,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, ret = -EFAULT; break; case FBIOGET_FSCREENINFO: - if (!lock_fb_info(info)) - return -ENODEV; + lock_fb_info(info); fix = info->fix; if (info->flags & FBINFO_HIDE_SMEM_START) fix.smem_start = 0; @@ -1162,8 +1146,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, case FBIOGETCMAP: if (copy_from_user(&cmap, argp, sizeof(cmap))) return -EFAULT; - if (!lock_fb_info(info)) - return -ENODEV; + lock_fb_info(info); cmap_from = info->cmap; unlock_fb_info(info); ret = fb_cmap_to_user(&cmap_from, &cmap); @@ -1172,10 +1155,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, if (copy_from_user(&var, argp, sizeof(var))) return -EFAULT; console_lock(); - if (!lock_fb_info(info)) { - console_unlock(); - return -ENODEV; - } + lock_fb_info(info); ret = fb_pan_display(info, &var); unlock_fb_info(info); console_unlock(); @@ -1192,8 +1172,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, return -EINVAL; con2fb.framebuffer = -1; event.data = &con2fb; - if (!lock_fb_info(info)) - return -ENODEV; + lock_fb_info(info); event.info = info; fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); unlock_fb_info(info); @@ -1214,10 +1193,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, } event.data = &con2fb; console_lock(); - if (!lock_fb_info(info)) { - console_unlock(); - return -ENODEV; - } + lock_fb_info(info); event.info = info; ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event); unlock_fb_info(info); @@ -1225,10 +1201,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, break; case FBIOBLANK: console_lock(); - if (!lock_fb_info(info)) { - console_unlock(); - return -ENODEV; - } + lock_fb_info(info); info->flags |= FBINFO_MISC_USEREVENT; ret = fb_blank(info, arg); info->flags &= ~FBINFO_MISC_USEREVENT; @@ -1236,8 +1209,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, console_unlock(); break; default: - if (!lock_fb_info(info)) - return -ENODEV; + lock_fb_info(info); fb = info->fbops; if (fb->fb_ioctl) ret = fb->fb_ioctl(info, cmd, arg); @@ -1357,8 +1329,7 @@ static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd, { struct fb_fix_screeninfo fix; - if (!lock_fb_info(info)) - return -ENODEV; + lock_fb_info(info); fix = info->fix; if (info->flags & FBINFO_HIDE_SMEM_START) fix.smem_start = 0; @@ -1418,8 +1389,6 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) if (!info) return -ENODEV; fb = info->fbops; - if (!fb) - return -ENODEV; mutex_lock(&info->mm_lock); if (fb->fb_mmap) { int res; @@ -1483,7 +1452,7 @@ __releases(&info->lock) if (IS_ERR(info)) return PTR_ERR(info); - mutex_lock(&info->lock); + lock_fb_info(info); if (!try_module_get(info->fbops->owner)) { res = -ENODEV; goto out; @@ -1499,7 +1468,7 @@ __releases(&info->lock) fb_deferred_io_open(info, inode, file); #endif out: - mutex_unlock(&info->lock); + unlock_fb_info(info); if (res) put_fb_info(info); return res; @@ -1512,11 +1481,11 @@ __releases(&info->lock) { struct fb_info * const info = file->private_data; - mutex_lock(&info->lock); + lock_fb_info(info); if (info->fbops->fb_release) info->fbops->fb_release(info,1); module_put(info->fbops->owner); - mutex_unlock(&info->lock); + unlock_fb_info(info); put_fb_info(info); return 0; } @@ -1734,14 +1703,10 @@ static int do_register_framebuffer(struct fb_info *fb_info) console_lock(); else atomic_inc(&ignore_console_lock_warning); - if (!lock_fb_info(fb_info)) { - ret = -ENODEV; - goto unlock_console; - } - + lock_fb_info(fb_info); ret = fbcon_fb_registered(fb_info); unlock_fb_info(fb_info); -unlock_console: + if (!lockless_register_fb) console_unlock(); else @@ -1759,11 +1724,7 @@ static int unbind_console(struct fb_info *fb_info) return -EINVAL; console_lock(); - if (!lock_fb_info(fb_info)) { - console_unlock(); - return -ENODEV; - } - + lock_fb_info(fb_info); event.info = fb_info; ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); unlock_fb_info(fb_info); -- cgit From 0e0f3250d4402d60f4571d076ab27d5af049853e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:48 +0200 Subject: fbcon: call fbcon_fb_bind directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also remove the error return value. That's all errors for either driver bugs (trying to unbind something that isn't bound), or errors of the new driver that will take over. There's nothing the outgoing driver can do about this anyway, so switch over to void. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: Hans de Goede Cc: Sergey Senozhatsky Cc: Peter Rosin Cc: Kees Cook Cc: Konstantin Khorenko Cc: Yisheng Xie Cc: "Michał Mirosław" Cc: Mikulas Patocka Cc: Thomas Zimmermann Cc: linux-fbdev@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-18-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbcon.c | 24 +++++++----------------- drivers/video/fbdev/core/fbmem.c | 7 ++----- 2 files changed, 9 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index f7f3eb0f1893..d1e37afa6f80 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -3046,7 +3046,7 @@ static int fbcon_mode_deleted(struct fb_info *info, } #ifdef CONFIG_VT_HW_CONSOLE_BINDING -static int fbcon_unbind(void) +static void fbcon_unbind(void) { int ret; @@ -3055,25 +3055,21 @@ static int fbcon_unbind(void) if (!ret) fbcon_has_console_bind = 0; - - return ret; } #else -static inline int fbcon_unbind(void) -{ - return -EINVAL; -} +static inline void fbcon_unbind(void) {} #endif /* CONFIG_VT_HW_CONSOLE_BINDING */ /* called with console_lock held */ -static int fbcon_fb_unbind(int idx) +void fbcon_fb_unbind(struct fb_info *info) { int i, new_idx = -1, ret = 0; + int idx = info->node; WARN_CONSOLE_UNLOCKED(); if (!fbcon_has_console_bind) - return 0; + return; for (i = first_fb_vc; i <= last_fb_vc; i++) { if (con2fb_map[i] != idx && @@ -3106,15 +3102,13 @@ static int fbcon_fb_unbind(int idx) idx, 0); if (ret) { con2fb_map[i] = idx; - return ret; + return; } } } } - ret = fbcon_unbind(); + fbcon_unbind(); } - - return ret; } /* called with console_lock held */ @@ -3352,10 +3346,6 @@ static int fbcon_event_notify(struct notifier_block *self, mode = event->data; ret = fbcon_mode_deleted(info, mode); break; - case FB_EVENT_FB_UNBIND: - idx = info->node; - ret = fbcon_fb_unbind(idx); - break; case FB_EVENT_SET_CONSOLE_MAP: /* called with console lock held */ con2fb = event->data; diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index d73762324ca2..f3fc2e5b193c 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1716,8 +1716,6 @@ static int do_register_framebuffer(struct fb_info *fb_info) static int unbind_console(struct fb_info *fb_info) { - struct fb_event event; - int ret; int i = fb_info->node; if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info) @@ -1725,12 +1723,11 @@ static int unbind_console(struct fb_info *fb_info) console_lock(); lock_fb_info(fb_info); - event.info = fb_info; - ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); + fbcon_fb_unbind(fb_info); unlock_fb_info(fb_info); console_unlock(); - return ret; + return 0; } static int __unlink_framebuffer(struct fb_info *fb_info); -- cgit From deb00d2785bedd379caa7aaf18c1ffb824580b9d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:49 +0200 Subject: fbdev: make unregister/unlink functions not fail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Except for driver bugs (which we'll catch with a WARN_ON) this is only to report failures of the new driver taking over the console. There's nothing the outgoing driver can do about that, and no one ever bothered to actually look at these return values. So remove them all. v2: fixup unregister_framebuffer in savagefb, fbtft, ivtvfb, and neofb drivers, reported by kbuild. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: "Michał Mirosław" Cc: Peter Rosin Cc: Hans de Goede Cc: Mikulas Patocka Cc: linux-fbdev@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-19-daniel.vetter@ffwll.ch --- drivers/media/pci/ivtv/ivtvfb.c | 6 +-- drivers/staging/fbtft/fbtft-core.c | 4 +- drivers/video/fbdev/core/fbmem.c | 73 +++++++++------------------- drivers/video/fbdev/neofb.c | 9 +--- drivers/video/fbdev/savage/savagefb_driver.c | 9 +--- 5 files changed, 29 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c index 66be490ec563..299ff032f528 100644 --- a/drivers/media/pci/ivtv/ivtvfb.c +++ b/drivers/media/pci/ivtv/ivtvfb.c @@ -1246,11 +1246,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p) struct osd_info *oi = itv->osd_info; if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { - if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) { - IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", - itv->instance); - return 0; - } + unregister_framebuffer(&itv->osd_info->ivtvfb_info); IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance); itv->ivtvfb_restore = NULL; ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info); diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index 9b07badf4c6c..7cbc1bdd2d8a 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -891,7 +891,9 @@ int fbtft_unregister_framebuffer(struct fb_info *fb_info) if (par->fbtftops.unregister_backlight) par->fbtftops.unregister_backlight(par); fbtft_sysfs_exit(par); - return unregister_framebuffer(fb_info); + unregister_framebuffer(fb_info); + + return 0; } EXPORT_SYMBOL(fbtft_unregister_framebuffer); diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index f3fc2e5b193c..f3bcad30d3ba 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1590,13 +1590,13 @@ static bool fb_do_apertures_overlap(struct apertures_struct *gena, return false; } -static int do_unregister_framebuffer(struct fb_info *fb_info); +static void do_unregister_framebuffer(struct fb_info *fb_info); #define VGA_FB_PHYS 0xA0000 -static int do_remove_conflicting_framebuffers(struct apertures_struct *a, - const char *name, bool primary) +static void do_remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary) { - int i, ret; + int i; /* check all firmware fbs and kick off if the base addr overlaps */ for_each_registered_fb(i) { @@ -1612,13 +1612,9 @@ static int do_remove_conflicting_framebuffers(struct apertures_struct *a, printk(KERN_INFO "fb%d: switching to %s from %s\n", i, name, registered_fb[i]->fix.id); - ret = do_unregister_framebuffer(registered_fb[i]); - if (ret) - return ret; + do_unregister_framebuffer(registered_fb[i]); } } - - return 0; } static bool lockless_register_fb; @@ -1634,11 +1630,9 @@ static int do_register_framebuffer(struct fb_info *fb_info) if (fb_check_foreignness(fb_info)) return -ENOSYS; - ret = do_remove_conflicting_framebuffers(fb_info->apertures, - fb_info->fix.id, - fb_is_primary_device(fb_info)); - if (ret) - return ret; + do_remove_conflicting_framebuffers(fb_info->apertures, + fb_info->fix.id, + fb_is_primary_device(fb_info)); if (num_registered_fb == FB_MAX) return -ENXIO; @@ -1714,32 +1708,25 @@ static int do_register_framebuffer(struct fb_info *fb_info) return ret; } -static int unbind_console(struct fb_info *fb_info) +static void unbind_console(struct fb_info *fb_info) { int i = fb_info->node; - if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info) - return -EINVAL; + if (WARN_ON(i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)) + return; console_lock(); lock_fb_info(fb_info); fbcon_fb_unbind(fb_info); unlock_fb_info(fb_info); console_unlock(); - - return 0; } -static int __unlink_framebuffer(struct fb_info *fb_info); +static void __unlink_framebuffer(struct fb_info *fb_info); -static int do_unregister_framebuffer(struct fb_info *fb_info) +static void do_unregister_framebuffer(struct fb_info *fb_info) { - int ret; - - ret = unbind_console(fb_info); - - if (ret) - return -EINVAL; + unbind_console(fb_info); pm_vt_switch_unregister(fb_info->dev); @@ -1764,36 +1751,27 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) /* this may free fb info */ put_fb_info(fb_info); - return 0; } -static int __unlink_framebuffer(struct fb_info *fb_info) +static void __unlink_framebuffer(struct fb_info *fb_info) { int i; i = fb_info->node; - if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info) - return -EINVAL; + if (WARN_ON(i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)) + return; if (fb_info->dev) { device_destroy(fb_class, MKDEV(FB_MAJOR, i)); fb_info->dev = NULL; } - - return 0; } -int unlink_framebuffer(struct fb_info *fb_info) +void unlink_framebuffer(struct fb_info *fb_info) { - int ret; - - ret = __unlink_framebuffer(fb_info); - if (ret) - return ret; + __unlink_framebuffer(fb_info); unbind_console(fb_info); - - return 0; } EXPORT_SYMBOL(unlink_framebuffer); @@ -1810,7 +1788,6 @@ EXPORT_SYMBOL(unlink_framebuffer); int remove_conflicting_framebuffers(struct apertures_struct *a, const char *name, bool primary) { - int ret; bool do_free = false; if (!a) { @@ -1824,13 +1801,13 @@ int remove_conflicting_framebuffers(struct apertures_struct *a, } mutex_lock(®istration_lock); - ret = do_remove_conflicting_framebuffers(a, name, primary); + do_remove_conflicting_framebuffers(a, name, primary); mutex_unlock(®istration_lock); if (do_free) kfree(a); - return ret; + return 0; } EXPORT_SYMBOL(remove_conflicting_framebuffers); @@ -1927,16 +1904,12 @@ EXPORT_SYMBOL(register_framebuffer); * that the driver implements fb_open() and fb_release() to * check that no processes are using the device. */ -int +void unregister_framebuffer(struct fb_info *fb_info) { - int ret; - mutex_lock(®istration_lock); - ret = do_unregister_framebuffer(fb_info); + do_unregister_framebuffer(fb_info); mutex_unlock(®istration_lock); - - return ret; } EXPORT_SYMBOL(unregister_framebuffer); diff --git a/drivers/video/fbdev/neofb.c b/drivers/video/fbdev/neofb.c index 5d3a444083f7..b770946a0920 100644 --- a/drivers/video/fbdev/neofb.c +++ b/drivers/video/fbdev/neofb.c @@ -2122,14 +2122,7 @@ static void neofb_remove(struct pci_dev *dev) DBG("neofb_remove"); if (info) { - /* - * If unregister_framebuffer fails, then - * we will be leaving hooks that could cause - * oopsen laying around. - */ - if (unregister_framebuffer(info)) - printk(KERN_WARNING - "neofb: danger danger! Oopsen imminent!\n"); + unregister_framebuffer(info); neo_unmap_video(info); fb_destroy_modedb(info->monspecs.modedb); diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c index 47b78f0138c3..512789f5f884 100644 --- a/drivers/video/fbdev/savage/savagefb_driver.c +++ b/drivers/video/fbdev/savage/savagefb_driver.c @@ -2333,14 +2333,7 @@ static void savagefb_remove(struct pci_dev *dev) DBG("savagefb_remove"); if (info) { - /* - * If unregister_framebuffer fails, then - * we will be leaving hooks that could cause - * oopsen laying around. - */ - if (unregister_framebuffer(info)) - printk(KERN_WARNING "savagefb: danger danger! " - "Oopsen imminent!\n"); + unregister_framebuffer(info); #ifdef CONFIG_FB_SAVAGE_I2C savagefb_delete_i2c_busses(info); -- cgit From 927ab1aed13d6a5188b764d830197d79b8c0e1ad Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:50 +0200 Subject: fbdev: unify unlink_framebuffer paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For some reasons the pm_vt_switch_unregister call was missing from the direct unregister_framebuffer path. Fix this. v2: fbinfo->dev is used to decided whether unlink_framebuffer has been called already. I botched that in v1. Make this all clearer by inlining __unlink_framebuffer. v3: Fix typoe in subject (Maarten). Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Maarten Lankhorst Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: "Michał Mirosław" Cc: Peter Rosin Cc: Hans de Goede Cc: Mikulas Patocka Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-20-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbmem.c | 47 +++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index f3bcad30d3ba..bee45e9405b8 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1722,15 +1722,30 @@ static void unbind_console(struct fb_info *fb_info) console_unlock(); } -static void __unlink_framebuffer(struct fb_info *fb_info); - -static void do_unregister_framebuffer(struct fb_info *fb_info) +void unlink_framebuffer(struct fb_info *fb_info) { - unbind_console(fb_info); + int i; + + i = fb_info->node; + if (WARN_ON(i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)) + return; + + if (!fb_info->dev) + return; + + device_destroy(fb_class, MKDEV(FB_MAJOR, i)); pm_vt_switch_unregister(fb_info->dev); - __unlink_framebuffer(fb_info); + unbind_console(fb_info); + + fb_info->dev = NULL; +} +EXPORT_SYMBOL(unlink_framebuffer); + +static void do_unregister_framebuffer(struct fb_info *fb_info) +{ + unlink_framebuffer(fb_info); if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) kfree(fb_info->pixmap.addr); @@ -1753,28 +1768,6 @@ static void do_unregister_framebuffer(struct fb_info *fb_info) put_fb_info(fb_info); } -static void __unlink_framebuffer(struct fb_info *fb_info) -{ - int i; - - i = fb_info->node; - if (WARN_ON(i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)) - return; - - if (fb_info->dev) { - device_destroy(fb_class, MKDEV(FB_MAJOR, i)); - fb_info->dev = NULL; - } -} - -void unlink_framebuffer(struct fb_info *fb_info) -{ - __unlink_framebuffer(fb_info); - - unbind_console(fb_info); -} -EXPORT_SYMBOL(unlink_framebuffer); - /** * remove_conflicting_framebuffers - remove firmware-configured framebuffers * @a: memory range, users of which are to be removed -- cgit From 9c22ad983328d6083420b5fcc035f001b7c8f875 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:51 +0200 Subject: fbdev/sh_mob: Remove fb notifier callback This seems to be entirely defunct: - The FB_EVEN_SUSPEND/RESUME events are only sent out by fb_set_suspend. Which is supposed to be called by drivers in their suspend/resume hooks, and not itself call into drivers. Luckily sh_mob doesn't call fb_set_suspend, so this seems to do nothing useful. - The notify hook calls sh_mobile_fb_reconfig() which in turn can call into the fb notifier. Or attempt too, since that would deadlock. So looks like leftover hacks from when this was originally introduced in commit 6011bdeaa6089d49c02de69f05980da7bad314ab Author: Guennadi Liakhovetski Date: Wed Jul 21 10:13:21 2010 +0000 fbdev: sh-mobile: HDMI support for SH-Mobile SoCs So let's just remove it. Signed-off-by: Daniel Vetter Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Daniel Vetter Cc: Bartlomiej Zolnierkiewicz Cc: Markus Elfring Cc: Geert Uytterhoeven Cc: Wolfram Sang Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-21-daniel.vetter@ffwll.ch --- drivers/video/fbdev/sh_mobile_lcdcfb.c | 38 ---------------------------------- 1 file changed, 38 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c index 1437695415c9..015a02a29d37 100644 --- a/drivers/video/fbdev/sh_mobile_lcdcfb.c +++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c @@ -213,7 +213,6 @@ struct sh_mobile_lcdc_priv { struct sh_mobile_lcdc_chan ch[2]; struct sh_mobile_lcdc_overlay overlays[4]; - struct notifier_block notifier; int started; int forced_fourcc; /* 2 channel LCDC must share fourcc setting */ }; @@ -2239,37 +2238,6 @@ static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { * Framebuffer notifier */ -/* locking: called with info->lock held */ -static int sh_mobile_lcdc_notify(struct notifier_block *nb, - unsigned long action, void *data) -{ - struct fb_event *event = data; - struct fb_info *info = event->info; - struct sh_mobile_lcdc_chan *ch = info->par; - - if (&ch->lcdc->notifier != nb) - return NOTIFY_DONE; - - dev_dbg(info->dev, "%s(): action = %lu, data = %p\n", - __func__, action, event->data); - - switch(action) { - case FB_EVENT_SUSPEND: - sh_mobile_lcdc_display_off(ch); - sh_mobile_lcdc_stop(ch->lcdc); - break; - case FB_EVENT_RESUME: - mutex_lock(&ch->open_lock); - sh_mobile_fb_reconfig(info); - mutex_unlock(&ch->open_lock); - - sh_mobile_lcdc_display_on(ch); - sh_mobile_lcdc_start(ch->lcdc); - } - - return NOTIFY_OK; -} - /* ----------------------------------------------------------------------------- * Probe/remove and driver init/exit */ @@ -2297,8 +2265,6 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev) struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev); unsigned int i; - fb_unregister_client(&priv->notifier); - for (i = 0; i < ARRAY_SIZE(priv->overlays); i++) sh_mobile_lcdc_overlay_fb_unregister(&priv->overlays[i]); for (i = 0; i < ARRAY_SIZE(priv->ch); i++) @@ -2688,10 +2654,6 @@ static int sh_mobile_lcdc_probe(struct platform_device *pdev) goto err1; } - /* Failure ignored */ - priv->notifier.notifier_call = sh_mobile_lcdc_notify; - fb_register_client(&priv->notifier); - return 0; err1: sh_mobile_lcdc_remove(pdev); -- cgit From 50c5056356340c8b5be90440d2f32fec8c47a7c3 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:52 +0200 Subject: fbdev: directly call fbcon_suspended/resumed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the sh_mobile notifier removed we can just directly call the fbcon code here. v2: Remove now unused local variable. v3: fixup !CONFIG_FRAMEBUFFER_CONSOLE, noticed by kbuild Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: Hans de Goede Cc: Greg Kroah-Hartman Cc: Prarit Bhargava Cc: Kees Cook Cc: Konstantin Khorenko Cc: Yisheng Xie Cc: "Michał Mirosław" Cc: Peter Rosin Cc: Mikulas Patocka Cc: linux-fbdev@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-22-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbcon.c | 10 ++-------- drivers/video/fbdev/core/fbmem.c | 7 ++----- 2 files changed, 4 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index d1e37afa6f80..9994111f2563 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2919,7 +2919,7 @@ static int fbcon_set_origin(struct vc_data *vc) return 0; } -static void fbcon_suspended(struct fb_info *info) +void fbcon_suspended(struct fb_info *info) { struct vc_data *vc = NULL; struct fbcon_ops *ops = info->fbcon_par; @@ -2932,7 +2932,7 @@ static void fbcon_suspended(struct fb_info *info) fbcon_cursor(vc, CM_ERASE); } -static void fbcon_resumed(struct fb_info *info) +void fbcon_resumed(struct fb_info *info) { struct vc_data *vc; struct fbcon_ops *ops = info->fbcon_par; @@ -3330,12 +3330,6 @@ static int fbcon_event_notify(struct notifier_block *self, int idx, ret = 0; switch(action) { - case FB_EVENT_SUSPEND: - fbcon_suspended(info); - break; - case FB_EVENT_RESUME: - fbcon_resumed(info); - break; case FB_EVENT_MODE_CHANGE: fbcon_modechanged(info); break; diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index bee45e9405b8..73269dedcd45 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1917,17 +1917,14 @@ EXPORT_SYMBOL(unregister_framebuffer); */ void fb_set_suspend(struct fb_info *info, int state) { - struct fb_event event; - WARN_CONSOLE_UNLOCKED(); - event.info = info; if (state) { - fb_notifier_call_chain(FB_EVENT_SUSPEND, &event); + fbcon_suspended(info); info->state = FBINFO_STATE_SUSPENDED; } else { info->state = FBINFO_STATE_RUNNING; - fb_notifier_call_chain(FB_EVENT_RESUME, &event); + fbcon_resumed(info); } } EXPORT_SYMBOL(fb_set_suspend); -- cgit From 13ff178ccd6d3b8074c542a911300b79c4eec255 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:53 +0200 Subject: fbcon: Call fbcon_mode_deleted/new_modelist directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I'm not entirely clear on what new_modelist actually does, it seems exclusively for a sysfs interface. Which in the end does amount to a normal fb_set_par to check the mode, but then takes a different path in both fbmem.c and fbcon.c. I have no idea why these 2 paths are different, but then I also don't really want to find out. So just do the simple conversion to a direct function call. v2: static inline for the dummy versions, I forgot. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: Hans de Goede Cc: Mikulas Patocka Cc: Sergey Senozhatsky Cc: Kees Cook Cc: Peter Rosin Cc: Yisheng Xie Cc: "Michał Mirosław" Cc: linux-fbdev@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-23-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbcon.c | 14 +++----------- drivers/video/fbdev/core/fbmem.c | 22 +++++++--------------- 2 files changed, 10 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 9994111f2563..24bd6cd270d5 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -3019,8 +3019,8 @@ static void fbcon_set_all_vcs(struct fb_info *info) fbcon_modechanged(info); } -static int fbcon_mode_deleted(struct fb_info *info, - struct fb_videomode *mode) +int fbcon_mode_deleted(struct fb_info *info, + struct fb_videomode *mode) { struct fb_info *fb_info; struct fbcon_display *p; @@ -3262,7 +3262,7 @@ static void fbcon_fb_blanked(struct fb_info *info, int blank) ops->blank_state = blank; } -static void fbcon_new_modelist(struct fb_info *info) +void fbcon_new_modelist(struct fb_info *info) { int i; struct vc_data *vc; @@ -3324,7 +3324,6 @@ static int fbcon_event_notify(struct notifier_block *self, { struct fb_event *event = data; struct fb_info *info = event->info; - struct fb_videomode *mode; struct fb_con2fbmap *con2fb; struct fb_blit_caps *caps; int idx, ret = 0; @@ -3336,10 +3335,6 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_MODE_CHANGE_ALL: fbcon_set_all_vcs(info); break; - case FB_EVENT_MODE_DELETE: - mode = event->data; - ret = fbcon_mode_deleted(info, mode); - break; case FB_EVENT_SET_CONSOLE_MAP: /* called with console lock held */ con2fb = event->data; @@ -3353,9 +3348,6 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_BLANK: fbcon_fb_blanked(info, *(int *)event->data); break; - case FB_EVENT_NEW_MODELIST: - fbcon_new_modelist(info); - break; case FB_EVENT_GET_REQ: caps = event->data; fbcon_get_requirement(info, caps); diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 73269dedcd45..cbdd141e7695 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -966,16 +966,11 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) /* make sure we don't delete the videomode of current var */ ret = fb_mode_is_equal(&mode1, &mode2); - if (!ret) { - struct fb_event event; - - event.info = info; - event.data = &mode1; - ret = fb_notifier_call_chain(FB_EVENT_MODE_DELETE, &event); - } + if (!ret) + fbcon_mode_deleted(info, &mode1); if (!ret) - fb_delete_videomode(&mode1, &info->modelist); + fb_delete_videomode(&mode1, &info->modelist); ret = (ret) ? -EINVAL : 0; @@ -1992,7 +1987,6 @@ subsys_initcall(fbmem_init); int fb_new_modelist(struct fb_info *info) { - struct fb_event event; struct fb_var_screeninfo var = info->var; struct list_head *pos, *n; struct fb_modelist *modelist; @@ -2012,14 +2006,12 @@ int fb_new_modelist(struct fb_info *info) } } - err = 1; + if (list_empty(&info->modelist)) + return 1; - if (!list_empty(&info->modelist)) { - event.info = info; - err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); - } + fbcon_new_modelist(info); - return err; + return 0; } MODULE_LICENSE("GPL"); -- cgit From 0526c2239ad8ceef98652fe8e059044c24c62ea7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:54 +0200 Subject: fbdev: Call fbcon_get_requirement directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pretty simple case really. v2: Forgot to remove a break; v3: Add static inline to the dummy versions. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: Hans de Goede Cc: "Steven Rostedt (VMware)" Cc: Prarit Bhargava Cc: Kees Cook Cc: Yisheng Xie Cc: "Michał Mirosław" Cc: Peter Rosin Cc: Mikulas Patocka Cc: linux-fbdev@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-24-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbcon.c | 9 ++------- drivers/video/fbdev/core/fbmem.c | 5 +---- 2 files changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 24bd6cd270d5..ee0bed9571aa 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -3283,8 +3283,8 @@ void fbcon_new_modelist(struct fb_info *info) } } -static void fbcon_get_requirement(struct fb_info *info, - struct fb_blit_caps *caps) +void fbcon_get_requirement(struct fb_info *info, + struct fb_blit_caps *caps) { struct vc_data *vc; struct fbcon_display *p; @@ -3325,7 +3325,6 @@ static int fbcon_event_notify(struct notifier_block *self, struct fb_event *event = data; struct fb_info *info = event->info; struct fb_con2fbmap *con2fb; - struct fb_blit_caps *caps; int idx, ret = 0; switch(action) { @@ -3348,10 +3347,6 @@ static int fbcon_event_notify(struct notifier_block *self, case FB_EVENT_BLANK: fbcon_fb_blanked(info, *(int *)event->data); break; - case FB_EVENT_GET_REQ: - caps = event->data; - fbcon_get_requirement(info, caps); - break; case FB_EVENT_REMAP_ALL_CONSOLE: idx = info->node; fbcon_remap_all(idx); diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index cbdd141e7695..ddc0c16b8bbf 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -932,16 +932,13 @@ EXPORT_SYMBOL(fb_pan_display); static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var, u32 activate) { - struct fb_event event; struct fb_blit_caps caps, fbcaps; int err = 0; memset(&caps, 0, sizeof(caps)); memset(&fbcaps, 0, sizeof(fbcaps)); caps.flags = (activate & FB_ACTIVATE_ALL) ? 1 : 0; - event.info = info; - event.data = ∩︀ - fb_notifier_call_chain(FB_EVENT_GET_REQ, &event); + fbcon_get_requirement(info, &caps); info->fbops->fb_get_caps(info, &fbcaps, var); if (((fbcaps.x ^ caps.x) & caps.x) || -- cgit From 7a625549ea8c14be70bc7cfaf30215401bba6da0 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:55 +0200 Subject: Revert "backlight/fbcon: Add FB_EVENT_CONBLANK" This reverts commit 994efacdf9a087b52f71e620b58dfa526b0cf928. The justification is that if hw blanking fails (i.e. fbops->fb_blank) fails, then we still want to shut down the backlight. Which is exactly _not_ what fb_blank() does and so rather inconsistent if we end up with different behaviour between fbcon and direct fbdev usage. Given that the entire notifier maze is getting in the way anyway I figured it's simplest to revert this not well justified commit. v2: Add static inline to the dummy version. Cc: Richard Purdie Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Acked-by: Daniel Thompson Cc: Lee Jones Cc: Daniel Thompson Cc: Jingoo Han Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: Hans de Goede Cc: Yisheng Xie Cc: linux-fbdev@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-25-daniel.vetter@ffwll.ch --- drivers/video/backlight/backlight.c | 2 +- drivers/video/fbdev/core/fbcon.c | 14 +------------- drivers/video/fbdev/core/fbmem.c | 1 + 3 files changed, 3 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 1ef8b6fd62ac..5dc07106a59e 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -47,7 +47,7 @@ static int fb_notifier_callback(struct notifier_block *self, int fb_blank = 0; /* If we aren't interested in this event, skip it immediately ... */ - if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK) + if (event != FB_EVENT_BLANK) return 0; bd = container_of(self, struct backlight_device, fb_notif); diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index ee0bed9571aa..be179b47d1c6 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2350,8 +2350,6 @@ static int fbcon_switch(struct vc_data *vc) static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info, int blank) { - struct fb_event event; - if (blank) { unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; @@ -2362,13 +2360,6 @@ static void fbcon_generic_blank(struct vc_data *vc, struct fb_info *info, fbcon_clear(vc, 0, 0, vc->vc_rows, vc->vc_cols); vc->vc_video_erase_char = oldc; } - - - lock_fb_info(info); - event.info = info; - event.data = ␣ - fb_notifier_call_chain(FB_EVENT_CONBLANK, &event); - unlock_fb_info(info); } static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) @@ -3240,7 +3231,7 @@ int fbcon_fb_registered(struct fb_info *info) return ret; } -static void fbcon_fb_blanked(struct fb_info *info, int blank) +void fbcon_fb_blanked(struct fb_info *info, int blank) { struct fbcon_ops *ops = info->fbcon_par; struct vc_data *vc; @@ -3344,9 +3335,6 @@ static int fbcon_event_notify(struct notifier_block *self, con2fb = event->data; con2fb->framebuffer = con2fb_map[con2fb->console - 1]; break; - case FB_EVENT_BLANK: - fbcon_fb_blanked(info, *(int *)event->data); - break; case FB_EVENT_REMAP_ALL_CONSOLE: idx = info->node; fbcon_remap_all(idx); diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index ddc0c16b8bbf..9366fbe99a58 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1068,6 +1068,7 @@ fb_blank(struct fb_info *info, int blank) event.data = ␣ early_ret = fb_notifier_call_chain(FB_EARLY_EVENT_BLANK, &event); + fbcon_fb_blanked(info, blank); if (info->fbops->fb_blank) ret = info->fbops->fb_blank(blank, info); -- cgit From de29ae5c092bd9a5360cfabf174b0f783248d278 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:56 +0200 Subject: fbmem: pull fbcon_fb_blanked out of fb_blank MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's a callchain of: fbcon_fb_blanked -> do_(un)blank_screen -> consw->con_blank -> fbcon_blank -> fb_blank Things don't go horribly wrong because the BKL console_lock safes the day, but that's about it. And the seeming recursion is broken in 2 ways: - Starting from the fbdev ioctl we set FBINFO_MISC_USEREVENT, which tells the fbcon_blank code to not call fb_blank. This was required to not deadlock when recursing on the fb_notifier_chain mutex. - Starting from the con_blank hook we're getting saved by the console_blanked checks in do_blank/unblank_screen. Or at least that's my theory. Anyway, recursion isn't awesome, so let's stop it. Breaking the recursion avoids the need to be in the FBINFO_MISC_USEREVENT critical section, so lets move it out of that too. The astute reader will notice that fb_blank seems to require lock_fb_info(), which the fbcon code seems to ignore. I have no idea how to fix that problem, so let's keep ignoring it. v2: I forgot the sysfs blanking code. v3: Fix typo in callchain in the commmit message (Sam). Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Sam Ravnborg Cc: Daniel Vetter Cc: Bartlomiej Zolnierkiewicz Cc: "Michał Mirosław" Cc: Peter Rosin Cc: Hans de Goede Cc: Mikulas Patocka Cc: Rob Clark Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-26-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbmem.c | 4 +++- drivers/video/fbdev/core/fbsysfs.c | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 9366fbe99a58..d6713dce9e31 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1068,7 +1068,6 @@ fb_blank(struct fb_info *info, int blank) event.data = ␣ early_ret = fb_notifier_call_chain(FB_EARLY_EVENT_BLANK, &event); - fbcon_fb_blanked(info, blank); if (info->fbops->fb_blank) ret = info->fbops->fb_blank(blank, info); @@ -1198,6 +1197,9 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, info->flags |= FBINFO_MISC_USEREVENT; ret = fb_blank(info, arg); info->flags &= ~FBINFO_MISC_USEREVENT; + + /* might again call into fb_blank */ + fbcon_fb_blanked(info, arg); unlock_fb_info(info); console_unlock(); break; diff --git a/drivers/video/fbdev/core/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c index f80d5b3a7797..6e39066774a6 100644 --- a/drivers/video/fbdev/core/fbsysfs.c +++ b/drivers/video/fbdev/core/fbsysfs.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -301,12 +302,15 @@ static ssize_t store_blank(struct device *device, { struct fb_info *fb_info = dev_get_drvdata(device); char *last = NULL; - int err; + int err, arg; + arg = simple_strtoul(buf, &last, 0); console_lock(); fb_info->flags |= FBINFO_MISC_USEREVENT; - err = fb_blank(fb_info, simple_strtoul(buf, &last, 0)); + err = fb_blank(fb_info, arg); fb_info->flags &= ~FBINFO_MISC_USEREVENT; + /* might again call into fb_blank */ + fbcon_fb_blanked(fb_info, arg); console_unlock(); if (err < 0) return err; -- cgit From 3667617347ba42c85ec846a9ea5c33f5d6ab9e4a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:57 +0200 Subject: fbdev: remove FBINFO_MISC_USEREVENT around fb_blank MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the recursion broken in the previous patch we can drop the FBINFO_MISC_USEREVENT flag around calls to fb_blank - recursion prevention was it's only job. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Daniel Vetter Cc: Bartlomiej Zolnierkiewicz Cc: Hans de Goede Cc: Yisheng Xie Cc: "Michał Mirosław" Cc: Peter Rosin Cc: Mikulas Patocka Cc: Rob Clark Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-27-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbcon.c | 5 ++--- drivers/video/fbdev/core/fbmem.c | 3 --- drivers/video/fbdev/core/fbsysfs.c | 2 -- 3 files changed, 2 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index be179b47d1c6..4afbc7d8c68c 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2386,9 +2386,8 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); ops->cursor_flash = (!blank); - if (!(info->flags & FBINFO_MISC_USEREVENT)) - if (fb_blank(info, blank)) - fbcon_generic_blank(vc, info, blank); + if (fb_blank(info, blank)) + fbcon_generic_blank(vc, info, blank); } if (!blank) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index d6713dce9e31..25ae466ba593 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1194,10 +1194,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, case FBIOBLANK: console_lock(); lock_fb_info(info); - info->flags |= FBINFO_MISC_USEREVENT; ret = fb_blank(info, arg); - info->flags &= ~FBINFO_MISC_USEREVENT; - /* might again call into fb_blank */ fbcon_fb_blanked(info, arg); unlock_fb_info(info); diff --git a/drivers/video/fbdev/core/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c index 6e39066774a6..d54c88f88991 100644 --- a/drivers/video/fbdev/core/fbsysfs.c +++ b/drivers/video/fbdev/core/fbsysfs.c @@ -306,9 +306,7 @@ static ssize_t store_blank(struct device *device, arg = simple_strtoul(buf, &last, 0); console_lock(); - fb_info->flags |= FBINFO_MISC_USEREVENT; err = fb_blank(fb_info, arg); - fb_info->flags &= ~FBINFO_MISC_USEREVENT; /* might again call into fb_blank */ fbcon_fb_blanked(fb_info, arg); console_unlock(); -- cgit From c428f35adf0faac11e0cceb7dadf3b29055d7d49 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:58 +0200 Subject: fb: Flatten control flow in fb_set_var MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of wiring almost everything down to the very last line using goto soup (but not consistently, where would the fun be otherwise) drop out early when checks fail. This allows us to flatten the huge indent levels to just 1. Aside: If a driver doesn't set ->fb_check_var, then FB_ACTIVATE_NOW does nothing. This bug exists ever since this code was extracted as a common helper in 2002, hence I decided against fixing it. Everyone just better have a fb_check_var to make sure things work correctly. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Daniel Vetter Cc: Bartlomiej Zolnierkiewicz Cc: "Michał Mirosław" Cc: Peter Rosin Cc: Hans de Goede Cc: Mikulas Patocka Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-28-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbmem.c | 126 +++++++++++++++++++-------------------- 1 file changed, 63 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 25ae466ba593..96805fe85332 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -954,6 +954,9 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) { int flags = info->flags; int ret = 0; + u32 activate; + struct fb_var_screeninfo old_var; + struct fb_videomode mode; if (var->activate & FB_ACTIVATE_INV_MODE) { struct fb_videomode mode1, mode2; @@ -970,87 +973,84 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) fb_delete_videomode(&mode1, &info->modelist); - ret = (ret) ? -EINVAL : 0; - goto done; + return ret ? -EINVAL : 0; } - if ((var->activate & FB_ACTIVATE_FORCE) || - memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) { - u32 activate = var->activate; + if (!(var->activate & FB_ACTIVATE_FORCE) && + !memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) + return 0; - /* When using FOURCC mode, make sure the red, green, blue and - * transp fields are set to 0. - */ - if ((info->fix.capabilities & FB_CAP_FOURCC) && - var->grayscale > 1) { - if (var->red.offset || var->green.offset || - var->blue.offset || var->transp.offset || - var->red.length || var->green.length || - var->blue.length || var->transp.length || - var->red.msb_right || var->green.msb_right || - var->blue.msb_right || var->transp.msb_right) - return -EINVAL; - } + activate = var->activate; - if (!info->fbops->fb_check_var) { - *var = info->var; - goto done; - } + /* When using FOURCC mode, make sure the red, green, blue and + * transp fields are set to 0. + */ + if ((info->fix.capabilities & FB_CAP_FOURCC) && + var->grayscale > 1) { + if (var->red.offset || var->green.offset || + var->blue.offset || var->transp.offset || + var->red.length || var->green.length || + var->blue.length || var->transp.length || + var->red.msb_right || var->green.msb_right || + var->blue.msb_right || var->transp.msb_right) + return -EINVAL; + } - ret = info->fbops->fb_check_var(var, info); + if (!info->fbops->fb_check_var) { + *var = info->var; + return 0; + } - if (ret) - goto done; + ret = info->fbops->fb_check_var(var, info); - if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { - struct fb_var_screeninfo old_var; - struct fb_videomode mode; + if (ret) + return ret; - if (info->fbops->fb_get_caps) { - ret = fb_check_caps(info, var, activate); + if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) + return 0; - if (ret) - goto done; - } + if (info->fbops->fb_get_caps) { + ret = fb_check_caps(info, var, activate); - old_var = info->var; - info->var = *var; + if (ret) + return ret; + } - if (info->fbops->fb_set_par) { - ret = info->fbops->fb_set_par(info); + old_var = info->var; + info->var = *var; - if (ret) { - info->var = old_var; - printk(KERN_WARNING "detected " - "fb_set_par error, " - "error code: %d\n", ret); - goto done; - } - } + if (info->fbops->fb_set_par) { + ret = info->fbops->fb_set_par(info); + + if (ret) { + info->var = old_var; + printk(KERN_WARNING "detected " + "fb_set_par error, " + "error code: %d\n", ret); + return ret; + } + } - fb_pan_display(info, &info->var); - fb_set_cmap(&info->cmap, info); - fb_var_to_videomode(&mode, &info->var); + fb_pan_display(info, &info->var); + fb_set_cmap(&info->cmap, info); + fb_var_to_videomode(&mode, &info->var); - if (info->modelist.prev && info->modelist.next && - !list_empty(&info->modelist)) - ret = fb_add_videomode(&mode, &info->modelist); + if (info->modelist.prev && info->modelist.next && + !list_empty(&info->modelist)) + ret = fb_add_videomode(&mode, &info->modelist); - if (!ret && (flags & FBINFO_MISC_USEREVENT)) { - struct fb_event event; - int evnt = (activate & FB_ACTIVATE_ALL) ? - FB_EVENT_MODE_CHANGE_ALL : - FB_EVENT_MODE_CHANGE; + if (!ret && (flags & FBINFO_MISC_USEREVENT)) { + struct fb_event event; + int evnt = (activate & FB_ACTIVATE_ALL) ? + FB_EVENT_MODE_CHANGE_ALL : + FB_EVENT_MODE_CHANGE; - info->flags &= ~FBINFO_MISC_USEREVENT; - event.info = info; - event.data = &mode; - fb_notifier_call_chain(evnt, &event); - } - } + info->flags &= ~FBINFO_MISC_USEREVENT; + event.info = info; + event.data = &mode; + fb_notifier_call_chain(evnt, &event); } - done: return ret; } EXPORT_SYMBOL(fb_set_var); -- cgit From 9e1467002630065ed86c65ea28bfc9194fff6f0e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:02:59 +0200 Subject: fbcon: replace FB_EVENT_MODE_CHANGE/_ALL with direct calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Create a new wrapper function for this, feels like there's some refactoring room here between the two modes. v2: backlight notifier is also interested in the mode change event, it calls lcd->set_mode, of which there are 3 implementations. Thanks to Maarten for spotting this. So we keep that. We can ditch the differentiation between mode change and all mode changes (because backlight notifier doesn't care), and we can drop the FBINFO_MISC_USEREVENT stuff too, because that's just to prevent recursion between fbmem.c and fbcon.c. While at it flatten the control flow a bit. v3: Need to add a static inline to the dummy function. v4: Add missing #include to sh_mob (Sam). Cc: Sam Ravnborg Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Acked-by: Daniel Thompson Cc: Maarten Lankhorst Cc: Lee Jones Cc: Daniel Thompson Cc: Jingoo Han Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: Hans de Goede Cc: Yisheng Xie Cc: "Michał Mirosław" Cc: Peter Rosin Cc: Mikulas Patocka Cc: linux-fbdev@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-29-daniel.vetter@ffwll.ch --- drivers/video/backlight/lcd.c | 1 - drivers/video/fbdev/core/fbcon.c | 15 +++++++++------ drivers/video/fbdev/core/fbmem.c | 21 ++++++++++----------- drivers/video/fbdev/sh_mobile_lcdcfb.c | 12 ++---------- 4 files changed, 21 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 151b18776add..ecdda06989d0 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c @@ -34,7 +34,6 @@ static int fb_notifier_callback(struct notifier_block *self, switch (event) { case FB_EVENT_BLANK: case FB_EVENT_MODE_CHANGE: - case FB_EVENT_MODE_CHANGE_ALL: case FB_EARLY_EVENT_BLANK: case FB_R_EARLY_EVENT_BLANK: break; diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 4afbc7d8c68c..1837985e1ffb 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -3009,6 +3009,15 @@ static void fbcon_set_all_vcs(struct fb_info *info) fbcon_modechanged(info); } + +void fbcon_update_vcs(struct fb_info *info, bool all) +{ + if (all) + fbcon_set_all_vcs(info); + else + fbcon_modechanged(info); +} + int fbcon_mode_deleted(struct fb_info *info, struct fb_videomode *mode) { @@ -3318,12 +3327,6 @@ static int fbcon_event_notify(struct notifier_block *self, int idx, ret = 0; switch(action) { - case FB_EVENT_MODE_CHANGE: - fbcon_modechanged(info); - break; - case FB_EVENT_MODE_CHANGE_ALL: - fbcon_set_all_vcs(info); - break; case FB_EVENT_SET_CONSOLE_MAP: /* called with console lock held */ con2fb = event->data; diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 96805fe85332..dd1a708df1a7 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -957,6 +957,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) u32 activate; struct fb_var_screeninfo old_var; struct fb_videomode mode; + struct fb_event event; if (var->activate & FB_ACTIVATE_INV_MODE) { struct fb_videomode mode1, mode2; @@ -1039,19 +1040,17 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) !list_empty(&info->modelist)) ret = fb_add_videomode(&mode, &info->modelist); - if (!ret && (flags & FBINFO_MISC_USEREVENT)) { - struct fb_event event; - int evnt = (activate & FB_ACTIVATE_ALL) ? - FB_EVENT_MODE_CHANGE_ALL : - FB_EVENT_MODE_CHANGE; + if (ret) + return ret; - info->flags &= ~FBINFO_MISC_USEREVENT; - event.info = info; - event.data = &mode; - fb_notifier_call_chain(evnt, &event); - } + event.info = info; + event.data = &mode; + fb_notifier_call_chain(FB_EVENT_MODE_CHANGE, &event); - return ret; + if (flags & FBINFO_MISC_USEREVENT) + fbcon_update_vcs(info, activate & FB_ACTIVATE_ALL); + + return 0; } EXPORT_SYMBOL(fb_set_var); diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c index 015a02a29d37..b8454424910d 100644 --- a/drivers/video/fbdev/sh_mobile_lcdcfb.c +++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -1757,8 +1758,6 @@ static void sh_mobile_fb_reconfig(struct fb_info *info) struct sh_mobile_lcdc_chan *ch = info->par; struct fb_var_screeninfo var; struct fb_videomode mode; - struct fb_event event; - int evnt = FB_EVENT_MODE_CHANGE_ALL; if (ch->use_count > 1 || (ch->use_count == 1 && !info->fbcon_par)) /* More framebuffer users are active */ @@ -1780,14 +1779,7 @@ static void sh_mobile_fb_reconfig(struct fb_info *info) /* Couldn't reconfigure, hopefully, can continue as before */ return; - /* - * fb_set_var() calls the notifier change internally, only if - * FBINFO_MISC_USEREVENT flag is set. Since we do not want to fake a - * user event, we have to call the chain ourselves. - */ - event.info = info; - event.data = &ch->display.mode; - fb_notifier_call_chain(evnt, &event); + fbcon_update_vcs(info, true); } /* -- cgit From 1cd51b5d200dec292577a4656803d8aeff54ad51 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:03:00 +0200 Subject: vgaswitcheroo: call fbcon_remap_all directly While at it, clean up the interface a bit and push the console locking into fbcon.c. v2: Remove now outdated comment (Lukas). v3: Forgot to add static inline to the dummy function. Acked-by: Lukas Wunner Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Lukas Wunner Cc: David Airlie Cc: Daniel Vetter Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Sean Paul Cc: Bartlomiej Zolnierkiewicz Cc: Hans de Goede Cc: Yisheng Xie Cc: linux-fbdev@vger.kernel.org Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-30-daniel.vetter@ffwll.ch --- drivers/gpu/vga/vga_switcheroo.c | 11 +++-------- drivers/video/fbdev/core/fbcon.c | 14 +++++--------- 2 files changed, 8 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index a132c37d7334..65d7541c413a 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -736,14 +737,8 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) if (!active->driver_power_control) set_audio_state(active->id, VGA_SWITCHEROO_OFF); - if (new_client->fb_info) { - struct fb_event event; - - console_lock(); - event.info = new_client->fb_info; - fb_notifier_call_chain(FB_EVENT_REMAP_ALL_CONSOLE, &event); - console_unlock(); - } + if (new_client->fb_info) + fbcon_remap_all(new_client->fb_info); mutex_lock(&vgasr_priv.mux_hw_lock); ret = vgasr_priv.handler->switchto(new_client->id); diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 1837985e1ffb..44779a4371ee 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -3149,17 +3149,16 @@ void fbcon_fb_unregistered(struct fb_info *info) do_unregister_con_driver(&fb_con); } -/* called with console_lock held */ -static void fbcon_remap_all(int idx) +void fbcon_remap_all(struct fb_info *info) { - int i; - - WARN_CONSOLE_UNLOCKED(); + int i, idx = info->node; + console_lock(); if (deferred_takeover) { for (i = first_fb_vc; i <= last_fb_vc; i++) con2fb_map_boot[i] = idx; fbcon_map_override(); + console_unlock(); return; } @@ -3172,6 +3171,7 @@ static void fbcon_remap_all(int idx) first_fb_vc + 1, last_fb_vc + 1); info_idx = idx; } + console_unlock(); } #ifdef CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY @@ -3337,10 +3337,6 @@ static int fbcon_event_notify(struct notifier_block *self, con2fb = event->data; con2fb->framebuffer = con2fb_map[con2fb->console - 1]; break; - case FB_EVENT_REMAP_ALL_CONSOLE: - idx = info->node; - fbcon_remap_all(idx); - break; } return ret; } -- cgit From fe2d70d6f6ff038c20705c34695bd34ac072af14 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:03:01 +0200 Subject: fbcon: Call con2fb_map functions directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are actually fbcon ioctls which just happen to be exposed through /dev/fb*. They completely ignore which fb_info they're called on, and I think the userspace tool even hardcodes to /dev/fb0. Hence just forward the entire thing to fbcon.c wholesale. Note that this patch drops the fb_lock/unlock on the set side. Since the ioctl can operate on any fb (as passed in through con2fb.framebuffer) this is bogus. Also note that fbcon.c in general never calls fb_lock on anything, so this has been badly broken already. With this the last user of the fbcon notifier callback is gone, and we can garbage collect that too. v2: add missing uaccess.h include (alpha fails to compile otherwise), reported by kbuild. v3: Remember to also drop the #defines (Maarten) v4: Add the static inline to dummy functions. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Maarten Lankhorst Cc: Daniel Vetter Cc: Bartlomiej Zolnierkiewicz Cc: Hans de Goede Cc: Yisheng Xie Cc: "Michał Mirosław" Cc: Peter Rosin Cc: Mikulas Patocka Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-31-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbcon.c | 59 ++++++++++++++++++++++++---------------- drivers/video/fbdev/core/fbmem.c | 34 ++--------------------- 2 files changed, 38 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 44779a4371ee..31d6a4e54436 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -76,6 +76,7 @@ #include #include #include /* For counting font checksums */ +#include #include #include @@ -3318,29 +3319,47 @@ void fbcon_get_requirement(struct fb_info *info, } } -static int fbcon_event_notify(struct notifier_block *self, - unsigned long action, void *data) +int fbcon_set_con2fb_map_ioctl(void __user *argp) { - struct fb_event *event = data; - struct fb_info *info = event->info; - struct fb_con2fbmap *con2fb; - int idx, ret = 0; + struct fb_con2fbmap con2fb; + int ret; - switch(action) { - case FB_EVENT_SET_CONSOLE_MAP: - /* called with console lock held */ - con2fb = event->data; - ret = set_con2fb_map(con2fb->console - 1, - con2fb->framebuffer, 1); - break; - case FB_EVENT_GET_CONSOLE_MAP: - con2fb = event->data; - con2fb->framebuffer = con2fb_map[con2fb->console - 1]; - break; + if (copy_from_user(&con2fb, argp, sizeof(con2fb))) + return -EFAULT; + if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) + return -EINVAL; + if (con2fb.framebuffer >= FB_MAX) + return -EINVAL; + if (!registered_fb[con2fb.framebuffer]) + request_module("fb%d", con2fb.framebuffer); + if (!registered_fb[con2fb.framebuffer]) { + return -EINVAL; } + + console_lock(); + ret = set_con2fb_map(con2fb.console - 1, + con2fb.framebuffer, 1); + console_unlock(); + return ret; } +int fbcon_get_con2fb_map_ioctl(void __user *argp) +{ + struct fb_con2fbmap con2fb; + + if (copy_from_user(&con2fb, argp, sizeof(con2fb))) + return -EFAULT; + if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) + return -EINVAL; + + console_lock(); + con2fb.framebuffer = con2fb_map[con2fb.console - 1]; + console_unlock(); + + return copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; +} + /* * The console `switch' structure for the frame buffer based console */ @@ -3372,10 +3391,6 @@ static const struct consw fb_con = { .con_debug_leave = fbcon_debug_leave, }; -static struct notifier_block fbcon_event_notifier = { - .notifier_call = fbcon_event_notify, -}; - static ssize_t store_rotate(struct device *device, struct device_attribute *attr, const char *buf, size_t count) @@ -3648,7 +3663,6 @@ void __init fb_console_init(void) int i; console_lock(); - fb_register_client(&fbcon_event_notifier); fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL, "fbcon"); @@ -3684,7 +3698,6 @@ static void __exit fbcon_deinit_device(void) void __exit fb_console_exit(void) { console_lock(); - fb_unregister_client(&fbcon_event_notifier); fbcon_deinit_device(); device_destroy(fb_class, MKDEV(0, 0)); fbcon_exit(); diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index dd1a708df1a7..64dd732021d8 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1092,10 +1092,8 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, struct fb_ops *fb; struct fb_var_screeninfo var; struct fb_fix_screeninfo fix; - struct fb_con2fbmap con2fb; struct fb_cmap cmap_from; struct fb_cmap_user cmap; - struct fb_event event; void __user *argp = (void __user *)arg; long ret = 0; @@ -1157,38 +1155,10 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, ret = -EINVAL; break; case FBIOGET_CON2FBMAP: - if (copy_from_user(&con2fb, argp, sizeof(con2fb))) - return -EFAULT; - if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) - return -EINVAL; - con2fb.framebuffer = -1; - event.data = &con2fb; - lock_fb_info(info); - event.info = info; - fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); - unlock_fb_info(info); - ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; + ret = fbcon_get_con2fb_map_ioctl(argp); break; case FBIOPUT_CON2FBMAP: - if (copy_from_user(&con2fb, argp, sizeof(con2fb))) - return -EFAULT; - if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) - return -EINVAL; - if (con2fb.framebuffer >= FB_MAX) - return -EINVAL; - if (!registered_fb[con2fb.framebuffer]) - request_module("fb%d", con2fb.framebuffer); - if (!registered_fb[con2fb.framebuffer]) { - ret = -EINVAL; - break; - } - event.data = &con2fb; - console_lock(); - lock_fb_info(info); - event.info = info; - ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event); - unlock_fb_info(info); - console_unlock(); + ret = fbcon_set_con2fb_map_ioctl(argp); break; case FBIOBLANK: console_lock(); -- cgit From 94193d2aae63c49b706b1b7e535f23cfeccec93e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:03:02 +0200 Subject: fbcon: Document what I learned about fbcon locking It's not pretty. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Cc: Daniel Vetter Cc: Bartlomiej Zolnierkiewicz Cc: Hans de Goede Cc: Yisheng Xie Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-32-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbcon.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 31d6a4e54436..b8067e07f8a8 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -88,6 +88,25 @@ # define DPRINTK(fmt, args...) #endif +/* + * FIXME: Locking + * + * - fbcon state itself is protected by the console_lock, and the code does a + * pretty good job at making sure that lock is held everywhere it's needed. + * + * - access to the registered_fb array is entirely unprotected. This should use + * proper object lifetime handling, i.e. get/put_fb_info. This also means + * switching from indices to proper pointers for fb_info everywhere. + * + * - fbcon doesn't bother with fb_lock/unlock at all. This is buggy, since it + * means concurrent access to the same fbdev from both fbcon and userspace + * will blow up. To fix this all fbcon calls from fbmem.c need to be moved out + * of fb_lock/unlock protected sections, since otherwise we'll recurse and + * deadlock eventually. Aside: Due to these deadlock issues the fbdev code in + * fbmem.c cannot use locking asserts, and there's lots of callers which get + * the rules wrong, e.g. fbsysfs.c entirely missed fb_lock/unlock calls too. + */ + enum { FBCON_LOGO_CANSHOW = -1, /* the logo can be shown */ FBCON_LOGO_DRAW = -2, /* draw the logo to a console */ -- cgit From af1440368837f19ac7d5dec05d929d91308f5a90 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:03:03 +0200 Subject: staging/olpc_dcon: Add drm conversion to TODO this driver is pretty horrible from a design pov, and needs a complete overhaul. Concrete thing that annoys me is that it looks at registered_fb, which is an internal thing to fbmem.c and fbcon.c. And ofc it gets the lifetime rules all wrong (it should at least use get/put_fb_info). Looking at the history, there's been an attempt at dropping this from staging in 2016, but that had to be reverted. Since then not real effort except the usual stream of trivial patches, and fbdev has been formally closed for any new hw support. Time to try again and drop this? Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Acked-by: Greg Kroah-Hartman Reviewed-by: Maarten Lankhorst Cc: Greg Kroah-Hartman Cc: Jens Frederich Cc: Daniel Drake Cc: Jon Nettleton Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-33-daniel.vetter@ffwll.ch --- drivers/staging/olpc_dcon/TODO | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/olpc_dcon/TODO b/drivers/staging/olpc_dcon/TODO index 665a0b061719..fe09efbc7f77 100644 --- a/drivers/staging/olpc_dcon/TODO +++ b/drivers/staging/olpc_dcon/TODO @@ -1,4 +1,11 @@ TODO: + - complete rewrite: + 1. The underlying fbdev drivers need to be converted into drm kernel + modesetting drivers. + 2. The dcon low-power display mode can then be integrated using the + drm damage tracking and self-refresh helpers. + This bolted-on self-refresh support that digs around in fbdev + internals, but isn't properly integrated, is not the correct solution. - see if vx855 gpio API can be made similar enough to cs5535 so we can share more code - convert all uses of the old GPIO API from to the -- cgit From 1dcff4ae65185e8c0300972f6d8d39d9a9db2bda Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 28 May 2019 11:03:04 +0200 Subject: backlight: simplify lcd notifier With all the work I've done on replacing fb notifier calls with direct calls into fbcon the backlight/lcd notifier is the only user left. It will only receive events now that it cares about, hence we can remove this check. Signed-off-by: Daniel Vetter Reviewed-by: Sam Ravnborg Reviewed-by: Maarten Lankhorst Acked-by: Daniel Thompson Cc: Lee Jones Cc: Daniel Thompson Cc: Jingoo Han Link: https://patchwork.freedesktop.org/patch/msgid/20190528090304.9388-34-daniel.vetter@ffwll.ch --- drivers/video/backlight/lcd.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'drivers') diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index ecdda06989d0..d6b653aa4ee9 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c @@ -30,17 +30,6 @@ static int fb_notifier_callback(struct notifier_block *self, struct lcd_device *ld; struct fb_event *evdata = data; - /* If we aren't interested in this event, skip it immediately ... */ - switch (event) { - case FB_EVENT_BLANK: - case FB_EVENT_MODE_CHANGE: - case FB_EARLY_EVENT_BLANK: - case FB_R_EARLY_EVENT_BLANK: - break; - default: - return 0; - } - ld = container_of(self, struct lcd_device, fb_notif); if (!ld->ops) return 0; -- cgit From 2443091408c267f84b40025183490486b79ee2cd Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 19 Jun 2019 10:11:15 +0200 Subject: fbcon: Export fbcon_update_vcs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I failed to spot this while compile-testing. Oops. Reported-by: kbuild test robot Fixes: 9e1467002630 ("fbcon: replace FB_EVENT_MODE_CHANGE/_ALL with direct calls") Cc: Sam Ravnborg Cc: Daniel Vetter Cc: Maarten Lankhorst Cc: Daniel Thompson Cc: Lee Jones Cc: Jingoo Han Cc: Bartlomiej Zolnierkiewicz Cc: Daniel Vetter Cc: Hans de Goede Cc: Yisheng Xie Cc: "Michał Mirosław" Cc: Peter Rosin Cc: Mikulas Patocka Cc: linux-fbdev@vger.kernel.org Cc: Gerd Hoffmann Cc: Geert Uytterhoeven Cc: Lukas Wunner Cc: dri-devel@lists.freedesktop.org Signed-off-by: Daniel Vetter Signed-off-by: Maarten Lankhorst Link: https://patchwork.freedesktop.org/patch/msgid/20190619081115.27921-1-daniel.vetter@ffwll.ch --- drivers/video/fbdev/core/fbcon.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index b8067e07f8a8..c9235a2f42f8 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -3037,6 +3037,7 @@ void fbcon_update_vcs(struct fb_info *info, bool all) else fbcon_modechanged(info); } +EXPORT_SYMBOL(fbcon_update_vcs); int fbcon_mode_deleted(struct fb_info *info, struct fb_videomode *mode) -- cgit