[PATCH 10/10] fbcon: Put font-rotation state into separate struct

Thomas Zimmermann
2026-03-27T13:05:04Z

Move all temporary state of the font-rotation code into the struct
rotated in struct fbcon_par. Protect it with the Kconfig symbol
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION. Avoids mixing it up with fbcon's
regular state.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/video/fbdev/core/fbcon.c | 8 ++++++--
drivers/video/fbdev/core/fbcon.h | 12 +++++++----
drivers/video/fbdev/core/fbcon_ccw.c | 8 ++++----
drivers/video/fbdev/core/fbcon_cw.c | 8 ++++----
drivers/video/fbdev/core/fbcon_rotate.c | 27 +++++++++++++------------
drivers/video/fbdev/core/fbcon_ud.c | 10 ++++-----
6 files changed, 41 insertions(+), 32 deletions(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 345d9aa193f0..00fa5990dfc5 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -787,7 +787,9 @@ static void fbcon_release(struct fb_info *info)
kfree(par->cursor_state.mask);
kfree(par->cursor_data);
kfree(par->cursor_src);
- kfree(par->fontbuffer);
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
+ kfree(par->rotated.buf);
+#endif
kfree(info->fbcon_par);
info->fbcon_par = NULL;
}
@@ -1040,7 +1042,9 @@ static const char *fbcon_startup(void)
par = info->fbcon_par;
par->currcon = -1;
par->graphics = 1;
- par->cur_rotate = -1;
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
+ par->rotated.buf_rotate = -1;
+#endif

p->con_rotate = initial_rotation;
if (p->con_rotate == -1)
diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h
index bb0727b70631..5a3866b7ee33 100644
--- a/drivers/video/fbdev/core/fbcon.h
+++ b/drivers/video/fbdev/core/fbcon.h
@@ -80,13 +80,17 @@ struct fbcon_par {
int graphics;
bool initialized;
int rotate;
- int cur_rotate;
char *cursor_data;
- u8 *fontbuffer;
- const u8 *fontdata;
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION
+ struct {
+ font_data_t *fontdata; /* source font */
+ u8 *buf; /* rotated glphys */
+ size_t bufsize;
+ int buf_rotate; /* rotation of buf */
+ } rotated;
+#endif
u8 *cursor_src;
u32 cursor_size;
- size_t fd_size;

const struct fbcon_bitops *bitops;
};
diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c
index 723d9a33067f..33f02d579e02 100644
--- a/drivers/video/fbdev/core/fbcon_ccw.c
+++ b/drivers/video/fbdev/core/fbcon_ccw.c
@@ -106,7 +106,7 @@ static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
u8 *src;

while (cnt--) {
- src = par->fontbuffer + (scr_readw(s--) & charmask) * cellsize;
+ src = par->rotated.buf + (scr_readw(s--) & charmask) * cellsize;

if (attr) {
ccw_update_attr(buf, src, attr, vc);
@@ -142,7 +142,7 @@ static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
u8 *dst, *buf = NULL;
u32 vyres = GETVYRES(par->p, info);

- if (!par->fontbuffer)
+ if (!par->rotated.buf)
return;

image.fg_color = fg;
@@ -232,14 +232,14 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
char *src;
u32 vyres = GETVYRES(par->p, info);

- if (!par->fontbuffer)
+ if (!par->rotated.buf)
return;

cursor.set = 0;

c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
- src = par->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
+ src = par->rotated.buf + ((c & charmask) * (w * vc->vc_font.width));

if (par->cursor_state.image.data != src ||
par->cursor_reset) {
diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c
index 732d093d462f..bde820967eb9 100644
--- a/drivers/video/fbdev/core/fbcon_cw.c
+++ b/drivers/video/fbdev/core/fbcon_cw.c
@@ -91,7 +91,7 @@ static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
u8 *src;

while (cnt--) {
- src = par->fontbuffer + (scr_readw(s++) & charmask) * cellsize;
+ src = par->rotated.buf + (scr_readw(s++) & charmask) * cellsize;

if (attr) {
cw_update_attr(buf, src, attr, vc);
@@ -127,7 +127,7 @@ static void cw_putcs(struct vc_data *vc, struct fb_info *info,
u8 *dst, *buf = NULL;
u32 vxres = GETVXRES(par->p, info);

- if (!par->fontbuffer)
+ if (!par->rotated.buf)
return;

image.fg_color = fg;
@@ -215,14 +215,14 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
char *src;
u32 vxres = GETVXRES(par->p, info);

- if (!par->fontbuffer)
+ if (!par->rotated.buf)
return;

cursor.set = 0;

c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
- src = par->fontbuffer + ((c & charmask) * (w * vc->vc_font.width));
+ src = par->rotated.buf + ((c & charmask) * (w * vc->vc_font.width));

if (par->cursor_state.image.data != src ||
par->cursor_reset) {
diff --git a/drivers/video/fbdev/core/fbcon_rotate.c b/drivers/video/fbdev/core/fbcon_rotate.c
index 74206f5a6e98..6cdbc96eeca6 100644
--- a/drivers/video/fbdev/core/fbcon_rotate.c
+++ b/drivers/video/fbdev/core/fbcon_rotate.c
@@ -18,34 +18,35 @@
int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
{
struct fbcon_par *par = info->fbcon_par;
- unsigned char *fontbuffer;
+ unsigned char *buf;
int ret;

- if (vc->vc_font.data == par->fontdata &&
- par->p->con_rotate == par->cur_rotate)
+ if (par->p->fontdata == par->rotated.fontdata && par->rotate == par->rotated.buf_rotate)
return 0;

- par->fontdata = vc->vc_font.data;
- par->cur_rotate = par->p->con_rotate;
+ par->rotated.fontdata = par->p->fontdata;
+ par->rotated.buf_rotate = par->rotate;

if (info->fbops->fb_sync)
info->fbops->fb_sync(info);

- fontbuffer = font_data_rotate(par->p->fontdata, vc->vc_font.width,
- vc->vc_font.height, vc->vc_font.charcount,
- par->rotate, par->fontbuffer, &par->fd_size);
- if (IS_ERR(fontbuffer)) {
- ret = PTR_ERR(fontbuffer);
+ buf = font_data_rotate(par->rotated.fontdata, vc->vc_font.width,
+ vc->vc_font.height, vc->vc_font.charcount,
+ par->rotated.buf_rotate, par->rotated.buf,
+ &par->rotated.bufsize);
+ if (IS_ERR(buf)) {
+ ret = PTR_ERR(buf);
goto err_kfree;
}

- par->fontbuffer = fontbuffer;
+ par->rotated.buf = buf;

return 0;

err_kfree:
- kfree(par->fontbuffer);
- par->fontbuffer = NULL; /* clear here to avoid output */
+ kfree(par->rotated.buf);
+ par->rotated.buf = NULL; /* clear here to avoid output */
+ par->rotated.bufsize = 0;

return ret;
}
diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c
index a1981fa4701a..eaf08999e249 100644
--- a/drivers/video/fbdev/core/fbcon_ud.c
+++ b/drivers/video/fbdev/core/fbcon_ud.c
@@ -92,7 +92,7 @@ static inline void ud_putcs_aligned(struct vc_data *vc, struct fb_info *info,
u8 *src;

while (cnt--) {
- src = par->fontbuffer + (scr_readw(s--) & charmask) * cellsize;
+ src = par->rotated.buf + (scr_readw(s--) & charmask) * cellsize;

if (attr) {
ud_update_attr(buf, src, attr, vc);
@@ -127,7 +127,7 @@ static inline void ud_putcs_unaligned(struct vc_data *vc,
u8 *src;

while (cnt--) {
- src = par->fontbuffer + (scr_readw(s--) & charmask) * cellsize;
+ src = par->rotated.buf + (scr_readw(s--) & charmask) * cellsize;

if (attr) {
ud_update_attr(buf, src, attr, vc);
@@ -164,7 +164,7 @@ static void ud_putcs(struct vc_data *vc, struct fb_info *info,
u32 vyres = GETVYRES(par->p, info);
u32 vxres = GETVXRES(par->p, info);

- if (!par->fontbuffer)
+ if (!par->rotated.buf)
return;

image.fg_color = fg;
@@ -262,14 +262,14 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
u32 vyres = GETVYRES(par->p, info);
u32 vxres = GETVXRES(par->p, info);

- if (!par->fontbuffer)
+ if (!par->rotated.buf)
return;

cursor.set = 0;

c = scr_readw((u16 *) vc->vc_pos);
attribute = get_attribute(info, c);
- src = par->fontbuffer + ((c & charmask) * (w * vc->vc_font.height));
+ src = par->rotated.buf + ((c & charmask) * (w * vc->vc_font.height));

if (par->cursor_state.image.data != src ||
par->cursor_reset) {
--
2.53.0