* Re: [PATCH] staging: sm750fb: constify static char pointer arrays
From: Greg Kroah-Hartman @ 2026-03-31 8:45 UTC (permalink / raw)
To: Hungyu Lin
Cc: Sudip Mukherjee, Teddy Wang, linux-fbdev, linux-staging,
linux-kernel
In-Reply-To: <20260331050738.1547-1-dennylin0707@gmail.com>
On Tue, Mar 31, 2026 at 05:07:38AM +0000, Hungyu Lin wrote:
> The static const char * arrays 'g_fbmode' and 'fix_id' should be
> defined as 'static const char * const' to make the pointer arrays
> themselves constant. This allows the compiler to place them in the
> read-only data section.
>
> Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
> ---
> drivers/staging/sm750fb/sm750.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
> index 9a42a08c8..b0bdfaeca 100644
> --- a/drivers/staging/sm750fb/sm750.c
> +++ b/drivers/staging/sm750fb/sm750.c
> @@ -33,7 +33,7 @@
> static int g_hwcursor = 1;
> static int g_noaccel;
> static int g_nomtrr;
> -static const char *g_fbmode[] = {NULL, NULL};
> +static const char * const g_fbmode[] = {NULL, NULL};
> static const char *g_def_fbmode = "1024x768-32@60";
> static char *g_settings;
> static int g_dualview;
> @@ -728,7 +728,7 @@ static int lynxfb_set_fbinfo(struct fb_info *info, int index)
> lynx750_ext, NULL, vesa_modes,
> };
> int cdb[] = {ARRAY_SIZE(lynx750_ext), 0, VESA_MODEDB_SIZE};
> - static const char *fix_id[2] = {
> + static const char * const fix_id[2] = {
> "sm750_fb1", "sm750_fb2",
> };
>
> --
> 2.34.1
>
>
Please always test-build your changes so you do not get grumpy kernel
maintainers asking you why you did not test-build your changes :(
thanks,
greg k-h
^ permalink raw reply
* [PATCH] staging: sm750fb: constify static char pointer arrays
From: Hungyu Lin @ 2026-03-31 5:07 UTC (permalink / raw)
To: Sudip Mukherjee, Teddy Wang, Greg Kroah-Hartman
Cc: linux-fbdev, linux-staging, linux-kernel, Hungyu Lin
The static const char * arrays 'g_fbmode' and 'fix_id' should be
defined as 'static const char * const' to make the pointer arrays
themselves constant. This allows the compiler to place them in the
read-only data section.
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
---
drivers/staging/sm750fb/sm750.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 9a42a08c8..b0bdfaeca 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -33,7 +33,7 @@
static int g_hwcursor = 1;
static int g_noaccel;
static int g_nomtrr;
-static const char *g_fbmode[] = {NULL, NULL};
+static const char * const g_fbmode[] = {NULL, NULL};
static const char *g_def_fbmode = "1024x768-32@60";
static char *g_settings;
static int g_dualview;
@@ -728,7 +728,7 @@ static int lynxfb_set_fbinfo(struct fb_info *info, int index)
lynx750_ext, NULL, vesa_modes,
};
int cdb[] = {ARRAY_SIZE(lynx750_ext), 0, VESA_MODEDB_SIZE};
- static const char *fix_id[2] = {
+ static const char * const fix_id[2] = {
"sm750_fb1", "sm750_fb2",
};
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v2 1/3] staging: sm750fb: Rename enum sm750_pnltype values to snake_case
From: Greg KH @ 2026-03-30 15:55 UTC (permalink / raw)
To: Shubham Chakraborty
Cc: sudipm.mukherjee, teddy.wang, linux-fbdev, linux-staging,
linux-kernel
In-Reply-To: <20260318173440.9457-2-chakrabortyshubham66@gmail.com>
On Wed, Mar 18, 2026 at 11:04:38PM +0530, Shubham Chakraborty wrote:
> This patch renames the CamelCase enum values in sm750_pnltype to
> follow the Linux kernel coding style.
Your subject says something different from what you actually did in this
commit :(
^ permalink raw reply
* Re: [PATCH v2] staging: sm750fb: fix naming conventions and remove dead code
From: Greg KH @ 2026-03-30 15:54 UTC (permalink / raw)
To: Hadi Chokr
Cc: sudipm.mukherjee, teddy.wang, linux-fbdev, linux-staging,
linux-kernel
In-Reply-To: <20260327170846.11077-2-hadichokr@icloud.com>
On Fri, Mar 27, 2026 at 06:08:47PM +0100, Hadi Chokr wrote:
> - Convert camelCase to snake_case to fix all checkpatch warnings.
>
> - Remove unused function sm750_hw_cursor_set_data2() and its declaration.
>
> - checkpatch warned that g_fbmode should be 'static const char * const';
> this revealed that lynxfb_set_fbinfo() was writing back into g_fbmode
> unnecessarily. Refactor to resolve the mode string into a local
> const char * instead. Also drop the redundant NULL initializer since
> static storage is zero-initialized.
>
> - Remove manual write to pdev->dev.power.power_state.event in
> lynxfb_resume(); fb_set_suspend() already handles the resume state
> correctly.
>
> Changes in v2:
>
> - Further rename Hungarian-encoded or mixed-case variables etc. to descriptive names:
> pv_mem → fb_mem, pv_reg → reg_base, bpp → bits_per_pixel,
> src_delta → src_pitch, f_color → fg_color etc.
>
> Signed-off-by: Hadi Chokr <hadichokr@icloud.com>
> ---
> drivers/staging/sm750fb/readme | 6 +--
> drivers/staging/sm750fb/sm750.c | 71 +++++++++++++-------------
> drivers/staging/sm750fb/sm750.h | 26 +++++-----
> drivers/staging/sm750fb/sm750_accel.c | 32 ++++++------
> drivers/staging/sm750fb/sm750_accel.h | 44 ++++++++--------
> drivers/staging/sm750fb/sm750_cursor.c | 43 ----------------
> drivers/staging/sm750fb/sm750_cursor.h | 2 -
> drivers/staging/sm750fb/sm750_hw.c | 22 ++++----
> 8 files changed, 100 insertions(+), 146 deletions(-)
>
> diff --git a/drivers/staging/sm750fb/readme b/drivers/staging/sm750fb/readme
> index cfa45958b..95b7d2539 100644
> --- a/drivers/staging/sm750fb/readme
> +++ b/drivers/staging/sm750fb/readme
> @@ -7,7 +7,7 @@ Introduction:
>
> About the kernel module parameter of driver:
>
> - Use 1280,8bpp index color and 60 hz mode:
> + Use 1280,8 bits_per_pixel index color and 60 hz mode:
> insmod ./sm750fb.ko g_option="1280x1024-8@60"
>
> Disable MTRR,Disable 2d acceleration,Disable hardware cursor,
> @@ -29,8 +29,8 @@ About the kernel module parameter of driver:
> it equal to modular method with below command:
> insmod ./sm750fb.ko g_option="noaccel:1280x1024@60:otherparm:etc..."
>
> - 2) if you put 800x600 into the parameter without bpp and
> - refresh rate, kernel driver will defaulty use 16bpp and 60hz
> + 2) if you put 800x600 into the parameter without bits_per_pixel and
> + refresh rate, kernel driver will defaulty use 16 bits_per_pixel and 60hz
>
> Important:
> if you have vesafb enabled in your config then /dev/fb0 will be created by vesafb
> diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
> index 9a42a08c8..103258819 100644
> --- a/drivers/staging/sm750fb/sm750.c
> +++ b/drivers/staging/sm750fb/sm750.c
> @@ -33,7 +33,7 @@
> static int g_hwcursor = 1;
> static int g_noaccel;
> static int g_nomtrr;
> -static const char *g_fbmode[] = {NULL, NULL};
> +static const char *g_fbmode[2];
> static const char *g_def_fbmode = "1024x768-32@60";
> static char *g_settings;
> static int g_dualview;
> @@ -160,7 +160,7 @@ static void lynxfb_ops_fillrect(struct fb_info *info,
> {
> struct lynxfb_par *par;
> struct sm750_dev *sm750_dev;
> - unsigned int base, pitch, bpp, rop;
> + unsigned int base, pitch, bits_per_pixel, rop;
> u32 color;
>
> if (info->state != FBINFO_STATE_RUNNING)
> @@ -175,9 +175,9 @@ static void lynxfb_ops_fillrect(struct fb_info *info,
> */
> base = par->crtc.o_screen;
> pitch = info->fix.line_length;
> - bpp = info->var.bits_per_pixel >> 3;
> + bits_per_pixel = info->var.bits_per_pixel >> 3;
>
> - color = (bpp == 1) ? region->color :
> + color = (bits_per_pixel == 1) ? region->color :
> ((u32 *)info->pseudo_palette)[region->color];
> rop = (region->rop != ROP_COPY) ? HW_ROP2_XOR : HW_ROP2_COPY;
>
> @@ -190,7 +190,7 @@ static void lynxfb_ops_fillrect(struct fb_info *info,
> spin_lock(&sm750_dev->slock);
>
> sm750_dev->accel.de_fillrect(&sm750_dev->accel,
> - base, pitch, bpp,
> + base, pitch, bits_per_pixel,
> region->dx, region->dy,
> region->width, region->height,
> color, rop);
> @@ -202,7 +202,7 @@ static void lynxfb_ops_copyarea(struct fb_info *info,
> {
> struct lynxfb_par *par;
> struct sm750_dev *sm750_dev;
> - unsigned int base, pitch, bpp;
> + unsigned int base, pitch, bits_per_pixel;
>
> par = info->par;
> sm750_dev = par->dev;
> @@ -213,7 +213,7 @@ static void lynxfb_ops_copyarea(struct fb_info *info,
> */
> base = par->crtc.o_screen;
> pitch = info->fix.line_length;
> - bpp = info->var.bits_per_pixel >> 3;
> + bits_per_pixel = info->var.bits_per_pixel >> 3;
>
> /*
> * If not use spin_lock, system will die if user load driver
> @@ -225,7 +225,7 @@ static void lynxfb_ops_copyarea(struct fb_info *info,
>
> sm750_dev->accel.de_copyarea(&sm750_dev->accel,
> base, pitch, region->sx, region->sy,
> - base, pitch, bpp, region->dx, region->dy,
> + base, pitch, bits_per_pixel, region->dx, region->dy,
> region->width, region->height,
> HW_ROP2_COPY);
> spin_unlock(&sm750_dev->slock);
> @@ -234,7 +234,7 @@ static void lynxfb_ops_copyarea(struct fb_info *info,
> static void lynxfb_ops_imageblit(struct fb_info *info,
> const struct fb_image *image)
> {
> - unsigned int base, pitch, bpp;
> + unsigned int base, pitch, bits_per_pixel;
> unsigned int fgcol, bgcol;
> struct lynxfb_par *par;
> struct sm750_dev *sm750_dev;
> @@ -247,7 +247,7 @@ static void lynxfb_ops_imageblit(struct fb_info *info,
> */
> base = par->crtc.o_screen;
> pitch = info->fix.line_length;
> - bpp = info->var.bits_per_pixel >> 3;
> + bits_per_pixel = info->var.bits_per_pixel >> 3;
>
> /* TODO: Implement hardware acceleration for image->depth > 1 */
> if (image->depth != 1) {
> @@ -274,7 +274,7 @@ static void lynxfb_ops_imageblit(struct fb_info *info,
>
> sm750_dev->accel.de_imageblit(&sm750_dev->accel,
> image->data, image->width >> 3, 0,
> - base, pitch, bpp,
> + base, pitch, bits_per_pixel,
> image->dx, image->dy,
> image->width, image->height,
> fgcol, bgcol, HW_ROP2_COPY);
> @@ -388,7 +388,7 @@ static int lynxfb_ops_set_par(struct fb_info *info)
> var->accel_flags = 0;/*FB_ACCELF_TEXT;*/
>
> if (ret) {
> - dev_err(info->device, "bpp %d not supported\n",
> + dev_err(info->device, "bits_per_pixel %d not supported\n",
> var->bits_per_pixel);
> return ret;
> }
> @@ -467,8 +467,6 @@ static int __maybe_unused lynxfb_resume(struct device *dev)
> fb_set_suspend(info, 0);
> }
>
> - pdev->dev.power.power_state.event = PM_EVENT_RESUME;
> -
> console_unlock();
> return 0;
> }
> @@ -488,7 +486,7 @@ static int lynxfb_ops_check_var(struct fb_var_screeninfo *var,
> ret = lynxfb_set_color_offsets(info);
>
> if (ret) {
> - dev_err(info->device, "bpp %d not supported\n",
> + dev_err(info->device, "bits_per_pixel %d not supported\n",
> var->bits_per_pixel);
> return ret;
> }
> @@ -619,26 +617,26 @@ static int sm750fb_set_drv(struct lynxfb_par *par)
> output->paths = sm750_pnc;
> crtc->channel = sm750_primary;
> crtc->o_screen = 0;
> - crtc->v_screen = sm750_dev->pvMem;
> + crtc->v_screen = sm750_dev->fb_mem;
> break;
> case sm750_simul_sec:
> output->paths = sm750_pnc;
> crtc->channel = sm750_secondary;
> crtc->o_screen = 0;
> - crtc->v_screen = sm750_dev->pvMem;
> + crtc->v_screen = sm750_dev->fb_mem;
> break;
> case sm750_dual_normal:
> if (par->index == 0) {
> output->paths = sm750_panel;
> crtc->channel = sm750_primary;
> crtc->o_screen = 0;
> - crtc->v_screen = sm750_dev->pvMem;
> + crtc->v_screen = sm750_dev->fb_mem;
> } else {
> output->paths = sm750_crt;
> crtc->channel = sm750_secondary;
> /* not consider of padding stuffs for o_screen,need fix */
> crtc->o_screen = sm750_dev->vidmem_size >> 1;
> - crtc->v_screen = sm750_dev->pvMem + crtc->o_screen;
> + crtc->v_screen = sm750_dev->fb_mem + crtc->o_screen;
> }
> break;
> case sm750_dual_swap:
> @@ -646,7 +644,7 @@ static int sm750fb_set_drv(struct lynxfb_par *par)
> output->paths = sm750_panel;
> crtc->channel = sm750_secondary;
> crtc->o_screen = 0;
> - crtc->v_screen = sm750_dev->pvMem;
> + crtc->v_screen = sm750_dev->fb_mem;
> } else {
> output->paths = sm750_crt;
> crtc->channel = sm750_primary;
> @@ -654,7 +652,7 @@ static int sm750fb_set_drv(struct lynxfb_par *par)
> * need fix
> */
> crtc->o_screen = sm750_dev->vidmem_size >> 1;
> - crtc->v_screen = sm750_dev->pvMem + crtc->o_screen;
> + crtc->v_screen = sm750_dev->fb_mem + crtc->o_screen;
> }
> break;
> default:
> @@ -752,13 +750,13 @@ static int lynxfb_set_fbinfo(struct fb_info *info, int index)
> * must be set after crtc member initialized
> */
> crtc->cursor.offset = crtc->o_screen + crtc->vidmem_size - 1024;
> - crtc->cursor.mmio = sm750_dev->pvReg +
> + crtc->cursor.mmio = sm750_dev->reg_base +
> 0x800f0 + (int)crtc->channel * 0x140;
>
> crtc->cursor.max_h = 64;
> crtc->cursor.max_w = 64;
> crtc->cursor.size = crtc->cursor.max_h * crtc->cursor.max_w * 2 / 8;
> - crtc->cursor.vstart = sm750_dev->pvMem + crtc->cursor.offset;
> + crtc->cursor.vstart = sm750_dev->fb_mem + crtc->cursor.offset;
>
> memset_io(crtc->cursor.vstart, 0, crtc->cursor.size);
> if (!g_hwcursor)
> @@ -777,15 +775,16 @@ static int lynxfb_set_fbinfo(struct fb_info *info, int index)
> else
> info->fbops = &lynxfb_ops_with_cursor;
> }
> + const char *mode = g_fbmode[index];
>
> - if (!g_fbmode[index]) {
> - g_fbmode[index] = g_def_fbmode;
> - if (index)
> - g_fbmode[index] = g_fbmode[0];
> + if (!mode) {
> + mode = g_def_fbmode;
> + if (index && g_fbmode[0])
> + mode = g_fbmode[0];
> }
>
> for (i = 0; i < 3; i++) {
> - ret = fb_find_mode(var, info, g_fbmode[index],
> + ret = fb_find_mode(var, info, mode,
> pdb[i], cdb[i], NULL, 8);
>
> if (ret == 1 || ret == 2)
> @@ -856,9 +855,9 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src)
> sm750_dev->init_parm.chip_clk = 0;
> sm750_dev->init_parm.mem_clk = 0;
> sm750_dev->init_parm.master_clk = 0;
> - sm750_dev->init_parm.powerMode = 0;
> - sm750_dev->init_parm.setAllEngOff = 0;
> - sm750_dev->init_parm.resetMemory = 1;
> + sm750_dev->init_parm.power_mode = 0;
> + sm750_dev->init_parm.set_all_eng_off = 0;
> + sm750_dev->init_parm.reset_memory = 1;
>
> /* defaultly turn g_hwcursor on for both view */
> g_hwcursor = 3;
> @@ -877,9 +876,9 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src)
> } else if (!strncmp(opt, "nocrt", strlen("nocrt"))) {
> sm750_dev->nocrt = 1;
> } else if (!strncmp(opt, "36bit", strlen("36bit"))) {
> - sm750_dev->pnltype = sm750_doubleTFT;
> + sm750_dev->pnltype = sm750_double_tft;
> } else if (!strncmp(opt, "18bit", strlen("18bit"))) {
> - sm750_dev->pnltype = sm750_dualTFT;
> + sm750_dev->pnltype = sm750_dual_tft;
> } else if (!strncmp(opt, "24bit", strlen("24bit"))) {
> sm750_dev->pnltype = sm750_24TFT;
> } else if (!strncmp(opt, "nohwc0", strlen("nohwc0"))) {
> @@ -1025,7 +1024,7 @@ static int lynxfb_pci_probe(struct pci_dev *pdev,
> sm750_dev->mtrr.vram = arch_phys_wc_add(sm750_dev->vidmem_start,
> sm750_dev->vidmem_size);
>
> - memset_io(sm750_dev->pvMem, 0, sm750_dev->vidmem_size);
> + memset_io(sm750_dev->fb_mem, 0, sm750_dev->vidmem_size);
>
> pci_set_drvdata(pdev, sm750_dev);
>
> @@ -1056,8 +1055,8 @@ static void lynxfb_pci_remove(struct pci_dev *pdev)
> sm750fb_framebuffer_release(sm750_dev);
> arch_phys_wc_del(sm750_dev->mtrr.vram);
>
> - iounmap(sm750_dev->pvReg);
> - iounmap(sm750_dev->pvMem);
> + iounmap(sm750_dev->reg_base);
> + iounmap(sm750_dev->fb_mem);
> pci_release_region(pdev, 1);
> kfree(g_settings);
> }
> diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h
> index 67b9bfa23..130ec3770 100644
> --- a/drivers/staging/sm750fb/sm750.h
> +++ b/drivers/staging/sm750fb/sm750.h
> @@ -14,8 +14,8 @@
>
> enum sm750_pnltype {
> sm750_24TFT = 0, /* 24bit tft */
> - sm750_dualTFT = 2, /* dual 18 bit tft */
> - sm750_doubleTFT = 1, /* 36 bit double pixel tft */
> + sm750_dual_tft = 2, /* dual 18 bit tft */
> + sm750_double_tft = 1, /* 36 bit double pixel tft */
> };
>
> /* vga channel is not concerned */
> @@ -39,13 +39,13 @@ enum sm750_path {
> };
>
> struct init_status {
> - ushort powerMode;
> + ushort power_mode;
> /* below three clocks are in unit of MHZ*/
> ushort chip_clk;
> ushort mem_clk;
> ushort master_clk;
> - ushort setAllEngOff;
> - ushort resetMemory;
> + ushort set_all_eng_off;
> + ushort reset_memory;
> };
>
> struct lynx_accel {
> @@ -60,22 +60,22 @@ struct lynx_accel {
> int (*de_wait)(void);/* see if hardware ready to work */
>
> int (*de_fillrect)(struct lynx_accel *accel,
> - u32 base, u32 pitch, u32 bpp,
> + u32 base, u32 pitch, u32 bits_per_pixel,
> u32 x, u32 y, u32 width, u32 height,
> u32 color, u32 rop);
>
> int (*de_copyarea)(struct lynx_accel *accel,
> u32 s_base, u32 s_pitch,
> u32 sx, u32 sy,
> - u32 d_base, u32 d_pitch,
> - u32 bpp, u32 dx, u32 dy,
> + u32 dest_base, u32 dest_pitch,
> + u32 bits_per_pixel, u32 dx, u32 dy,
> u32 width, u32 height,
> u32 rop2);
>
> - int (*de_imageblit)(struct lynx_accel *accel, const char *p_srcbuf,
> - u32 src_delta, u32 start_bit, u32 d_base, u32 d_pitch,
> + int (*de_imageblit)(struct lynx_accel *accel, const char *src_buf,
> + u32 src_pitch, u32 start_bit, u32 dest_base, u32 dest_pitch,
> u32 byte_per_pixel, u32 dx, u32 dy, u32 width,
> - u32 height, u32 f_color, u32 b_color, u32 rop2);
> + u32 height, u32 fg_color, u32 bg_color, u32 rop2);
>
> };
>
> @@ -97,8 +97,8 @@ struct sm750_dev {
> unsigned long vidreg_start;
> __u32 vidmem_size;
> __u32 vidreg_size;
> - void __iomem *pvReg;
> - unsigned char __iomem *pvMem;
> + void __iomem *reg_base;
> + unsigned char __iomem *fb_mem;
> /* locks*/
> spinlock_t slock;
>
> diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c
> index 0f94d859e..b72d7f78e 100644
> --- a/drivers/staging/sm750fb/sm750_accel.c
> +++ b/drivers/staging/sm750fb/sm750_accel.c
> @@ -48,7 +48,7 @@ void sm750_hw_de_init(struct lynx_accel *accel)
> DE_STRETCH_FORMAT_ADDRESSING_MASK |
> DE_STRETCH_FORMAT_SOURCE_HEIGHT_MASK;
>
> - /* DE_STRETCH bpp format need be initialized in setMode routine */
> + /* DE_STRETCH bits_per_pixel format need be initialized in setMode routine */
> write_dpr(accel, DE_STRETCH_FORMAT,
> (read_dpr(accel, DE_STRETCH_FORMAT) & ~clr) | reg);
>
> @@ -76,7 +76,7 @@ void sm750_hw_set2dformat(struct lynx_accel *accel, int fmt)
> {
> u32 reg;
>
> - /* fmt=0,1,2 for 8,16,32,bpp on sm718/750/502 */
> + /* fmt=0,1,2 for 8,16,32,bits_per_pixel on sm718/750/502 */
> reg = read_dpr(accel, DE_STRETCH_FORMAT);
> reg &= ~DE_STRETCH_FORMAT_PIXEL_FORMAT_MASK;
> reg |= ((fmt << DE_STRETCH_FORMAT_PIXEL_FORMAT_SHIFT) &
> @@ -85,7 +85,7 @@ void sm750_hw_set2dformat(struct lynx_accel *accel, int fmt)
> }
>
> int sm750_hw_fillrect(struct lynx_accel *accel,
> - u32 base, u32 pitch, u32 Bpp,
> + u32 base, u32 pitch, u32 bits_per_pixel,
> u32 x, u32 y, u32 width, u32 height,
> u32 color, u32 rop)
> {
> @@ -102,14 +102,14 @@ int sm750_hw_fillrect(struct lynx_accel *accel,
>
> write_dpr(accel, DE_WINDOW_DESTINATION_BASE, base); /* dpr40 */
> write_dpr(accel, DE_PITCH,
> - ((pitch / Bpp << DE_PITCH_DESTINATION_SHIFT) &
> + ((pitch / bits_per_pixel << DE_PITCH_DESTINATION_SHIFT) &
> DE_PITCH_DESTINATION_MASK) |
> - (pitch / Bpp & DE_PITCH_SOURCE_MASK)); /* dpr10 */
> + (pitch / bits_per_pixel & DE_PITCH_SOURCE_MASK)); /* dpr10 */
>
> write_dpr(accel, DE_WINDOW_WIDTH,
> - ((pitch / Bpp << DE_WINDOW_WIDTH_DST_SHIFT) &
> + ((pitch / bits_per_pixel << DE_WINDOW_WIDTH_DST_SHIFT) &
> DE_WINDOW_WIDTH_DST_MASK) |
> - (pitch / Bpp & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr44 */
> + (pitch / bits_per_pixel & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr44 */
>
> write_dpr(accel, DE_FOREGROUND, color); /* DPR14 */
>
> @@ -138,7 +138,7 @@ int sm750_hw_fillrect(struct lynx_accel *accel,
> * @sy: Starting y coordinate of source surface
> * @dest_base: Address of destination: offset in frame buffer
> * @dest_pitch: Pitch value of destination surface in BYTE
> - * @Bpp: Color depth of destination surface
> + * @bits_per_pixel: Color depth of destination surface
> * @dx: Starting x coordinate of destination surface
> * @dy: Starting y coordinate of destination surface
> * @width: width of rectangle in pixel value
> @@ -149,7 +149,7 @@ int sm750_hw_copyarea(struct lynx_accel *accel,
> unsigned int source_base, unsigned int source_pitch,
> unsigned int sx, unsigned int sy,
> unsigned int dest_base, unsigned int dest_pitch,
> - unsigned int Bpp, unsigned int dx, unsigned int dy,
> + unsigned int bits_per_pixel, unsigned int dx, unsigned int dy,
> unsigned int width, unsigned int height,
> unsigned int rop2)
> {
> @@ -249,9 +249,9 @@ int sm750_hw_copyarea(struct lynx_accel *accel,
> * pixel values. Need Byte to pixel conversion.
> */
> write_dpr(accel, DE_PITCH,
> - ((dest_pitch / Bpp << DE_PITCH_DESTINATION_SHIFT) &
> + ((dest_pitch / bits_per_pixel << DE_PITCH_DESTINATION_SHIFT) &
> DE_PITCH_DESTINATION_MASK) |
> - (source_pitch / Bpp & DE_PITCH_SOURCE_MASK)); /* dpr10 */
> + (source_pitch / bits_per_pixel & DE_PITCH_SOURCE_MASK)); /* dpr10 */
>
> /*
> * Screen Window width in Pixels.
> @@ -259,9 +259,9 @@ int sm750_hw_copyarea(struct lynx_accel *accel,
> * for a given point.
> */
> write_dpr(accel, DE_WINDOW_WIDTH,
> - ((dest_pitch / Bpp << DE_WINDOW_WIDTH_DST_SHIFT) &
> + ((dest_pitch / bits_per_pixel << DE_WINDOW_WIDTH_DST_SHIFT) &
> DE_WINDOW_WIDTH_DST_MASK) |
> - (source_pitch / Bpp & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr3c */
> + (source_pitch / bits_per_pixel & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr3c */
>
> if (accel->de_wait() != 0)
> return -1;
> @@ -300,7 +300,7 @@ static unsigned int de_get_transparency(struct lynx_accel *accel)
> * sm750_hw_imageblit
> * @accel: Acceleration device data
> * @src_buf: pointer to start of source buffer in system memory
> - * @src_delta: Pitch value (in bytes) of the source buffer, +ive means top down
> + * @src_pitch: Pitch value (in bytes) of the source buffer, +ive means top down
> * and -ive mean button up
> * @start_bit: Mono data can start at any bit in a byte, this value should be
> * 0 to 7
> @@ -316,7 +316,7 @@ static unsigned int de_get_transparency(struct lynx_accel *accel)
> * @rop2: ROP value
> */
> int sm750_hw_imageblit(struct lynx_accel *accel, const char *src_buf,
> - u32 src_delta, u32 start_bit, u32 dest_base, u32 dest_pitch,
> + u32 src_pitch, u32 start_bit, u32 dest_base, u32 dest_pitch,
> u32 byte_per_pixel, u32 dx, u32 dy, u32 width,
> u32 height, u32 fg_color, u32 bg_color, u32 rop2)
> {
> @@ -405,7 +405,7 @@ int sm750_hw_imageblit(struct lynx_accel *accel, const char *src_buf,
> write_dp_port(accel, *(unsigned int *)remain);
> }
>
> - src_buf += src_delta;
> + src_buf += src_pitch;
> }
>
> return 0;
> diff --git a/drivers/staging/sm750fb/sm750_accel.h b/drivers/staging/sm750fb/sm750_accel.h
> index 2c79cb730..d0b3b653a 100644
> --- a/drivers/staging/sm750fb/sm750_accel.h
> +++ b/drivers/staging/sm750fb/sm750_accel.h
> @@ -190,19 +190,19 @@ void sm750_hw_set2dformat(struct lynx_accel *accel, int fmt);
> void sm750_hw_de_init(struct lynx_accel *accel);
>
> int sm750_hw_fillrect(struct lynx_accel *accel,
> - u32 base, u32 pitch, u32 Bpp,
> + u32 base, u32 pitch, u32 bits_per_pixel,
> u32 x, u32 y, u32 width, u32 height,
> u32 color, u32 rop);
>
> /**
> - * sm750_hm_copyarea
> - * @sBase: Address of source: offset in frame buffer
> - * @sPitch: Pitch value of source surface in BYTE
> + * sm750_hw_copyarea
> + * @s_base: Address of source: offset in frame buffer
> + * @s_pitch: Pitch value of source surface in BYTE
> * @sx: Starting x coordinate of source surface
> * @sy: Starting y coordinate of source surface
> - * @dBase: Address of destination: offset in frame buffer
> - * @dPitch: Pitch value of destination surface in BYTE
> - * @Bpp: Color depth of destination surface
> + * @dest_base: Address of destination: offset in frame buffer
> + * @dest_pitch: Pitch value of destination surface in BYTE
> + * @bits_per_pixel: Color depth of destination surface
> * @dx: Starting x coordinate of destination surface
> * @dy: Starting y coordinate of destination surface
> * @width: width of rectangle in pixel value
> @@ -210,34 +210,34 @@ int sm750_hw_fillrect(struct lynx_accel *accel,
> * @rop2: ROP value
> */
> int sm750_hw_copyarea(struct lynx_accel *accel,
> - unsigned int sBase, unsigned int sPitch,
> + unsigned int s_base, unsigned int s_pitch,
> unsigned int sx, unsigned int sy,
> - unsigned int dBase, unsigned int dPitch,
> - unsigned int Bpp, unsigned int dx, unsigned int dy,
> + unsigned int dest_base, unsigned int dest_pitch,
> + unsigned int bits_per_pixel, unsigned int dx, unsigned int dy,
> unsigned int width, unsigned int height,
> unsigned int rop2);
>
> /**
> * sm750_hw_imageblit
> - * @pSrcbuf: pointer to start of source buffer in system memory
> - * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top down
> + * @src_buf: pointer to start of source buffer in system memory
> + * @src_pitch: Pitch value (in bytes) of the source buffer, +ive means top down
> *>----- and -ive mean button up
> - * @startBit: Mono data can start at any bit in a byte, this value should be
> + * @start_bit: Mono data can start at any bit in a byte, this value should be
> *>----- 0 to 7
> - * @dBase: Address of destination: offset in frame buffer
> - * @dPitch: Pitch value of destination surface in BYTE
> - * @bytePerPixel: Color depth of destination surface
> + * @dest_base: Address of destination: offset in frame buffer
> + * @dest_pitch: Pitch value of destination surface in BYTE
> + * @byte_per_pixel: Color depth of destination surface
> * @dx: Starting x coordinate of destination surface
> * @dy: Starting y coordinate of destination surface
> * @width: width of rectangle in pixel value
> * @height: height of rectangle in pixel value
> - * @fColor: Foreground color (corresponding to a 1 in the monochrome data
> - * @bColor: Background color (corresponding to a 0 in the monochrome data
> + * @fg_color: Foreground color (corresponding to a 1 in the monochrome data
> + * @bg_color: Background color (corresponding to a 0 in the monochrome data
> * @rop2: ROP value
> */
> -int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf,
> - u32 srcDelta, u32 startBit, u32 dBase, u32 dPitch,
> - u32 bytePerPixel, u32 dx, u32 dy, u32 width,
> - u32 height, u32 fColor, u32 bColor, u32 rop2);
> +int sm750_hw_imageblit(struct lynx_accel *accel, const char *src_buf,
> + u32 src_pitch, u32 start_bit, u32 dest_base, u32 dest_pitch,
> + u32 byte_per_pixel, u32 dx, u32 dy, u32 width,
> + u32 height, u32 fg_color, u32 bg_color, u32 rop2);
>
> #endif
> diff --git a/drivers/staging/sm750fb/sm750_cursor.c b/drivers/staging/sm750fb/sm750_cursor.c
> index 7ede14490..f0338e6e7 100644
> --- a/drivers/staging/sm750fb/sm750_cursor.c
> +++ b/drivers/staging/sm750fb/sm750_cursor.c
> @@ -130,46 +130,3 @@ void sm750_hw_cursor_set_data(struct lynx_cursor *cursor, u16 rop,
> }
> }
> }
> -
> -void sm750_hw_cursor_set_data2(struct lynx_cursor *cursor, u16 rop,
> - const u8 *pcol, const u8 *pmsk)
> -{
> - int i, j, count, pitch, offset;
> - u8 color, mask;
> - u16 data;
> - void __iomem *pbuffer, *pstart;
> -
> - /* in byte*/
> - pitch = cursor->w >> 3;
> -
> - /* in byte */
> - count = pitch * cursor->h;
> -
> - /* in byte */
> - offset = cursor->max_w * 2 / 8;
> -
> - data = 0;
> - pstart = cursor->vstart;
> - pbuffer = pstart;
> -
> - for (i = 0; i < count; i++) {
> - color = *pcol++;
> - mask = *pmsk++;
> - data = 0;
> -
> - for (j = 0; j < 8; j++) {
> - if (mask & (1 << j))
> - data |= ((color & (1 << j)) ? 1 : 2) << (j * 2);
> - }
> - iowrite16(data, pbuffer);
> -
> - /* assume pitch is 1,2,4,8,...*/
> - if (!(i & (pitch - 1))) {
> - /* need a return */
> - pstart += offset;
> - pbuffer = pstart;
> - } else {
> - pbuffer += sizeof(u16);
> - }
> - }
> -}
> diff --git a/drivers/staging/sm750fb/sm750_cursor.h b/drivers/staging/sm750fb/sm750_cursor.h
> index 88fa02f63..51ba0da02 100644
> --- a/drivers/staging/sm750fb/sm750_cursor.h
> +++ b/drivers/staging/sm750fb/sm750_cursor.h
> @@ -10,6 +10,4 @@ void sm750_hw_cursor_set_pos(struct lynx_cursor *cursor, int x, int y);
> void sm750_hw_cursor_set_color(struct lynx_cursor *cursor, u32 fg, u32 bg);
> void sm750_hw_cursor_set_data(struct lynx_cursor *cursor, u16 rop,
> const u8 *data, const u8 *mask);
> -void sm750_hw_cursor_set_data2(struct lynx_cursor *cursor, u16 rop,
> - const u8 *data, const u8 *mask);
> #endif
> diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c
> index a2798d428..b1045b088 100644
> --- a/drivers/staging/sm750fb/sm750_hw.c
> +++ b/drivers/staging/sm750fb/sm750_hw.c
> @@ -42,18 +42,18 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
> }
>
> /* now map mmio and vidmem */
> - sm750_dev->pvReg =
> + sm750_dev->reg_base =
> ioremap(sm750_dev->vidreg_start, sm750_dev->vidreg_size);
> - if (!sm750_dev->pvReg) {
> + if (!sm750_dev->reg_base) {
> dev_err(&pdev->dev, "mmio failed\n");
> ret = -EFAULT;
> goto err_release_region;
> }
>
> - sm750_dev->accel.dpr_base = sm750_dev->pvReg + DE_BASE_ADDR_TYPE1;
> - sm750_dev->accel.dp_port_base = sm750_dev->pvReg + DE_PORT_ADDR_TYPE1;
> + sm750_dev->accel.dpr_base = sm750_dev->reg_base + DE_BASE_ADDR_TYPE1;
> + sm750_dev->accel.dp_port_base = sm750_dev->reg_base + DE_PORT_ADDR_TYPE1;
>
> - mmio750 = sm750_dev->pvReg;
> + mmio750 = sm750_dev->reg_base;
> sm750_set_chip_type(sm750_dev->devid, sm750_dev->revid);
>
> sm750_dev->vidmem_start = pci_resource_start(pdev, 0);
> @@ -66,9 +66,9 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
> sm750_dev->vidmem_size = ddk750_get_vm_size();
>
> /* reserve the vidmem space of smi adaptor */
> - sm750_dev->pvMem =
> + sm750_dev->fb_mem =
> ioremap_wc(sm750_dev->vidmem_start, sm750_dev->vidmem_size);
> - if (!sm750_dev->pvMem) {
> + if (!sm750_dev->fb_mem) {
> dev_err(&pdev->dev, "Map video memory failed\n");
> ret = -EFAULT;
> goto err_unmap_reg;
> @@ -77,7 +77,7 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
> return 0;
>
> err_unmap_reg:
> - iounmap(sm750_dev->pvReg);
> + iounmap(sm750_dev->reg_base);
> err_release_region:
> pci_release_region(pdev, 1);
> return ret;
> @@ -130,10 +130,10 @@ int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
> switch (sm750_dev->pnltype) {
> case sm750_24TFT:
> break;
> - case sm750_doubleTFT:
> + case sm750_double_tft:
> val |= PANEL_DISPLAY_CTRL_DOUBLE_PIXEL;
> break;
> - case sm750_dualTFT:
> + case sm750_dual_tft:
> val |= PANEL_DISPLAY_CTRL_DUAL_DISPLAY;
> break;
> }
> @@ -248,7 +248,7 @@ int hw_sm750_crtc_set_mode(struct lynxfb_crtc *crtc,
> sm750_dev = par->dev;
>
> if (!sm750_dev->accel_off) {
> - /* set 2d engine pixel format according to mode bpp */
> + /* set 2d engine pixel format according to mode bits_per_pixel */
> switch (var->bits_per_pixel) {
> case 8:
> fmt = 0;
> --
> 2.53.0
>
Hi,
This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him
a patch that has triggered this response. He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created. Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.
You are receiving this message because of the following common error(s)
as indicated below:
- Your patch did many different things all at once, making it difficult
to review. All Linux kernel patches need to only do one thing at a
time. If you need to do multiple things (such as clean up all coding
style issues in a file/driver), do it in a sequence of patches, each
one doing only one thing. This will make it easier to review the
patches to ensure that they are correct, and to help alleviate any
merge issues that larger patches can cause.
- This looks like a new version of a previously submitted patch, but you
did not list below the --- line any changes from the previous version.
Please read the section entitled "The canonical patch format" in the
kernel file, Documentation/process/submitting-patches.rst for what
needs to be done here to properly describe this.
If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.
thanks,
greg k-h's patch email bot
^ permalink raw reply
* Re: [PATCH 02/10] vt: Implement helpers for struct vc_font in source file
From: Greg KH @ 2026-03-30 15:35 UTC (permalink / raw)
To: Thomas Zimmermann
Cc: deller, jirislaby, simona, sam, linux-fbdev, dri-devel,
linux-kernel, linux-serial
In-Reply-To: <20260327130431.59481-3-tzimmermann@suse.de>
On Fri, Mar 27, 2026 at 01:49:35PM +0100, Thomas Zimmermann wrote:
> Move the helpers vc_font_pitch() and vc_font_size() from the VT
> header file into source file. They are not called very often, so
> there's no benefit in keeping them in the headers. Also avoids
> including <liux/math.h> from the header.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
> drivers/tty/vt/vt.c | 35 ++++++++++++++++++++++++++++++++++
> include/linux/console_struct.h | 30 ++---------------------------
> 2 files changed, 37 insertions(+), 28 deletions(-)
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
^ permalink raw reply
* Re: [PATCH v2 2/2] staging: greybus: switch sysfs show paths to sysfs_emit()
From: Greg KH @ 2026-03-30 15:23 UTC (permalink / raw)
To: Yug Merabtene
Cc: andy, hvaibhav.linux, johan, elder, vaibhav.sr, mgreer, rmfrfs,
pure.logic, dri-devel, linux-fbdev, greybus-dev, linux-staging,
linux-kernel
In-Reply-To: <20260329184124.775392-3-yug.merabtene@gmail.com>
On Sun, Mar 29, 2026 at 08:41:24PM +0200, Yug Merabtene wrote:
> Signed-off-by: Yug Merabtene <yug.merabtene@gmail.com>
> ---
> drivers/staging/greybus/arche-apb-ctrl.c | 12 ++++++------
> drivers/staging/greybus/arche-platform.c | 10 +++++-----
> drivers/staging/greybus/audio_manager_module.c | 12 ++++++------
> drivers/staging/greybus/gbphy.c | 2 +-
> drivers/staging/greybus/light.c | 4 ++--
> drivers/staging/greybus/loopback.c | 14 +++++++-------
> 6 files changed, 27 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c
> index 33f26a65f0cc..10effbe07a2a 100644
> --- a/drivers/staging/greybus/arche-apb-ctrl.c
> +++ b/drivers/staging/greybus/arche-apb-ctrl.c
> @@ -300,16 +300,16 @@ static ssize_t state_show(struct device *dev,
>
> switch (apb->state) {
> case ARCHE_PLATFORM_STATE_OFF:
> - return sprintf(buf, "off%s\n",
> - apb->init_disabled ? ",disabled" : "");
> + return sysfs_emit(buf, "off%s\n",
> + apb->init_disabled ? ",disabled" : "");
> case ARCHE_PLATFORM_STATE_ACTIVE:
> - return sprintf(buf, "active\n");
> + return sysfs_emit(buf, "active\n");
> case ARCHE_PLATFORM_STATE_STANDBY:
> - return sprintf(buf, "standby\n");
> + return sysfs_emit(buf, "standby\n");
> case ARCHE_PLATFORM_STATE_FW_FLASHING:
> - return sprintf(buf, "fw_flashing\n");
> + return sysfs_emit(buf, "fw_flashing\n");
> default:
> - return sprintf(buf, "unknown state\n");
> + return sysfs_emit(buf, "unknown state\n");
> }
> }
>
> diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c
> index f669a7e2eb11..de5de59ea8ab 100644
> --- a/drivers/staging/greybus/arche-platform.c
> +++ b/drivers/staging/greybus/arche-platform.c
> @@ -374,15 +374,15 @@ static ssize_t state_show(struct device *dev,
>
> switch (arche_pdata->state) {
> case ARCHE_PLATFORM_STATE_OFF:
> - return sprintf(buf, "off\n");
> + return sysfs_emit(buf, "off\n");
> case ARCHE_PLATFORM_STATE_ACTIVE:
> - return sprintf(buf, "active\n");
> + return sysfs_emit(buf, "active\n");
> case ARCHE_PLATFORM_STATE_STANDBY:
> - return sprintf(buf, "standby\n");
> + return sysfs_emit(buf, "standby\n");
> case ARCHE_PLATFORM_STATE_FW_FLASHING:
> - return sprintf(buf, "fw_flashing\n");
> + return sysfs_emit(buf, "fw_flashing\n");
> default:
> - return sprintf(buf, "unknown state\n");
> + return sysfs_emit(buf, "unknown state\n");
> }
> }
>
> diff --git a/drivers/staging/greybus/audio_manager_module.c b/drivers/staging/greybus/audio_manager_module.c
> index e87b82ca6d8a..f22ee73eb8d2 100644
> --- a/drivers/staging/greybus/audio_manager_module.c
> +++ b/drivers/staging/greybus/audio_manager_module.c
> @@ -76,7 +76,7 @@ static void gb_audio_module_release(struct kobject *kobj)
> static ssize_t gb_audio_module_name_show(struct gb_audio_manager_module *module,
> struct gb_audio_manager_module_attribute *attr, char *buf)
> {
> - return sprintf(buf, "%s", module->desc.name);
> + return sysfs_emit(buf, "%s\n", module->desc.name);
> }
>
> static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute =
> @@ -85,7 +85,7 @@ static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute =
> static ssize_t gb_audio_module_vid_show(struct gb_audio_manager_module *module,
> struct gb_audio_manager_module_attribute *attr, char *buf)
> {
> - return sprintf(buf, "%d", module->desc.vid);
> + return sysfs_emit(buf, "%d\n", module->desc.vid);
> }
>
> static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute =
> @@ -94,7 +94,7 @@ static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute =
> static ssize_t gb_audio_module_pid_show(struct gb_audio_manager_module *module,
> struct gb_audio_manager_module_attribute *attr, char *buf)
> {
> - return sprintf(buf, "%d", module->desc.pid);
> + return sysfs_emit(buf, "%d\n", module->desc.pid);
> }
>
> static struct gb_audio_manager_module_attribute gb_audio_module_pid_attribute =
> @@ -104,7 +104,7 @@ static ssize_t gb_audio_module_intf_id_show(struct gb_audio_manager_module *modu
> struct gb_audio_manager_module_attribute *attr,
> char *buf)
> {
> - return sprintf(buf, "%d", module->desc.intf_id);
> + return sysfs_emit(buf, "%d\n", module->desc.intf_id);
> }
>
> static struct gb_audio_manager_module_attribute
> @@ -115,7 +115,7 @@ static ssize_t gb_audio_module_ip_devices_show(struct gb_audio_manager_module *m
> struct gb_audio_manager_module_attribute *attr,
> char *buf)
> {
> - return sprintf(buf, "0x%X", module->desc.ip_devices);
> + return sysfs_emit(buf, "0x%X\n", module->desc.ip_devices);
> }
>
> static struct gb_audio_manager_module_attribute
> @@ -126,7 +126,7 @@ static ssize_t gb_audio_module_op_devices_show(struct gb_audio_manager_module *m
> struct gb_audio_manager_module_attribute *attr,
> char *buf)
> {
> - return sprintf(buf, "0x%X", module->desc.op_devices);
> + return sysfs_emit(buf, "0x%X\n", module->desc.op_devices);
> }
>
> static struct gb_audio_manager_module_attribute
> diff --git a/drivers/staging/greybus/gbphy.c b/drivers/staging/greybus/gbphy.c
> index bdb0f5164a6f..bb9a5b538e6e 100644
> --- a/drivers/staging/greybus/gbphy.c
> +++ b/drivers/staging/greybus/gbphy.c
> @@ -31,7 +31,7 @@ static ssize_t protocol_id_show(struct device *dev,
> {
> struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
>
> - return sprintf(buf, "0x%02x\n", gbphy_dev->cport_desc->protocol_id);
> + return sysfs_emit(buf, "0x%02x\n", gbphy_dev->cport_desc->protocol_id);
> }
> static DEVICE_ATTR_RO(protocol_id);
>
> diff --git a/drivers/staging/greybus/light.c b/drivers/staging/greybus/light.c
> index cab02b5da867..2689f9a7524a 100644
> --- a/drivers/staging/greybus/light.c
> +++ b/drivers/staging/greybus/light.c
> @@ -173,7 +173,7 @@ static ssize_t fade_##__dir##_show(struct device *dev, \
> struct led_classdev *cdev = dev_get_drvdata(dev); \
> struct gb_channel *channel = get_channel_from_cdev(cdev); \
> \
> - return sprintf(buf, "%u\n", channel->fade_##__dir); \
> + return sysfs_emit(buf, "%u\n", channel->fade_##__dir); \
> } \
> \
> static ssize_t fade_##__dir##_store(struct device *dev, \
> @@ -220,7 +220,7 @@ static ssize_t color_show(struct device *dev, struct device_attribute *attr,
> struct led_classdev *cdev = dev_get_drvdata(dev);
> struct gb_channel *channel = get_channel_from_cdev(cdev);
>
> - return sprintf(buf, "0x%08x\n", channel->color);
> + return sysfs_emit(buf, "0x%08x\n", channel->color);
> }
>
> static ssize_t color_store(struct device *dev, struct device_attribute *attr,
> diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c
> index aa9c73cb0ae5..3a502d89d19f 100644
> --- a/drivers/staging/greybus/loopback.c
> +++ b/drivers/staging/greybus/loopback.c
> @@ -125,7 +125,7 @@ static ssize_t field##_show(struct device *dev, \
> char *buf) \
> { \
> struct gb_loopback *gb = dev_get_drvdata(dev); \
> - return sprintf(buf, "%u\n", gb->field); \
> + return sysfs_emit(buf, "%u\n", gb->field); \
> } \
> static DEVICE_ATTR_RO(field)
>
> @@ -137,8 +137,8 @@ static ssize_t name##_##field##_show(struct device *dev, \
> struct gb_loopback *gb = dev_get_drvdata(dev); \
> /* Report 0 for min and max if no transfer succeeded */ \
> if (!gb->requests_completed) \
> - return sprintf(buf, "0\n"); \
> - return sprintf(buf, "%" #type "\n", gb->name.field); \
> + return sysfs_emit(buf, "0\n"); \
> + return sysfs_emit(buf, "%" #type "\n", gb->name.field); \
> } \
> static DEVICE_ATTR_RO(name##_##field)
>
> @@ -158,7 +158,7 @@ static ssize_t name##_avg_show(struct device *dev, \
> rem = do_div(avg, count); \
> rem *= 1000000; \
> do_div(rem, count); \
> - return sprintf(buf, "%llu.%06u\n", avg, (u32)rem); \
> + return sysfs_emit(buf, "%llu.%06u\n", avg, (u32)rem); \
> } \
> static DEVICE_ATTR_RO(name##_avg)
>
> @@ -173,7 +173,7 @@ static ssize_t field##_show(struct device *dev, \
> char *buf) \
> { \
> struct gb_loopback *gb = dev_get_drvdata(dev); \
> - return sprintf(buf, "%" #type "\n", gb->field); \
> + return sysfs_emit(buf, "%" #type "\n", gb->field); \
> } \
> static ssize_t field##_store(struct device *dev, \
> struct device_attribute *attr, \
> @@ -199,7 +199,7 @@ static ssize_t field##_show(struct device *dev, \
> char *buf) \
> { \
> struct gb_loopback *gb = dev_get_drvdata(dev); \
> - return sprintf(buf, "%u\n", gb->field); \
> + return sysfs_emit(buf, "%u\n", gb->field); \
> } \
> static DEVICE_ATTR_RO(field)
>
> @@ -209,7 +209,7 @@ static ssize_t field##_show(struct device *dev, \
> char *buf) \
> { \
> struct gb_loopback *gb = dev_get_drvdata(dev); \
> - return sprintf(buf, "%" #type "\n", gb->field); \
> + return sysfs_emit(buf, "%" #type "\n", gb->field); \
> } \
> static ssize_t field##_store(struct device *dev, \
> struct device_attribute *attr, \
> --
> 2.34.1
>
Hi,
This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him
a patch that has triggered this response. He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created. Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.
You are receiving this message because of the following common error(s)
as indicated below:
- You did not specify a description of why the patch is needed, or
possibly, any description at all, in the email body. Please read the
section entitled "The canonical patch format" in the kernel file,
Documentation/process/submitting-patches.rst for what is needed in
order to properly describe the change.
If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.
thanks,
greg k-h's patch email bot
^ permalink raw reply
* [PATCH] fbdev: atyfb: Remove unused fb_list
From: Geert Uytterhoeven @ 2026-03-30 9:44 UTC (permalink / raw)
To: Helge Deller
Cc: linux-fbdev, dri-devel, linux-kernel, Geert Uytterhoeven,
kernel test robot
With clang and W=1:
drivers/video/fbdev/aty/atyfb_base.c:2327:24: warning: variable 'fb_list' set but not used [-Wunused-but-set-global]
2327 | static struct fb_info *fb_list = NULL;
Indeed, the last user of fb_list was removed in 2004, while the actual
linked list was removed in 2002.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202603300931.osMYxYZ7-lkp@intel.com/
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
drivers/video/fbdev/aty/atyfb_base.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
index d5e107730a4d75dd..9fc5af09f86c4df2 100644
--- a/drivers/video/fbdev/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
@@ -2324,8 +2324,6 @@ static void aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
* Initialisation
*/
-static struct fb_info *fb_list = NULL;
-
#if defined(__i386__) && defined(CONFIG_FB_ATY_GENERIC_LCD)
static int atyfb_get_timings_from_lcd(struct atyfb_par *par,
struct fb_var_screeninfo *var)
@@ -2758,8 +2756,6 @@ static int aty_init(struct fb_info *info)
#endif
}
- fb_list = info;
-
PRINTKI("fb%d: %s frame buffer device on %s\n",
info->node, info->fix.id, par->bus_type == ISA ? "ISA" : "PCI");
return 0;
--
2.43.0
^ permalink raw reply related
* [PATCH] backlight: ktd2801: enable BL_CORE_SUSPENDRESUME
From: Duje Mihanović @ 2026-03-28 20:42 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Helge Deller
Cc: Karel Balej, dri-devel, linux-fbdev, phone-devel,
~postmarketos/upstreaming, linux-kernel, Duje Mihanović,
stable
From: Duje Mihanović <duje@dujemihanovic.xyz>
Boards using this backlight chip do not power the backlight off on
suspend. Enable BL_CORE_SUSPENDRESUME so the chip gets powered off by
the backlight core on suspend.
Tested on samsung,coreprimevelte.
Cc: stable@vger.kernel.org # v6.19
Signed-off-by: Duje Mihanović <duje@dujemihanovic.xyz>
---
drivers/video/backlight/ktd2801-backlight.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/video/backlight/ktd2801-backlight.c b/drivers/video/backlight/ktd2801-backlight.c
index 17eac1b3bce4..1b1307e03b20 100644
--- a/drivers/video/backlight/ktd2801-backlight.c
+++ b/drivers/video/backlight/ktd2801-backlight.c
@@ -53,6 +53,7 @@ static int ktd2801_update_status(struct backlight_device *bd)
}
static const struct backlight_ops ktd2801_backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
.update_status = ktd2801_update_status,
};
---
base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
change-id: 20260314-ktd2801-pm-fix-17e8715f8c37
Best regards,
--
Duje Mihanović <duje@dujemihanovic.xyz>
^ permalink raw reply related
* Re: [PATCH] staging: fbtft: avoid empty macro argument
From: Andy Shevchenko @ 2026-03-28 17:49 UTC (permalink / raw)
To: amanohina1
Cc: andy, gregkh, dri-devel, linux-fbdev, linux-staging, linux-kernel
In-Reply-To: <20260328160114.1143108-1-caiyuhe80@gmail.com>
On Sat, Mar 28, 2026 at 6:02 PM amanohina1 <caiyuhe80@gmail.com> wrote:
Read Submitting Patches documentation along with
https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git/tree/drivers/staging/fbtft/README?h=staging-next
Act accordingly.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [PATCH] staging: fbtft: avoid empty macro argument
From: amanohina1 @ 2026-03-28 16:01 UTC (permalink / raw)
To: andy, gregkh
Cc: dri-devel, linux-fbdev, linux-staging, linux-kernel, amanohina1
Signed-off-by: amanohina1 <caiyuhe80@gmail.com>
---
drivers/staging/fbtft/fbtft-bus.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c
index 30e436ff19e4..d1eb3fc03d7a 100644
--- a/drivers/staging/fbtft/fbtft-bus.c
+++ b/drivers/staging/fbtft/fbtft-bus.c
@@ -62,9 +62,11 @@ out: \
} \
EXPORT_SYMBOL(func);
-define_fbtft_write_reg(fbtft_write_reg8_bus8, u8, u8, )
+#define fbtft_nop(x) (x)
+
+define_fbtft_write_reg(fbtft_write_reg8_bus8, u8, u8, fbtft_nop)
define_fbtft_write_reg(fbtft_write_reg16_bus8, __be16, u16, cpu_to_be16)
-define_fbtft_write_reg(fbtft_write_reg16_bus16, u16, u16, )
+define_fbtft_write_reg(fbtft_write_reg16_bus16, u16, u16, fbtft_nop)
void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...)
{
--
2.34.1
^ permalink raw reply related
* [PATCH 2/2] MAINTAINERS: Add cgbc backlight driver
From: Thomas Richard @ 2026-03-27 19:39 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Helge Deller
Cc: Thomas Petazzoni, dri-devel, linux-fbdev, linux-kernel,
Thomas Richard
In-Reply-To: <20260327-backlight-cgbc-remove-x86-dependency-v1-0-4851c9e95371@bootlin.com>
Add missing backlight driver in CONGATEC BOARD CONTROLLER entry.
Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
---
MAINTAINERS | 1 +
1 file changed, 1 insertion(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 7d10988cbc62..c210dbb94459 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6476,6 +6476,7 @@ F: drivers/gpio/gpio-cgbc.c
F: drivers/hwmon/cgbc-hwmon.c
F: drivers/i2c/busses/i2c-cgbc.c
F: drivers/mfd/cgbc-core.c
+F: drivers/video/backlight/cgbc_bl.c
F: drivers/watchdog/cgbc_wdt.c
F: include/linux/mfd/cgbc.h
--
2.53.0
^ permalink raw reply related
* [PATCH 1/2] backlight: cgbc: Remove redundant X86 dependency
From: Thomas Richard @ 2026-03-27 19:39 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Helge Deller
Cc: Thomas Petazzoni, dri-devel, linux-fbdev, linux-kernel,
Thomas Richard
In-Reply-To: <20260327-backlight-cgbc-remove-x86-dependency-v1-0-4851c9e95371@bootlin.com>
The backlight driver depends on the MFD cgbc-core driver, which already
depends on X86. The explicit X86 dependency for the backlight driver is
redundant and can be safely removed.
Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
---
drivers/video/backlight/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index a7a3fbaf7c29..07905d2ba01a 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -260,7 +260,7 @@ config BACKLIGHT_PWM
config BACKLIGHT_CGBC
tristate "Congatec Board Controller (CGBC) backlight support"
- depends on MFD_CGBC && X86
+ depends on MFD_CGBC
help
Say Y here to enable support for LCD backlight control on Congatec
x86-based boards via the CGBC (Congatec Board Controller).
--
2.53.0
^ permalink raw reply related
* [PATCH 0/2] Remove redundant X86 dependency for the cgbc backlight driver
From: Thomas Richard @ 2026-03-27 19:39 UTC (permalink / raw)
To: Lee Jones, Daniel Thompson, Jingoo Han, Helge Deller
Cc: Thomas Petazzoni, dri-devel, linux-fbdev, linux-kernel,
Thomas Richard
Remove redundant X86 dependency for the cgbc backlight driver. Additionally
the driver is added to MAINTAINERS file.
Signed-off-by: Thomas Richard <thomas.richard@bootlin.com>
---
Thomas Richard (2):
backlight: cgbc: Remove redundant X86 dependency
MAINTAINERS: Add cgbc backlight driver
MAINTAINERS | 1 +
drivers/video/backlight/Kconfig | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
---
base-commit: c369299895a591d96745d6492d4888259b004a9e
change-id: 20260309-backlight-cgbc-remove-x86-dependency-40a7c9516459
Best regards,
--
Thomas Richard <thomas.richard@bootlin.com>
^ permalink raw reply
* [PATCH v2] staging: sm750fb: fix naming conventions and remove dead code
From: Hadi Chokr @ 2026-03-27 17:08 UTC (permalink / raw)
To: sudipm.mukherjee, teddy.wang
Cc: gregkh, linux-fbdev, linux-staging, linux-kernel, Hadi Chokr
In-Reply-To: <20260327091402.55366-1-hadichokr@icloud.com>
- Convert camelCase to snake_case to fix all checkpatch warnings.
- Remove unused function sm750_hw_cursor_set_data2() and its declaration.
- checkpatch warned that g_fbmode should be 'static const char * const';
this revealed that lynxfb_set_fbinfo() was writing back into g_fbmode
unnecessarily. Refactor to resolve the mode string into a local
const char * instead. Also drop the redundant NULL initializer since
static storage is zero-initialized.
- Remove manual write to pdev->dev.power.power_state.event in
lynxfb_resume(); fb_set_suspend() already handles the resume state
correctly.
Changes in v2:
- Further rename Hungarian-encoded or mixed-case variables etc. to descriptive names:
pv_mem → fb_mem, pv_reg → reg_base, bpp → bits_per_pixel,
src_delta → src_pitch, f_color → fg_color etc.
Signed-off-by: Hadi Chokr <hadichokr@icloud.com>
---
drivers/staging/sm750fb/readme | 6 +--
drivers/staging/sm750fb/sm750.c | 71 +++++++++++++-------------
drivers/staging/sm750fb/sm750.h | 26 +++++-----
drivers/staging/sm750fb/sm750_accel.c | 32 ++++++------
drivers/staging/sm750fb/sm750_accel.h | 44 ++++++++--------
drivers/staging/sm750fb/sm750_cursor.c | 43 ----------------
drivers/staging/sm750fb/sm750_cursor.h | 2 -
drivers/staging/sm750fb/sm750_hw.c | 22 ++++----
8 files changed, 100 insertions(+), 146 deletions(-)
diff --git a/drivers/staging/sm750fb/readme b/drivers/staging/sm750fb/readme
index cfa45958b..95b7d2539 100644
--- a/drivers/staging/sm750fb/readme
+++ b/drivers/staging/sm750fb/readme
@@ -7,7 +7,7 @@ Introduction:
About the kernel module parameter of driver:
- Use 1280,8bpp index color and 60 hz mode:
+ Use 1280,8 bits_per_pixel index color and 60 hz mode:
insmod ./sm750fb.ko g_option="1280x1024-8@60"
Disable MTRR,Disable 2d acceleration,Disable hardware cursor,
@@ -29,8 +29,8 @@ About the kernel module parameter of driver:
it equal to modular method with below command:
insmod ./sm750fb.ko g_option="noaccel:1280x1024@60:otherparm:etc..."
- 2) if you put 800x600 into the parameter without bpp and
- refresh rate, kernel driver will defaulty use 16bpp and 60hz
+ 2) if you put 800x600 into the parameter without bits_per_pixel and
+ refresh rate, kernel driver will defaulty use 16 bits_per_pixel and 60hz
Important:
if you have vesafb enabled in your config then /dev/fb0 will be created by vesafb
diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c
index 9a42a08c8..103258819 100644
--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -33,7 +33,7 @@
static int g_hwcursor = 1;
static int g_noaccel;
static int g_nomtrr;
-static const char *g_fbmode[] = {NULL, NULL};
+static const char *g_fbmode[2];
static const char *g_def_fbmode = "1024x768-32@60";
static char *g_settings;
static int g_dualview;
@@ -160,7 +160,7 @@ static void lynxfb_ops_fillrect(struct fb_info *info,
{
struct lynxfb_par *par;
struct sm750_dev *sm750_dev;
- unsigned int base, pitch, bpp, rop;
+ unsigned int base, pitch, bits_per_pixel, rop;
u32 color;
if (info->state != FBINFO_STATE_RUNNING)
@@ -175,9 +175,9 @@ static void lynxfb_ops_fillrect(struct fb_info *info,
*/
base = par->crtc.o_screen;
pitch = info->fix.line_length;
- bpp = info->var.bits_per_pixel >> 3;
+ bits_per_pixel = info->var.bits_per_pixel >> 3;
- color = (bpp == 1) ? region->color :
+ color = (bits_per_pixel == 1) ? region->color :
((u32 *)info->pseudo_palette)[region->color];
rop = (region->rop != ROP_COPY) ? HW_ROP2_XOR : HW_ROP2_COPY;
@@ -190,7 +190,7 @@ static void lynxfb_ops_fillrect(struct fb_info *info,
spin_lock(&sm750_dev->slock);
sm750_dev->accel.de_fillrect(&sm750_dev->accel,
- base, pitch, bpp,
+ base, pitch, bits_per_pixel,
region->dx, region->dy,
region->width, region->height,
color, rop);
@@ -202,7 +202,7 @@ static void lynxfb_ops_copyarea(struct fb_info *info,
{
struct lynxfb_par *par;
struct sm750_dev *sm750_dev;
- unsigned int base, pitch, bpp;
+ unsigned int base, pitch, bits_per_pixel;
par = info->par;
sm750_dev = par->dev;
@@ -213,7 +213,7 @@ static void lynxfb_ops_copyarea(struct fb_info *info,
*/
base = par->crtc.o_screen;
pitch = info->fix.line_length;
- bpp = info->var.bits_per_pixel >> 3;
+ bits_per_pixel = info->var.bits_per_pixel >> 3;
/*
* If not use spin_lock, system will die if user load driver
@@ -225,7 +225,7 @@ static void lynxfb_ops_copyarea(struct fb_info *info,
sm750_dev->accel.de_copyarea(&sm750_dev->accel,
base, pitch, region->sx, region->sy,
- base, pitch, bpp, region->dx, region->dy,
+ base, pitch, bits_per_pixel, region->dx, region->dy,
region->width, region->height,
HW_ROP2_COPY);
spin_unlock(&sm750_dev->slock);
@@ -234,7 +234,7 @@ static void lynxfb_ops_copyarea(struct fb_info *info,
static void lynxfb_ops_imageblit(struct fb_info *info,
const struct fb_image *image)
{
- unsigned int base, pitch, bpp;
+ unsigned int base, pitch, bits_per_pixel;
unsigned int fgcol, bgcol;
struct lynxfb_par *par;
struct sm750_dev *sm750_dev;
@@ -247,7 +247,7 @@ static void lynxfb_ops_imageblit(struct fb_info *info,
*/
base = par->crtc.o_screen;
pitch = info->fix.line_length;
- bpp = info->var.bits_per_pixel >> 3;
+ bits_per_pixel = info->var.bits_per_pixel >> 3;
/* TODO: Implement hardware acceleration for image->depth > 1 */
if (image->depth != 1) {
@@ -274,7 +274,7 @@ static void lynxfb_ops_imageblit(struct fb_info *info,
sm750_dev->accel.de_imageblit(&sm750_dev->accel,
image->data, image->width >> 3, 0,
- base, pitch, bpp,
+ base, pitch, bits_per_pixel,
image->dx, image->dy,
image->width, image->height,
fgcol, bgcol, HW_ROP2_COPY);
@@ -388,7 +388,7 @@ static int lynxfb_ops_set_par(struct fb_info *info)
var->accel_flags = 0;/*FB_ACCELF_TEXT;*/
if (ret) {
- dev_err(info->device, "bpp %d not supported\n",
+ dev_err(info->device, "bits_per_pixel %d not supported\n",
var->bits_per_pixel);
return ret;
}
@@ -467,8 +467,6 @@ static int __maybe_unused lynxfb_resume(struct device *dev)
fb_set_suspend(info, 0);
}
- pdev->dev.power.power_state.event = PM_EVENT_RESUME;
-
console_unlock();
return 0;
}
@@ -488,7 +486,7 @@ static int lynxfb_ops_check_var(struct fb_var_screeninfo *var,
ret = lynxfb_set_color_offsets(info);
if (ret) {
- dev_err(info->device, "bpp %d not supported\n",
+ dev_err(info->device, "bits_per_pixel %d not supported\n",
var->bits_per_pixel);
return ret;
}
@@ -619,26 +617,26 @@ static int sm750fb_set_drv(struct lynxfb_par *par)
output->paths = sm750_pnc;
crtc->channel = sm750_primary;
crtc->o_screen = 0;
- crtc->v_screen = sm750_dev->pvMem;
+ crtc->v_screen = sm750_dev->fb_mem;
break;
case sm750_simul_sec:
output->paths = sm750_pnc;
crtc->channel = sm750_secondary;
crtc->o_screen = 0;
- crtc->v_screen = sm750_dev->pvMem;
+ crtc->v_screen = sm750_dev->fb_mem;
break;
case sm750_dual_normal:
if (par->index == 0) {
output->paths = sm750_panel;
crtc->channel = sm750_primary;
crtc->o_screen = 0;
- crtc->v_screen = sm750_dev->pvMem;
+ crtc->v_screen = sm750_dev->fb_mem;
} else {
output->paths = sm750_crt;
crtc->channel = sm750_secondary;
/* not consider of padding stuffs for o_screen,need fix */
crtc->o_screen = sm750_dev->vidmem_size >> 1;
- crtc->v_screen = sm750_dev->pvMem + crtc->o_screen;
+ crtc->v_screen = sm750_dev->fb_mem + crtc->o_screen;
}
break;
case sm750_dual_swap:
@@ -646,7 +644,7 @@ static int sm750fb_set_drv(struct lynxfb_par *par)
output->paths = sm750_panel;
crtc->channel = sm750_secondary;
crtc->o_screen = 0;
- crtc->v_screen = sm750_dev->pvMem;
+ crtc->v_screen = sm750_dev->fb_mem;
} else {
output->paths = sm750_crt;
crtc->channel = sm750_primary;
@@ -654,7 +652,7 @@ static int sm750fb_set_drv(struct lynxfb_par *par)
* need fix
*/
crtc->o_screen = sm750_dev->vidmem_size >> 1;
- crtc->v_screen = sm750_dev->pvMem + crtc->o_screen;
+ crtc->v_screen = sm750_dev->fb_mem + crtc->o_screen;
}
break;
default:
@@ -752,13 +750,13 @@ static int lynxfb_set_fbinfo(struct fb_info *info, int index)
* must be set after crtc member initialized
*/
crtc->cursor.offset = crtc->o_screen + crtc->vidmem_size - 1024;
- crtc->cursor.mmio = sm750_dev->pvReg +
+ crtc->cursor.mmio = sm750_dev->reg_base +
0x800f0 + (int)crtc->channel * 0x140;
crtc->cursor.max_h = 64;
crtc->cursor.max_w = 64;
crtc->cursor.size = crtc->cursor.max_h * crtc->cursor.max_w * 2 / 8;
- crtc->cursor.vstart = sm750_dev->pvMem + crtc->cursor.offset;
+ crtc->cursor.vstart = sm750_dev->fb_mem + crtc->cursor.offset;
memset_io(crtc->cursor.vstart, 0, crtc->cursor.size);
if (!g_hwcursor)
@@ -777,15 +775,16 @@ static int lynxfb_set_fbinfo(struct fb_info *info, int index)
else
info->fbops = &lynxfb_ops_with_cursor;
}
+ const char *mode = g_fbmode[index];
- if (!g_fbmode[index]) {
- g_fbmode[index] = g_def_fbmode;
- if (index)
- g_fbmode[index] = g_fbmode[0];
+ if (!mode) {
+ mode = g_def_fbmode;
+ if (index && g_fbmode[0])
+ mode = g_fbmode[0];
}
for (i = 0; i < 3; i++) {
- ret = fb_find_mode(var, info, g_fbmode[index],
+ ret = fb_find_mode(var, info, mode,
pdb[i], cdb[i], NULL, 8);
if (ret == 1 || ret == 2)
@@ -856,9 +855,9 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src)
sm750_dev->init_parm.chip_clk = 0;
sm750_dev->init_parm.mem_clk = 0;
sm750_dev->init_parm.master_clk = 0;
- sm750_dev->init_parm.powerMode = 0;
- sm750_dev->init_parm.setAllEngOff = 0;
- sm750_dev->init_parm.resetMemory = 1;
+ sm750_dev->init_parm.power_mode = 0;
+ sm750_dev->init_parm.set_all_eng_off = 0;
+ sm750_dev->init_parm.reset_memory = 1;
/* defaultly turn g_hwcursor on for both view */
g_hwcursor = 3;
@@ -877,9 +876,9 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src)
} else if (!strncmp(opt, "nocrt", strlen("nocrt"))) {
sm750_dev->nocrt = 1;
} else if (!strncmp(opt, "36bit", strlen("36bit"))) {
- sm750_dev->pnltype = sm750_doubleTFT;
+ sm750_dev->pnltype = sm750_double_tft;
} else if (!strncmp(opt, "18bit", strlen("18bit"))) {
- sm750_dev->pnltype = sm750_dualTFT;
+ sm750_dev->pnltype = sm750_dual_tft;
} else if (!strncmp(opt, "24bit", strlen("24bit"))) {
sm750_dev->pnltype = sm750_24TFT;
} else if (!strncmp(opt, "nohwc0", strlen("nohwc0"))) {
@@ -1025,7 +1024,7 @@ static int lynxfb_pci_probe(struct pci_dev *pdev,
sm750_dev->mtrr.vram = arch_phys_wc_add(sm750_dev->vidmem_start,
sm750_dev->vidmem_size);
- memset_io(sm750_dev->pvMem, 0, sm750_dev->vidmem_size);
+ memset_io(sm750_dev->fb_mem, 0, sm750_dev->vidmem_size);
pci_set_drvdata(pdev, sm750_dev);
@@ -1056,8 +1055,8 @@ static void lynxfb_pci_remove(struct pci_dev *pdev)
sm750fb_framebuffer_release(sm750_dev);
arch_phys_wc_del(sm750_dev->mtrr.vram);
- iounmap(sm750_dev->pvReg);
- iounmap(sm750_dev->pvMem);
+ iounmap(sm750_dev->reg_base);
+ iounmap(sm750_dev->fb_mem);
pci_release_region(pdev, 1);
kfree(g_settings);
}
diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h
index 67b9bfa23..130ec3770 100644
--- a/drivers/staging/sm750fb/sm750.h
+++ b/drivers/staging/sm750fb/sm750.h
@@ -14,8 +14,8 @@
enum sm750_pnltype {
sm750_24TFT = 0, /* 24bit tft */
- sm750_dualTFT = 2, /* dual 18 bit tft */
- sm750_doubleTFT = 1, /* 36 bit double pixel tft */
+ sm750_dual_tft = 2, /* dual 18 bit tft */
+ sm750_double_tft = 1, /* 36 bit double pixel tft */
};
/* vga channel is not concerned */
@@ -39,13 +39,13 @@ enum sm750_path {
};
struct init_status {
- ushort powerMode;
+ ushort power_mode;
/* below three clocks are in unit of MHZ*/
ushort chip_clk;
ushort mem_clk;
ushort master_clk;
- ushort setAllEngOff;
- ushort resetMemory;
+ ushort set_all_eng_off;
+ ushort reset_memory;
};
struct lynx_accel {
@@ -60,22 +60,22 @@ struct lynx_accel {
int (*de_wait)(void);/* see if hardware ready to work */
int (*de_fillrect)(struct lynx_accel *accel,
- u32 base, u32 pitch, u32 bpp,
+ u32 base, u32 pitch, u32 bits_per_pixel,
u32 x, u32 y, u32 width, u32 height,
u32 color, u32 rop);
int (*de_copyarea)(struct lynx_accel *accel,
u32 s_base, u32 s_pitch,
u32 sx, u32 sy,
- u32 d_base, u32 d_pitch,
- u32 bpp, u32 dx, u32 dy,
+ u32 dest_base, u32 dest_pitch,
+ u32 bits_per_pixel, u32 dx, u32 dy,
u32 width, u32 height,
u32 rop2);
- int (*de_imageblit)(struct lynx_accel *accel, const char *p_srcbuf,
- u32 src_delta, u32 start_bit, u32 d_base, u32 d_pitch,
+ int (*de_imageblit)(struct lynx_accel *accel, const char *src_buf,
+ u32 src_pitch, u32 start_bit, u32 dest_base, u32 dest_pitch,
u32 byte_per_pixel, u32 dx, u32 dy, u32 width,
- u32 height, u32 f_color, u32 b_color, u32 rop2);
+ u32 height, u32 fg_color, u32 bg_color, u32 rop2);
};
@@ -97,8 +97,8 @@ struct sm750_dev {
unsigned long vidreg_start;
__u32 vidmem_size;
__u32 vidreg_size;
- void __iomem *pvReg;
- unsigned char __iomem *pvMem;
+ void __iomem *reg_base;
+ unsigned char __iomem *fb_mem;
/* locks*/
spinlock_t slock;
diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c
index 0f94d859e..b72d7f78e 100644
--- a/drivers/staging/sm750fb/sm750_accel.c
+++ b/drivers/staging/sm750fb/sm750_accel.c
@@ -48,7 +48,7 @@ void sm750_hw_de_init(struct lynx_accel *accel)
DE_STRETCH_FORMAT_ADDRESSING_MASK |
DE_STRETCH_FORMAT_SOURCE_HEIGHT_MASK;
- /* DE_STRETCH bpp format need be initialized in setMode routine */
+ /* DE_STRETCH bits_per_pixel format need be initialized in setMode routine */
write_dpr(accel, DE_STRETCH_FORMAT,
(read_dpr(accel, DE_STRETCH_FORMAT) & ~clr) | reg);
@@ -76,7 +76,7 @@ void sm750_hw_set2dformat(struct lynx_accel *accel, int fmt)
{
u32 reg;
- /* fmt=0,1,2 for 8,16,32,bpp on sm718/750/502 */
+ /* fmt=0,1,2 for 8,16,32,bits_per_pixel on sm718/750/502 */
reg = read_dpr(accel, DE_STRETCH_FORMAT);
reg &= ~DE_STRETCH_FORMAT_PIXEL_FORMAT_MASK;
reg |= ((fmt << DE_STRETCH_FORMAT_PIXEL_FORMAT_SHIFT) &
@@ -85,7 +85,7 @@ void sm750_hw_set2dformat(struct lynx_accel *accel, int fmt)
}
int sm750_hw_fillrect(struct lynx_accel *accel,
- u32 base, u32 pitch, u32 Bpp,
+ u32 base, u32 pitch, u32 bits_per_pixel,
u32 x, u32 y, u32 width, u32 height,
u32 color, u32 rop)
{
@@ -102,14 +102,14 @@ int sm750_hw_fillrect(struct lynx_accel *accel,
write_dpr(accel, DE_WINDOW_DESTINATION_BASE, base); /* dpr40 */
write_dpr(accel, DE_PITCH,
- ((pitch / Bpp << DE_PITCH_DESTINATION_SHIFT) &
+ ((pitch / bits_per_pixel << DE_PITCH_DESTINATION_SHIFT) &
DE_PITCH_DESTINATION_MASK) |
- (pitch / Bpp & DE_PITCH_SOURCE_MASK)); /* dpr10 */
+ (pitch / bits_per_pixel & DE_PITCH_SOURCE_MASK)); /* dpr10 */
write_dpr(accel, DE_WINDOW_WIDTH,
- ((pitch / Bpp << DE_WINDOW_WIDTH_DST_SHIFT) &
+ ((pitch / bits_per_pixel << DE_WINDOW_WIDTH_DST_SHIFT) &
DE_WINDOW_WIDTH_DST_MASK) |
- (pitch / Bpp & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr44 */
+ (pitch / bits_per_pixel & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr44 */
write_dpr(accel, DE_FOREGROUND, color); /* DPR14 */
@@ -138,7 +138,7 @@ int sm750_hw_fillrect(struct lynx_accel *accel,
* @sy: Starting y coordinate of source surface
* @dest_base: Address of destination: offset in frame buffer
* @dest_pitch: Pitch value of destination surface in BYTE
- * @Bpp: Color depth of destination surface
+ * @bits_per_pixel: Color depth of destination surface
* @dx: Starting x coordinate of destination surface
* @dy: Starting y coordinate of destination surface
* @width: width of rectangle in pixel value
@@ -149,7 +149,7 @@ int sm750_hw_copyarea(struct lynx_accel *accel,
unsigned int source_base, unsigned int source_pitch,
unsigned int sx, unsigned int sy,
unsigned int dest_base, unsigned int dest_pitch,
- unsigned int Bpp, unsigned int dx, unsigned int dy,
+ unsigned int bits_per_pixel, unsigned int dx, unsigned int dy,
unsigned int width, unsigned int height,
unsigned int rop2)
{
@@ -249,9 +249,9 @@ int sm750_hw_copyarea(struct lynx_accel *accel,
* pixel values. Need Byte to pixel conversion.
*/
write_dpr(accel, DE_PITCH,
- ((dest_pitch / Bpp << DE_PITCH_DESTINATION_SHIFT) &
+ ((dest_pitch / bits_per_pixel << DE_PITCH_DESTINATION_SHIFT) &
DE_PITCH_DESTINATION_MASK) |
- (source_pitch / Bpp & DE_PITCH_SOURCE_MASK)); /* dpr10 */
+ (source_pitch / bits_per_pixel & DE_PITCH_SOURCE_MASK)); /* dpr10 */
/*
* Screen Window width in Pixels.
@@ -259,9 +259,9 @@ int sm750_hw_copyarea(struct lynx_accel *accel,
* for a given point.
*/
write_dpr(accel, DE_WINDOW_WIDTH,
- ((dest_pitch / Bpp << DE_WINDOW_WIDTH_DST_SHIFT) &
+ ((dest_pitch / bits_per_pixel << DE_WINDOW_WIDTH_DST_SHIFT) &
DE_WINDOW_WIDTH_DST_MASK) |
- (source_pitch / Bpp & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr3c */
+ (source_pitch / bits_per_pixel & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr3c */
if (accel->de_wait() != 0)
return -1;
@@ -300,7 +300,7 @@ static unsigned int de_get_transparency(struct lynx_accel *accel)
* sm750_hw_imageblit
* @accel: Acceleration device data
* @src_buf: pointer to start of source buffer in system memory
- * @src_delta: Pitch value (in bytes) of the source buffer, +ive means top down
+ * @src_pitch: Pitch value (in bytes) of the source buffer, +ive means top down
* and -ive mean button up
* @start_bit: Mono data can start at any bit in a byte, this value should be
* 0 to 7
@@ -316,7 +316,7 @@ static unsigned int de_get_transparency(struct lynx_accel *accel)
* @rop2: ROP value
*/
int sm750_hw_imageblit(struct lynx_accel *accel, const char *src_buf,
- u32 src_delta, u32 start_bit, u32 dest_base, u32 dest_pitch,
+ u32 src_pitch, u32 start_bit, u32 dest_base, u32 dest_pitch,
u32 byte_per_pixel, u32 dx, u32 dy, u32 width,
u32 height, u32 fg_color, u32 bg_color, u32 rop2)
{
@@ -405,7 +405,7 @@ int sm750_hw_imageblit(struct lynx_accel *accel, const char *src_buf,
write_dp_port(accel, *(unsigned int *)remain);
}
- src_buf += src_delta;
+ src_buf += src_pitch;
}
return 0;
diff --git a/drivers/staging/sm750fb/sm750_accel.h b/drivers/staging/sm750fb/sm750_accel.h
index 2c79cb730..d0b3b653a 100644
--- a/drivers/staging/sm750fb/sm750_accel.h
+++ b/drivers/staging/sm750fb/sm750_accel.h
@@ -190,19 +190,19 @@ void sm750_hw_set2dformat(struct lynx_accel *accel, int fmt);
void sm750_hw_de_init(struct lynx_accel *accel);
int sm750_hw_fillrect(struct lynx_accel *accel,
- u32 base, u32 pitch, u32 Bpp,
+ u32 base, u32 pitch, u32 bits_per_pixel,
u32 x, u32 y, u32 width, u32 height,
u32 color, u32 rop);
/**
- * sm750_hm_copyarea
- * @sBase: Address of source: offset in frame buffer
- * @sPitch: Pitch value of source surface in BYTE
+ * sm750_hw_copyarea
+ * @s_base: Address of source: offset in frame buffer
+ * @s_pitch: Pitch value of source surface in BYTE
* @sx: Starting x coordinate of source surface
* @sy: Starting y coordinate of source surface
- * @dBase: Address of destination: offset in frame buffer
- * @dPitch: Pitch value of destination surface in BYTE
- * @Bpp: Color depth of destination surface
+ * @dest_base: Address of destination: offset in frame buffer
+ * @dest_pitch: Pitch value of destination surface in BYTE
+ * @bits_per_pixel: Color depth of destination surface
* @dx: Starting x coordinate of destination surface
* @dy: Starting y coordinate of destination surface
* @width: width of rectangle in pixel value
@@ -210,34 +210,34 @@ int sm750_hw_fillrect(struct lynx_accel *accel,
* @rop2: ROP value
*/
int sm750_hw_copyarea(struct lynx_accel *accel,
- unsigned int sBase, unsigned int sPitch,
+ unsigned int s_base, unsigned int s_pitch,
unsigned int sx, unsigned int sy,
- unsigned int dBase, unsigned int dPitch,
- unsigned int Bpp, unsigned int dx, unsigned int dy,
+ unsigned int dest_base, unsigned int dest_pitch,
+ unsigned int bits_per_pixel, unsigned int dx, unsigned int dy,
unsigned int width, unsigned int height,
unsigned int rop2);
/**
* sm750_hw_imageblit
- * @pSrcbuf: pointer to start of source buffer in system memory
- * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top down
+ * @src_buf: pointer to start of source buffer in system memory
+ * @src_pitch: Pitch value (in bytes) of the source buffer, +ive means top down
*>----- and -ive mean button up
- * @startBit: Mono data can start at any bit in a byte, this value should be
+ * @start_bit: Mono data can start at any bit in a byte, this value should be
*>----- 0 to 7
- * @dBase: Address of destination: offset in frame buffer
- * @dPitch: Pitch value of destination surface in BYTE
- * @bytePerPixel: Color depth of destination surface
+ * @dest_base: Address of destination: offset in frame buffer
+ * @dest_pitch: Pitch value of destination surface in BYTE
+ * @byte_per_pixel: Color depth of destination surface
* @dx: Starting x coordinate of destination surface
* @dy: Starting y coordinate of destination surface
* @width: width of rectangle in pixel value
* @height: height of rectangle in pixel value
- * @fColor: Foreground color (corresponding to a 1 in the monochrome data
- * @bColor: Background color (corresponding to a 0 in the monochrome data
+ * @fg_color: Foreground color (corresponding to a 1 in the monochrome data
+ * @bg_color: Background color (corresponding to a 0 in the monochrome data
* @rop2: ROP value
*/
-int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf,
- u32 srcDelta, u32 startBit, u32 dBase, u32 dPitch,
- u32 bytePerPixel, u32 dx, u32 dy, u32 width,
- u32 height, u32 fColor, u32 bColor, u32 rop2);
+int sm750_hw_imageblit(struct lynx_accel *accel, const char *src_buf,
+ u32 src_pitch, u32 start_bit, u32 dest_base, u32 dest_pitch,
+ u32 byte_per_pixel, u32 dx, u32 dy, u32 width,
+ u32 height, u32 fg_color, u32 bg_color, u32 rop2);
#endif
diff --git a/drivers/staging/sm750fb/sm750_cursor.c b/drivers/staging/sm750fb/sm750_cursor.c
index 7ede14490..f0338e6e7 100644
--- a/drivers/staging/sm750fb/sm750_cursor.c
+++ b/drivers/staging/sm750fb/sm750_cursor.c
@@ -130,46 +130,3 @@ void sm750_hw_cursor_set_data(struct lynx_cursor *cursor, u16 rop,
}
}
}
-
-void sm750_hw_cursor_set_data2(struct lynx_cursor *cursor, u16 rop,
- const u8 *pcol, const u8 *pmsk)
-{
- int i, j, count, pitch, offset;
- u8 color, mask;
- u16 data;
- void __iomem *pbuffer, *pstart;
-
- /* in byte*/
- pitch = cursor->w >> 3;
-
- /* in byte */
- count = pitch * cursor->h;
-
- /* in byte */
- offset = cursor->max_w * 2 / 8;
-
- data = 0;
- pstart = cursor->vstart;
- pbuffer = pstart;
-
- for (i = 0; i < count; i++) {
- color = *pcol++;
- mask = *pmsk++;
- data = 0;
-
- for (j = 0; j < 8; j++) {
- if (mask & (1 << j))
- data |= ((color & (1 << j)) ? 1 : 2) << (j * 2);
- }
- iowrite16(data, pbuffer);
-
- /* assume pitch is 1,2,4,8,...*/
- if (!(i & (pitch - 1))) {
- /* need a return */
- pstart += offset;
- pbuffer = pstart;
- } else {
- pbuffer += sizeof(u16);
- }
- }
-}
diff --git a/drivers/staging/sm750fb/sm750_cursor.h b/drivers/staging/sm750fb/sm750_cursor.h
index 88fa02f63..51ba0da02 100644
--- a/drivers/staging/sm750fb/sm750_cursor.h
+++ b/drivers/staging/sm750fb/sm750_cursor.h
@@ -10,6 +10,4 @@ void sm750_hw_cursor_set_pos(struct lynx_cursor *cursor, int x, int y);
void sm750_hw_cursor_set_color(struct lynx_cursor *cursor, u32 fg, u32 bg);
void sm750_hw_cursor_set_data(struct lynx_cursor *cursor, u16 rop,
const u8 *data, const u8 *mask);
-void sm750_hw_cursor_set_data2(struct lynx_cursor *cursor, u16 rop,
- const u8 *data, const u8 *mask);
#endif
diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c
index a2798d428..b1045b088 100644
--- a/drivers/staging/sm750fb/sm750_hw.c
+++ b/drivers/staging/sm750fb/sm750_hw.c
@@ -42,18 +42,18 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
}
/* now map mmio and vidmem */
- sm750_dev->pvReg =
+ sm750_dev->reg_base =
ioremap(sm750_dev->vidreg_start, sm750_dev->vidreg_size);
- if (!sm750_dev->pvReg) {
+ if (!sm750_dev->reg_base) {
dev_err(&pdev->dev, "mmio failed\n");
ret = -EFAULT;
goto err_release_region;
}
- sm750_dev->accel.dpr_base = sm750_dev->pvReg + DE_BASE_ADDR_TYPE1;
- sm750_dev->accel.dp_port_base = sm750_dev->pvReg + DE_PORT_ADDR_TYPE1;
+ sm750_dev->accel.dpr_base = sm750_dev->reg_base + DE_BASE_ADDR_TYPE1;
+ sm750_dev->accel.dp_port_base = sm750_dev->reg_base + DE_PORT_ADDR_TYPE1;
- mmio750 = sm750_dev->pvReg;
+ mmio750 = sm750_dev->reg_base;
sm750_set_chip_type(sm750_dev->devid, sm750_dev->revid);
sm750_dev->vidmem_start = pci_resource_start(pdev, 0);
@@ -66,9 +66,9 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
sm750_dev->vidmem_size = ddk750_get_vm_size();
/* reserve the vidmem space of smi adaptor */
- sm750_dev->pvMem =
+ sm750_dev->fb_mem =
ioremap_wc(sm750_dev->vidmem_start, sm750_dev->vidmem_size);
- if (!sm750_dev->pvMem) {
+ if (!sm750_dev->fb_mem) {
dev_err(&pdev->dev, "Map video memory failed\n");
ret = -EFAULT;
goto err_unmap_reg;
@@ -77,7 +77,7 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
return 0;
err_unmap_reg:
- iounmap(sm750_dev->pvReg);
+ iounmap(sm750_dev->reg_base);
err_release_region:
pci_release_region(pdev, 1);
return ret;
@@ -130,10 +130,10 @@ int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
switch (sm750_dev->pnltype) {
case sm750_24TFT:
break;
- case sm750_doubleTFT:
+ case sm750_double_tft:
val |= PANEL_DISPLAY_CTRL_DOUBLE_PIXEL;
break;
- case sm750_dualTFT:
+ case sm750_dual_tft:
val |= PANEL_DISPLAY_CTRL_DUAL_DISPLAY;
break;
}
@@ -248,7 +248,7 @@ int hw_sm750_crtc_set_mode(struct lynxfb_crtc *crtc,
sm750_dev = par->dev;
if (!sm750_dev->accel_off) {
- /* set 2d engine pixel format according to mode bpp */
+ /* set 2d engine pixel format according to mode bits_per_pixel */
switch (var->bits_per_pixel) {
case 8:
fmt = 0;
--
2.53.0
^ permalink raw reply related
* [PATCH 08/10] lib/fonts: Implement font rotation
From: Thomas Zimmermann @ 2026-03-27 12:49 UTC (permalink / raw)
To: deller, gregkh, jirislaby, simona, sam
Cc: linux-fbdev, dri-devel, linux-kernel, linux-serial,
Thomas Zimmermann
In-Reply-To: <20260327130431.59481-1-tzimmermann@suse.de>
Move the core of fbcon's font-rotation code to the font library as
the new helper font_data_rotate(). The code can rotate in steps of
90°. For completeness, it also copies the glyph data for multiples
of 360°.
Bring back the memset optimization. A memset to 0 again clears the
whole glyph output buffer. Then use the internal rotation helpers on
the cleared output. Fbcon's original implementation worked like this,
but lost it during refactoring.
Replace fbcon's font-rotation code with the new implementations.
All that's left to do for fbcon is to maintain its internal fbcon
state.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/video/fbdev/core/fbcon.h | 2 +-
drivers/video/fbdev/core/fbcon_rotate.c | 78 +++++-------------
include/linux/font.h | 3 +
lib/fonts/font_rotate.c | 103 ++++++++++++++++++++++++
4 files changed, 126 insertions(+), 60 deletions(-)
diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h
index 1e3c1ef84762..1793f34a6c84 100644
--- a/drivers/video/fbdev/core/fbcon.h
+++ b/drivers/video/fbdev/core/fbcon.h
@@ -86,7 +86,7 @@ struct fbcon_par {
const u8 *fontdata;
u8 *cursor_src;
u32 cursor_size;
- u32 fd_size;
+ size_t fd_size;
const struct fbcon_bitops *bitops;
};
diff --git a/drivers/video/fbdev/core/fbcon_rotate.c b/drivers/video/fbdev/core/fbcon_rotate.c
index 588dc9d6758a..74206f5a6e98 100644
--- a/drivers/video/fbdev/core/fbcon_rotate.c
+++ b/drivers/video/fbdev/core/fbcon_rotate.c
@@ -8,84 +8,44 @@
* more details.
*/
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/string.h>
+#include <linux/errno.h>
#include <linux/fb.h>
#include <linux/font.h>
-#include <linux/vt_kern.h>
-#include <linux/console.h>
-#include <asm/types.h>
+
#include "fbcon.h"
#include "fbcon_rotate.h"
int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
{
struct fbcon_par *par = info->fbcon_par;
- int len, err = 0;
- int s_cellsize, d_cellsize, i;
- const u8 *src;
- u8 *dst;
+ unsigned char *fontbuffer;
+ int ret;
if (vc->vc_font.data == par->fontdata &&
par->p->con_rotate == par->cur_rotate)
- goto finished;
+ return 0;
- src = par->fontdata = vc->vc_font.data;
+ par->fontdata = vc->vc_font.data;
par->cur_rotate = par->p->con_rotate;
- len = vc->vc_font.charcount;
- s_cellsize = font_glyph_size(vc->vc_font.width, vc->vc_font.height);
- d_cellsize = s_cellsize;
-
- if (par->rotate == FB_ROTATE_CW ||
- par->rotate == FB_ROTATE_CCW)
- d_cellsize = font_glyph_size(vc->vc_font.height, vc->vc_font.width);
if (info->fbops->fb_sync)
info->fbops->fb_sync(info);
- if (par->fd_size < d_cellsize * len) {
- kfree(par->fontbuffer);
- par->fontbuffer = NULL;
- par->fd_size = 0;
-
- dst = kmalloc_array(len, d_cellsize, GFP_KERNEL);
-
- if (dst == NULL) {
- err = -ENOMEM;
- goto finished;
- }
-
- par->fd_size = d_cellsize * len;
- par->fontbuffer = dst;
+ 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);
+ goto err_kfree;
}
- dst = par->fontbuffer;
+ par->fontbuffer = fontbuffer;
- switch (par->rotate) {
- case FB_ROTATE_UD:
- for (i = len; i--; ) {
- font_glyph_rotate_180(src, vc->vc_font.width, vc->vc_font.height, dst);
- src += s_cellsize;
- dst += d_cellsize;
- }
- break;
- case FB_ROTATE_CW:
- for (i = len; i--; ) {
- font_glyph_rotate_90(src, vc->vc_font.width, vc->vc_font.height, dst);
- src += s_cellsize;
- dst += d_cellsize;
- }
- break;
- case FB_ROTATE_CCW:
- for (i = len; i--; ) {
- font_glyph_rotate_270(src, vc->vc_font.width, vc->vc_font.height, dst);
- src += s_cellsize;
- dst += d_cellsize;
- }
- break;
- }
+ return 0;
+
+err_kfree:
+ kfree(par->fontbuffer);
+ par->fontbuffer = NULL; /* clear here to avoid output */
-finished:
- return err;
+ return ret;
}
diff --git a/include/linux/font.h b/include/linux/font.h
index 0a240dd70422..6845f02d739a 100644
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -111,6 +111,9 @@ void font_glyph_rotate_180(const unsigned char *glyph, unsigned int width, unsig
unsigned char *out);
void font_glyph_rotate_270(const unsigned char *glyph, unsigned int width, unsigned int height,
unsigned char *out);
+unsigned char *font_data_rotate(font_data_t *fd, unsigned int width, unsigned int height,
+ unsigned int charcount, unsigned int steps,
+ unsigned char *buf, size_t *bufsize);
/*
* Font description
diff --git a/lib/fonts/font_rotate.c b/lib/fonts/font_rotate.c
index f1e441a931ab..d8c8973310c2 100644
--- a/lib/fonts/font_rotate.c
+++ b/lib/fonts/font_rotate.c
@@ -9,8 +9,11 @@
* more details.
*/
+#include <linux/errno.h>
#include <linux/export.h>
#include <linux/math.h>
+#include <linux/overflow.h>
+#include <linux/slab.h>
#include <linux/string.h>
#include "font.h"
@@ -170,3 +173,103 @@ void font_glyph_rotate_270(const unsigned char *glyph, unsigned int width, unsig
__font_glyph_rotate_270(glyph, width, height, out);
}
EXPORT_SYMBOL_GPL(font_glyph_rotate_270);
+
+/**
+ * font_data_rotate - Rotate font data by multiples of 90°
+ * @fd: The font data to rotate
+ * @width: The glyph width in bits per scanline
+ * @height: The number of scanlines in the glyph
+ * @charcount: The number of glyphs in the font
+ * @steps: Number of rotation steps of 90°
+ * @buf: Preallocated output buffer; can be NULL
+ * @bufsize: The size of @buf in bytes; can be NULL
+ *
+ * The parameters @width and @height refer to the visible number of pixels
+ * and scanlines in a single glyph. The number of glyphs is given in @charcount.
+ * Rotation happens in steps of 90°. The @steps parameter can have any value,
+ * but only 0 to 3 produce distinct results. With 4 or higher, a full rotation
+ * has been performed. You can pass any value for @steps and the helper will
+ * perform the appropriate rotation. Note that the returned buffer is not
+ * compatible with font_data_t. It only contains glphy data in the same format
+ * as returned by font_data_buf(). Callers are responsible to free the returned
+ * buffer with kfree(). Font rotation typically happens when displays get
+ * re-oriented. To avoid unnecessary re-allocation of the memory buffer, the
+ * caller can pass in an earlier result buffer in @buf for reuse. The buffer
+ * size of given and returned in @bufsize. The allocation semantics are compatible
+ * with krealloc().
+ *
+ * Returns:
+ * A buffer with rotated glyphs on success, or an error pointer otherwise
+ */
+unsigned char *font_data_rotate(font_data_t *fd, unsigned int width, unsigned int height,
+ unsigned int charcount, unsigned int steps,
+ unsigned char *buf, size_t *bufsize)
+{
+ const unsigned char *src = font_data_buf(fd);
+ unsigned int s_cellsize = font_glyph_size(width, height);
+ unsigned int d_cellsize, i;
+ unsigned char *dst;
+ size_t size;
+
+ steps %= 4;
+
+ switch (steps) {
+ case 0:
+ case 2:
+ d_cellsize = s_cellsize;
+ break;
+ case 1:
+ case 3:
+ d_cellsize = font_glyph_size(height, width); /* flip width/height */
+ break;
+ }
+
+ if (check_mul_overflow(charcount, d_cellsize, &size))
+ return ERR_PTR(-EINVAL);
+
+ if (!buf || !bufsize || size > *bufsize) {
+ dst = kmalloc_array(charcount, d_cellsize, GFP_KERNEL);
+ if (!dst)
+ return ERR_PTR(-ENOMEM);
+
+ kfree(buf);
+ buf = dst;
+ if (bufsize)
+ *bufsize = size;
+ } else {
+ dst = buf;
+ }
+
+ switch (steps) {
+ case 0:
+ memcpy(dst, src, size);
+ break;
+ case 1:
+ memset(dst, 0, size);
+ for (i = 0; i < charcount; ++i) {
+ __font_glyph_rotate_90(src, width, height, dst);
+ src += s_cellsize;
+ dst += d_cellsize;
+ }
+ break;
+ case 2:
+ memset(dst, 0, size);
+ for (i = 0; i < charcount; ++i) {
+ __font_glyph_rotate_180(src, width, height, dst);
+ src += s_cellsize;
+ dst += d_cellsize;
+ }
+ break;
+ case 3:
+ memset(dst, 0, size);
+ for (i = 0; i < charcount; ++i) {
+ __font_glyph_rotate_270(src, width, height, dst);
+ src += s_cellsize;
+ dst += d_cellsize;
+ }
+ break;
+ }
+
+ return buf;
+}
+EXPORT_SYMBOL_GPL(font_data_rotate);
--
2.53.0
^ permalink raw reply related
* [PATCH 07/10] lib/fonts: Refactor glyph-rotation helpers
From: Thomas Zimmermann @ 2026-03-27 12:49 UTC (permalink / raw)
To: deller, gregkh, jirislaby, simona, sam
Cc: linux-fbdev, dri-devel, linux-kernel, linux-serial,
Thomas Zimmermann
In-Reply-To: <20260327130431.59481-1-tzimmermann@suse.de>
Change the signatures of the glyph-rotation helpers to match their
public interfaces. Drop the inline qualifier.
Rename several variables to better match their meaning. Especially
rename variables to bit_pitch (or a variant thereof) if they store
a pitch value in bits per scanline. The original code is fairly
confusing about this. Move the calculation of the bit pitch into the
new helper font_glyph_bit_pitch().
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
lib/fonts/font_rotate.c | 85 ++++++++++++++++++++++++-----------------
1 file changed, 49 insertions(+), 36 deletions(-)
diff --git a/lib/fonts/font_rotate.c b/lib/fonts/font_rotate.c
index cfaf5b98f49a..f1e441a931ab 100644
--- a/lib/fonts/font_rotate.c
+++ b/lib/fonts/font_rotate.c
@@ -15,6 +15,12 @@
#include "font.h"
+/* number of bits per line */
+static unsigned int font_glyph_bit_pitch(unsigned int width)
+{
+ return round_up(width, 8);
+}
+
static unsigned int __font_glyph_pos(unsigned int x, unsigned int y, unsigned int bit_pitch,
unsigned int *bit)
{
@@ -44,18 +50,21 @@ static void font_glyph_set_bit(unsigned char *glyph, unsigned int x, unsigned in
glyph[i] |= bit;
}
-static inline void rotate_cw(const char *in, char *out, u32 width, u32 height)
+static void __font_glyph_rotate_90(const unsigned char *glyph,
+ unsigned int width, unsigned int height,
+ unsigned char *out)
{
- int i, j, h = height, w = width;
- int shift = (8 - (height % 8)) & 7;
-
- width = (width + 7) & ~7;
- height = (height + 7) & ~7;
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- if (font_glyph_test_bit(in, j, i, width))
- font_glyph_set_bit(out, height - 1 - i - shift, j, height);
+ unsigned int x, y;
+ unsigned int shift = (8 - (height % 8)) & 7;
+ unsigned int bit_pitch = font_glyph_bit_pitch(width);
+ unsigned int out_bit_pitch = font_glyph_bit_pitch(height);
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ if (font_glyph_test_bit(glyph, x, y, bit_pitch)) {
+ font_glyph_set_bit(out, out_bit_pitch - 1 - y - shift, x,
+ out_bit_pitch);
+ }
}
}
}
@@ -79,22 +88,24 @@ void font_glyph_rotate_90(const unsigned char *glyph, unsigned int width, unsign
{
memset(out, 0, font_glyph_size(height, width)); /* flip width/height */
- rotate_cw(glyph, out, width, height);
+ __font_glyph_rotate_90(glyph, width, height, out);
}
EXPORT_SYMBOL_GPL(font_glyph_rotate_90);
-static inline void rotate_ud(const char *in, char *out, u32 width, u32 height)
+static void __font_glyph_rotate_180(const unsigned char *glyph,
+ unsigned int width, unsigned int height,
+ unsigned char *out)
{
- int i, j;
- int shift = (8 - (width % 8)) & 7;
-
- width = (width + 7) & ~7;
-
- for (i = 0; i < height; i++) {
- for (j = 0; j < width - shift; j++) {
- if (font_glyph_test_bit(in, j, i, width))
- font_glyph_set_bit(out, width - (1 + j + shift),
- height - (1 + i), width);
+ unsigned int x, y;
+ unsigned int shift = (8 - (width % 8)) & 7;
+ unsigned int bit_pitch = font_glyph_bit_pitch(width);
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ if (font_glyph_test_bit(glyph, x, y, bit_pitch)) {
+ font_glyph_set_bit(out, width - (1 + x + shift), height - (1 + y),
+ bit_pitch);
+ }
}
}
}
@@ -115,22 +126,24 @@ void font_glyph_rotate_180(const unsigned char *glyph, unsigned int width, unsig
{
memset(out, 0, font_glyph_size(width, height));
- rotate_ud(glyph, out, width, height);
+ __font_glyph_rotate_180(glyph, width, height, out);
}
EXPORT_SYMBOL_GPL(font_glyph_rotate_180);
-static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height)
+static void __font_glyph_rotate_270(const unsigned char *glyph,
+ unsigned int width, unsigned int height,
+ unsigned char *out)
{
- int i, j, h = height, w = width;
- int shift = (8 - (width % 8)) & 7;
-
- width = (width + 7) & ~7;
- height = (height + 7) & ~7;
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- if (font_glyph_test_bit(in, j, i, width))
- font_glyph_set_bit(out, i, width - 1 - j - shift, height);
+ unsigned int x, y;
+ unsigned int shift = (8 - (width % 8)) & 7;
+ unsigned int bit_pitch = font_glyph_bit_pitch(width);
+ unsigned int out_bit_pitch = font_glyph_bit_pitch(height);
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ if (font_glyph_test_bit(glyph, x, y, bit_pitch))
+ font_glyph_set_bit(out, y, bit_pitch - 1 - x - shift,
+ out_bit_pitch);
}
}
}
@@ -154,6 +167,6 @@ void font_glyph_rotate_270(const unsigned char *glyph, unsigned int width, unsig
{
memset(out, 0, font_glyph_size(height, width)); /* flip width/height */
- rotate_ccw(glyph, out, width, height);
+ __font_glyph_rotate_270(glyph, width, height, out);
}
EXPORT_SYMBOL_GPL(font_glyph_rotate_270);
--
2.53.0
^ permalink raw reply related
* [PATCH 10/10] fbcon: Put font-rotation state into separate struct
From: Thomas Zimmermann @ 2026-03-27 12:49 UTC (permalink / raw)
To: deller, gregkh, jirislaby, simona, sam
Cc: linux-fbdev, dri-devel, linux-kernel, linux-serial,
Thomas Zimmermann
In-Reply-To: <20260327130431.59481-1-tzimmermann@suse.de>
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
^ permalink raw reply related
* [PATCH 06/10] lib/fonts: Refactor glyph-pattern helpers
From: Thomas Zimmermann @ 2026-03-27 12:49 UTC (permalink / raw)
To: deller, gregkh, jirislaby, simona, sam
Cc: linux-fbdev, dri-devel, linux-kernel, linux-serial,
Thomas Zimmermann
In-Reply-To: <20260327130431.59481-1-tzimmermann@suse.de>
Change the signatures of the pattern helpers to align them with other
font-glyph helpers: use the font_glyph_ prefix and pass the glyph
buffer first.
Calculating the position of the involved bit is somewhat obfuscated
in the original implementation. Move it into the new helper
__font_glphy_pos() and use the result as array index and bit position.
Note that these bit helpers use a bit pitch, while other code uses a
byte pitch. This is intentional an required here.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
lib/fonts/font_rotate.c | 45 ++++++++++++++++++++++++-----------------
1 file changed, 27 insertions(+), 18 deletions(-)
diff --git a/lib/fonts/font_rotate.c b/lib/fonts/font_rotate.c
index 3e0a19c889f3..cfaf5b98f49a 100644
--- a/lib/fonts/font_rotate.c
+++ b/lib/fonts/font_rotate.c
@@ -15,21 +15,33 @@
#include "font.h"
-static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
+static unsigned int __font_glyph_pos(unsigned int x, unsigned int y, unsigned int bit_pitch,
+ unsigned int *bit)
{
- u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
+ unsigned int off = y * bit_pitch + x;
+ unsigned int bit_shift = off % 8;
- pat += index;
- return (*pat) & (0x80 >> bit);
+ *bit = 0x80 >> bit_shift; /* MSB has position 0, LSB has position 7 */
+
+ return off / 8;
}
-static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat)
+static bool font_glyph_test_bit(const unsigned char *glyph, unsigned int x, unsigned int y,
+ unsigned int bit_pitch)
{
- u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
+ unsigned int bit;
+ unsigned int i = __font_glyph_pos(x, y, bit_pitch, &bit);
+
+ return glyph[i] & bit;
+}
- pat += index;
+static void font_glyph_set_bit(unsigned char *glyph, unsigned int x, unsigned int y,
+ unsigned int bit_pitch)
+{
+ unsigned int bit;
+ unsigned int i = __font_glyph_pos(x, y, bit_pitch, &bit);
- (*pat) |= 0x80 >> bit;
+ glyph[i] |= bit;
}
static inline void rotate_cw(const char *in, char *out, u32 width, u32 height)
@@ -42,9 +54,8 @@ static inline void rotate_cw(const char *in, char *out, u32 width, u32 height)
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
- if (pattern_test_bit(j, i, width, in))
- pattern_set_bit(height - 1 - i - shift, j,
- height, out);
+ if (font_glyph_test_bit(in, j, i, width))
+ font_glyph_set_bit(out, height - 1 - i - shift, j, height);
}
}
}
@@ -81,10 +92,9 @@ static inline void rotate_ud(const char *in, char *out, u32 width, u32 height)
for (i = 0; i < height; i++) {
for (j = 0; j < width - shift; j++) {
- if (pattern_test_bit(j, i, width, in))
- pattern_set_bit(width - (1 + j + shift),
- height - (1 + i),
- width, out);
+ if (font_glyph_test_bit(in, j, i, width))
+ font_glyph_set_bit(out, width - (1 + j + shift),
+ height - (1 + i), width);
}
}
}
@@ -119,9 +129,8 @@ static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height)
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
- if (pattern_test_bit(j, i, width, in))
- pattern_set_bit(i, width - 1 - j - shift,
- height, out);
+ if (font_glyph_test_bit(in, j, i, width))
+ font_glyph_set_bit(out, i, width - 1 - j - shift, height);
}
}
}
--
2.53.0
^ permalink raw reply related
* [PATCH 09/10] fbcon: Fill cursor mask in helper function
From: Thomas Zimmermann @ 2026-03-27 12:49 UTC (permalink / raw)
To: deller, gregkh, jirislaby, simona, sam
Cc: linux-fbdev, dri-devel, linux-kernel, linux-serial,
Thomas Zimmermann
In-Reply-To: <20260327130431.59481-1-tzimmermann@suse.de>
Fbcon creates a cursor shape on the fly from the user-configured
settings. The logic to create a glyph with the cursor's bitmap mask
is duplicated in four places. In the cases that involve console
rotation, the implementation further rotates the cursor glyph for
displaying.
Consolidate all cursor-mask creation in a single helper. Update the
callers accordingly. For console rotation, use the glyph helpers to
rotate the created cursor glyph to the correct orientation.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/video/fbdev/core/bitblit.c | 35 ++-----------------
drivers/video/fbdev/core/fbcon.c | 40 ++++++++++++++++++++++
drivers/video/fbdev/core/fbcon.h | 2 ++
drivers/video/fbdev/core/fbcon_ccw.c | 51 ++++++----------------------
drivers/video/fbdev/core/fbcon_cw.c | 51 ++++++----------------------
drivers/video/fbdev/core/fbcon_ud.c | 50 +++++++--------------------
6 files changed, 78 insertions(+), 151 deletions(-)
diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c
index 7478accea8ec..65681dcc5930 100644
--- a/drivers/video/fbdev/core/bitblit.c
+++ b/drivers/video/fbdev/core/bitblit.c
@@ -329,46 +329,17 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
vc->vc_cursor_type != par->p->cursor_shape ||
par->cursor_state.mask == NULL ||
par->cursor_reset) {
- char *mask = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC);
- int cur_height, size, i = 0;
- u8 msk = 0xff;
+ unsigned char *mask = kmalloc_array(vc->vc_font.height, w, GFP_ATOMIC);
if (!mask)
return;
+ fbcon_fill_cursor_mask(par, vc, mask);
kfree(par->cursor_state.mask);
- par->cursor_state.mask = mask;
+ par->cursor_state.mask = (const char *)mask;
par->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
-
- switch (CUR_SIZE(par->p->cursor_shape)) {
- case CUR_NONE:
- cur_height = 0;
- break;
- case CUR_UNDERLINE:
- cur_height = (vc->vc_font.height < 10) ? 1 : 2;
- break;
- case CUR_LOWER_THIRD:
- cur_height = vc->vc_font.height/3;
- break;
- case CUR_LOWER_HALF:
- cur_height = vc->vc_font.height >> 1;
- break;
- case CUR_TWO_THIRDS:
- cur_height = (vc->vc_font.height << 1)/3;
- break;
- case CUR_BLOCK:
- default:
- cur_height = vc->vc_font.height;
- break;
- }
- size = (vc->vc_font.height - cur_height) * w;
- while (size--)
- mask[i++] = ~msk;
- size = cur_height * w;
- while (size--)
- mask[i++] = msk;
}
par->cursor_state.enable = enable && !use_sw;
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 8641b0b3edc4..345d9aa193f0 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -446,6 +446,46 @@ static void fbcon_del_cursor_work(struct fb_info *info)
cancel_delayed_work_sync(&par->cursor_work);
}
+void fbcon_fill_cursor_mask(struct fbcon_par *par, struct vc_data *vc, unsigned char *mask)
+{
+ static const unsigned char pattern = 0xff;
+ unsigned int pitch = vc_font_pitch(&vc->vc_font);
+ unsigned int cur_height, size;
+
+ switch (CUR_SIZE(vc->vc_cursor_type)) {
+ case CUR_NONE:
+ cur_height = 0;
+ break;
+ case CUR_UNDERLINE:
+ if (vc->vc_font.height < 10)
+ cur_height = 1;
+ else
+ cur_height = 2;
+ break;
+ case CUR_LOWER_THIRD:
+ cur_height = vc->vc_font.height / 3;
+ break;
+ case CUR_LOWER_HALF:
+ cur_height = vc->vc_font.height / 2;
+ break;
+ case CUR_TWO_THIRDS:
+ cur_height = (vc->vc_font.height * 2) / 3;
+ break;
+ case CUR_BLOCK:
+ default:
+ cur_height = vc->vc_font.height;
+ break;
+ }
+
+ size = (vc->vc_font.height - cur_height) * pitch;
+ while (size--)
+ *mask++ = (unsigned char)~pattern;
+
+ size = cur_height * pitch;
+ while (size--)
+ *mask++ = pattern;
+}
+
#ifndef MODULE
static int __init fb_console_setup(char *this_opt)
{
diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h
index 1793f34a6c84..bb0727b70631 100644
--- a/drivers/video/fbdev/core/fbcon.h
+++ b/drivers/video/fbdev/core/fbcon.h
@@ -192,6 +192,8 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
extern void fbcon_set_bitops_ur(struct fbcon_par *par);
extern int soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
+void fbcon_fill_cursor_mask(struct fbcon_par *par, struct vc_data *vc, unsigned char *mask);
+
#define FBCON_ATTRIBUTE_UNDERLINE 1
#define FBCON_ATTRIBUTE_REVERSE 2
#define FBCON_ATTRIBUTE_BOLD 4
diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c
index 72453a2aaca8..723d9a33067f 100644
--- a/drivers/video/fbdev/core/fbcon_ccw.c
+++ b/drivers/video/fbdev/core/fbcon_ccw.c
@@ -296,57 +296,26 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
vc->vc_cursor_type != par->p->cursor_shape ||
par->cursor_state.mask == NULL ||
par->cursor_reset) {
- char *tmp, *mask = kmalloc_array(w, vc->vc_font.width,
- GFP_ATOMIC);
- int cur_height, size, i = 0;
- int width = font_glyph_pitch(vc->vc_font.width);
+ unsigned char *tmp, *mask;
- if (!mask)
+ tmp = kmalloc_array(vc->vc_font.height, vc_font_pitch(&vc->vc_font), GFP_ATOMIC);
+ if (!tmp)
return;
+ fbcon_fill_cursor_mask(par, vc, tmp);
- tmp = kmalloc_array(width, vc->vc_font.height, GFP_ATOMIC);
-
- if (!tmp) {
- kfree(mask);
+ mask = kmalloc_array(vc->vc_font.width, w, GFP_ATOMIC);
+ if (!mask) {
+ kfree(tmp);
return;
}
+ font_glyph_rotate_270(tmp, vc->vc_font.width, vc->vc_font.height, mask);
+ kfree(tmp);
kfree(par->cursor_state.mask);
- par->cursor_state.mask = mask;
+ par->cursor_state.mask = (const char *)mask;
par->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
-
- switch (CUR_SIZE(par->p->cursor_shape)) {
- case CUR_NONE:
- cur_height = 0;
- break;
- case CUR_UNDERLINE:
- cur_height = (vc->vc_font.height < 10) ? 1 : 2;
- break;
- case CUR_LOWER_THIRD:
- cur_height = vc->vc_font.height/3;
- break;
- case CUR_LOWER_HALF:
- cur_height = vc->vc_font.height >> 1;
- break;
- case CUR_TWO_THIRDS:
- cur_height = (vc->vc_font.height << 1)/3;
- break;
- case CUR_BLOCK:
- default:
- cur_height = vc->vc_font.height;
- break;
- }
-
- size = (vc->vc_font.height - cur_height) * width;
- while (size--)
- tmp[i++] = 0;
- size = cur_height * width;
- while (size--)
- tmp[i++] = 0xff;
- font_glyph_rotate_270(tmp, vc->vc_font.width, vc->vc_font.height, mask);
- kfree(tmp);
}
par->cursor_state.enable = enable && !use_sw;
diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c
index 5690fc1d7854..732d093d462f 100644
--- a/drivers/video/fbdev/core/fbcon_cw.c
+++ b/drivers/video/fbdev/core/fbcon_cw.c
@@ -279,57 +279,26 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
vc->vc_cursor_type != par->p->cursor_shape ||
par->cursor_state.mask == NULL ||
par->cursor_reset) {
- char *tmp, *mask = kmalloc_array(w, vc->vc_font.width,
- GFP_ATOMIC);
- int cur_height, size, i = 0;
- int width = font_glyph_pitch(vc->vc_font.width);
+ unsigned char *tmp, *mask;
- if (!mask)
+ tmp = kmalloc_array(vc->vc_font.height, vc_font_pitch(&vc->vc_font), GFP_ATOMIC);
+ if (!tmp)
return;
+ fbcon_fill_cursor_mask(par, vc, tmp);
- tmp = kmalloc_array(width, vc->vc_font.height, GFP_ATOMIC);
-
- if (!tmp) {
- kfree(mask);
+ mask = kmalloc_array(vc->vc_font.width, w, GFP_ATOMIC);
+ if (!mask) {
+ kfree(tmp);
return;
}
+ font_glyph_rotate_90(tmp, vc->vc_font.width, vc->vc_font.height, mask);
+ kfree(tmp);
kfree(par->cursor_state.mask);
- par->cursor_state.mask = mask;
+ par->cursor_state.mask = (const char *)mask;
par->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
-
- switch (CUR_SIZE(par->p->cursor_shape)) {
- case CUR_NONE:
- cur_height = 0;
- break;
- case CUR_UNDERLINE:
- cur_height = (vc->vc_font.height < 10) ? 1 : 2;
- break;
- case CUR_LOWER_THIRD:
- cur_height = vc->vc_font.height/3;
- break;
- case CUR_LOWER_HALF:
- cur_height = vc->vc_font.height >> 1;
- break;
- case CUR_TWO_THIRDS:
- cur_height = (vc->vc_font.height << 1)/3;
- break;
- case CUR_BLOCK:
- default:
- cur_height = vc->vc_font.height;
- break;
- }
-
- size = (vc->vc_font.height - cur_height) * width;
- while (size--)
- tmp[i++] = 0;
- size = cur_height * width;
- while (size--)
- tmp[i++] = 0xff;
- font_glyph_rotate_90(tmp, vc->vc_font.width, vc->vc_font.height, mask);
- kfree(tmp);
}
par->cursor_state.enable = enable && !use_sw;
diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c
index f7cd89c42b01..a1981fa4701a 100644
--- a/drivers/video/fbdev/core/fbcon_ud.c
+++ b/drivers/video/fbdev/core/fbcon_ud.c
@@ -326,50 +326,26 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
vc->vc_cursor_type != par->p->cursor_shape ||
par->cursor_state.mask == NULL ||
par->cursor_reset) {
- char *mask = kmalloc_array(w, vc->vc_font.height, GFP_ATOMIC);
- int cur_height, size, i = 0;
- u8 msk = 0xff;
+ unsigned char *tmp, *mask;
- if (!mask)
+ tmp = kmalloc_array(vc->vc_font.height, w, GFP_ATOMIC);
+ if (!tmp)
return;
+ fbcon_fill_cursor_mask(par, vc, tmp);
+
+ mask = kmalloc_array(vc->vc_font.height, w, GFP_ATOMIC);
+ if (!mask) {
+ kfree(tmp);
+ return;
+ }
+ font_glyph_rotate_180(tmp, vc->vc_font.width, vc->vc_font.height, mask);
+ kfree(tmp);
kfree(par->cursor_state.mask);
- par->cursor_state.mask = mask;
+ par->cursor_state.mask = (const char *)mask;
par->p->cursor_shape = vc->vc_cursor_type;
cursor.set |= FB_CUR_SETSHAPE;
-
- switch (CUR_SIZE(par->p->cursor_shape)) {
- case CUR_NONE:
- cur_height = 0;
- break;
- case CUR_UNDERLINE:
- cur_height = (vc->vc_font.height < 10) ? 1 : 2;
- break;
- case CUR_LOWER_THIRD:
- cur_height = vc->vc_font.height/3;
- break;
- case CUR_LOWER_HALF:
- cur_height = vc->vc_font.height >> 1;
- break;
- case CUR_TWO_THIRDS:
- cur_height = (vc->vc_font.height << 1)/3;
- break;
- case CUR_BLOCK:
- default:
- cur_height = vc->vc_font.height;
- break;
- }
-
- size = cur_height * w;
-
- while (size--)
- mask[i++] = msk;
-
- size = (vc->vc_font.height - cur_height) * w;
-
- while (size--)
- mask[i++] = ~msk;
}
par->cursor_state.enable = enable && !use_sw;
--
2.53.0
^ permalink raw reply related
* [PATCH 04/10] lib/fonts: Clean up Makefile
From: Thomas Zimmermann @ 2026-03-27 12:49 UTC (permalink / raw)
To: deller, gregkh, jirislaby, simona, sam
Cc: linux-fbdev, dri-devel, linux-kernel, linux-serial,
Thomas Zimmermann
In-Reply-To: <20260327130431.59481-1-tzimmermann@suse.de>
Simplify the Makefile. Drop font-obj-y and sort the fonts by dictionary
order. Done in preparation for supporting optional font rotation.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
lib/fonts/Makefile | 35 +++++++++++++++++------------------
1 file changed, 17 insertions(+), 18 deletions(-)
diff --git a/lib/fonts/Makefile b/lib/fonts/Makefile
index 30a85a4292fa..3268d344c0a1 100644
--- a/lib/fonts/Makefile
+++ b/lib/fonts/Makefile
@@ -1,23 +1,22 @@
# SPDX-License-Identifier: GPL-2.0
# Font handling
-font-objs := fonts.o
+font-y := fonts.o
-font-objs-$(CONFIG_FONT_SUN8x16) += font_sun8x16.o
-font-objs-$(CONFIG_FONT_SUN12x22) += font_sun12x22.o
-font-objs-$(CONFIG_FONT_8x8) += font_8x8.o
-font-objs-$(CONFIG_FONT_8x16) += font_8x16.o
-font-objs-$(CONFIG_FONT_6x11) += font_6x11.o
-font-objs-$(CONFIG_FONT_7x14) += font_7x14.o
-font-objs-$(CONFIG_FONT_10x18) += font_10x18.o
-font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
-font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
-font-objs-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o
-font-objs-$(CONFIG_FONT_6x10) += font_6x10.o
-font-objs-$(CONFIG_FONT_TER10x18) += font_ter10x18.o
-font-objs-$(CONFIG_FONT_TER16x32) += font_ter16x32.o
-font-objs-$(CONFIG_FONT_6x8) += font_6x8.o
+# Built-in fonts
+font-$(CONFIG_FONT_10x18) += font_10x18.o
+font-$(CONFIG_FONT_6x10) += font_6x10.o
+font-$(CONFIG_FONT_6x11) += font_6x11.o
+font-$(CONFIG_FONT_6x8) += font_6x8.o
+font-$(CONFIG_FONT_7x14) += font_7x14.o
+font-$(CONFIG_FONT_8x16) += font_8x16.o
+font-$(CONFIG_FONT_8x8) += font_8x8.o
+font-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
+font-$(CONFIG_FONT_MINI_4x6) += font_mini_4x6.o
+font-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
+font-$(CONFIG_FONT_SUN12x22) += font_sun12x22.o
+font-$(CONFIG_FONT_SUN8x16) += font_sun8x16.o
+font-$(CONFIG_FONT_TER10x18) += font_ter10x18.o
+font-$(CONFIG_FONT_TER16x32) += font_ter16x32.o
-font-objs += $(font-objs-y)
-
-obj-$(CONFIG_FONT_SUPPORT) += font.o
+obj-$(CONFIG_FONT_SUPPORT) += font.o
--
2.53.0
^ permalink raw reply related
* [PATCH 05/10] lib/fonts: Implement glyph rotation
From: Thomas Zimmermann @ 2026-03-27 12:49 UTC (permalink / raw)
To: deller, gregkh, jirislaby, simona, sam
Cc: linux-fbdev, dri-devel, linux-kernel, linux-serial,
Thomas Zimmermann
In-Reply-To: <20260327130431.59481-1-tzimmermann@suse.de>
Move the glphy rotation helpers from fbcon to the font library. Wrap them
behind clean interfaces. Also clear the output memory to zero. Previously,
the implementation relied on the caller to do that.
Go through the fbcon code and callers of the glyph-rotation helpers. In
addition to the font rotation, there's also the cursor code, which uses
the rotation helpers.
The font-rotation relied on a single memset to zero for the whole font.
This is now multiple memsets on each glyph. This will be sorted out when
the font library also implements font rotation.
Building glyph rotation in the font library still depends on
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y. If we get more users of the code,
we can still add a dedicated Kconfig symbol to the font library.
No changes have been made to the actual implementation of the rotate_*()
and pattern_*() functions. These will be refactored as separate changes.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/video/fbdev/core/fbcon_ccw.c | 4 +-
drivers/video/fbdev/core/fbcon_cw.c | 4 +-
drivers/video/fbdev/core/fbcon_rotate.c | 12 +-
drivers/video/fbdev/core/fbcon_rotate.h | 71 -----------
include/linux/font.h | 8 ++
lib/fonts/Makefile | 1 +
lib/fonts/font_rotate.c | 150 ++++++++++++++++++++++++
7 files changed, 167 insertions(+), 83 deletions(-)
create mode 100644 lib/fonts/font_rotate.c
diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c
index 96ef449ee6ac..72453a2aaca8 100644
--- a/drivers/video/fbdev/core/fbcon_ccw.c
+++ b/drivers/video/fbdev/core/fbcon_ccw.c
@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/fb.h>
+#include <linux/font.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <asm/types.h>
@@ -344,8 +345,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
size = cur_height * width;
while (size--)
tmp[i++] = 0xff;
- memset(mask, 0, w * vc->vc_font.width);
- rotate_ccw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
+ font_glyph_rotate_270(tmp, vc->vc_font.width, vc->vc_font.height, mask);
kfree(tmp);
}
diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c
index ea712654edae..5690fc1d7854 100644
--- a/drivers/video/fbdev/core/fbcon_cw.c
+++ b/drivers/video/fbdev/core/fbcon_cw.c
@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/fb.h>
+#include <linux/font.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <asm/types.h>
@@ -327,8 +328,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
size = cur_height * width;
while (size--)
tmp[i++] = 0xff;
- memset(mask, 0, w * vc->vc_font.width);
- rotate_cw(tmp, mask, vc->vc_font.width, vc->vc_font.height);
+ font_glyph_rotate_90(tmp, vc->vc_font.width, vc->vc_font.height, mask);
kfree(tmp);
}
diff --git a/drivers/video/fbdev/core/fbcon_rotate.c b/drivers/video/fbdev/core/fbcon_rotate.c
index 18575c5182db..588dc9d6758a 100644
--- a/drivers/video/fbdev/core/fbcon_rotate.c
+++ b/drivers/video/fbdev/core/fbcon_rotate.c
@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/fb.h>
+#include <linux/font.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <asm/types.h>
@@ -60,30 +61,25 @@ int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
}
dst = par->fontbuffer;
- memset(dst, 0, par->fd_size);
switch (par->rotate) {
case FB_ROTATE_UD:
for (i = len; i--; ) {
- rotate_ud(src, dst, vc->vc_font.width,
- vc->vc_font.height);
-
+ font_glyph_rotate_180(src, vc->vc_font.width, vc->vc_font.height, dst);
src += s_cellsize;
dst += d_cellsize;
}
break;
case FB_ROTATE_CW:
for (i = len; i--; ) {
- rotate_cw(src, dst, vc->vc_font.width,
- vc->vc_font.height);
+ font_glyph_rotate_90(src, vc->vc_font.width, vc->vc_font.height, dst);
src += s_cellsize;
dst += d_cellsize;
}
break;
case FB_ROTATE_CCW:
for (i = len; i--; ) {
- rotate_ccw(src, dst, vc->vc_font.width,
- vc->vc_font.height);
+ font_glyph_rotate_270(src, vc->vc_font.width, vc->vc_font.height, dst);
src += s_cellsize;
dst += d_cellsize;
}
diff --git a/drivers/video/fbdev/core/fbcon_rotate.h b/drivers/video/fbdev/core/fbcon_rotate.h
index 8cb019e8a9c0..725bcae2df61 100644
--- a/drivers/video/fbdev/core/fbcon_rotate.h
+++ b/drivers/video/fbdev/core/fbcon_rotate.h
@@ -19,77 +19,6 @@
(fb_scrollmode(s) == SCROLL_REDRAW || fb_scrollmode(s) == SCROLL_MOVE || !(i)->fix.xpanstep) ? \
(i)->var.xres : (i)->var.xres_virtual; })
-
-static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
-{
- u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
-
- pat +=index;
- return (*pat) & (0x80 >> bit);
-}
-
-static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat)
-{
- u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
-
- pat += index;
-
- (*pat) |= 0x80 >> bit;
-}
-
-static inline void rotate_ud(const char *in, char *out, u32 width, u32 height)
-{
- int i, j;
- int shift = (8 - (width % 8)) & 7;
-
- width = (width + 7) & ~7;
-
- for (i = 0; i < height; i++) {
- for (j = 0; j < width - shift; j++) {
- if (pattern_test_bit(j, i, width, in))
- pattern_set_bit(width - (1 + j + shift),
- height - (1 + i),
- width, out);
- }
-
- }
-}
-
-static inline void rotate_cw(const char *in, char *out, u32 width, u32 height)
-{
- int i, j, h = height, w = width;
- int shift = (8 - (height % 8)) & 7;
-
- width = (width + 7) & ~7;
- height = (height + 7) & ~7;
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- if (pattern_test_bit(j, i, width, in))
- pattern_set_bit(height - 1 - i - shift, j,
- height, out);
-
- }
- }
-}
-
-static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height)
-{
- int i, j, h = height, w = width;
- int shift = (8 - (width % 8)) & 7;
-
- width = (width + 7) & ~7;
- height = (height + 7) & ~7;
-
- for (i = 0; i < h; i++) {
- for (j = 0; j < w; j++) {
- if (pattern_test_bit(j, i, width, in))
- pattern_set_bit(i, width - 1 - j - shift,
- height, out);
- }
- }
-}
-
int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc);
#if defined(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION)
diff --git a/include/linux/font.h b/include/linux/font.h
index 3bd49d914b22..0a240dd70422 100644
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -104,6 +104,14 @@ unsigned int font_data_size(font_data_t *fd);
bool font_data_is_equal(font_data_t *lhs, font_data_t *rhs);
int font_data_export(font_data_t *fd, struct console_font *font, unsigned int vpitch);
+/* font_rotate.c */
+void font_glyph_rotate_90(const unsigned char *glyph, unsigned int width, unsigned int height,
+ unsigned char *out);
+void font_glyph_rotate_180(const unsigned char *glyph, unsigned int width, unsigned int height,
+ unsigned char *out);
+void font_glyph_rotate_270(const unsigned char *glyph, unsigned int width, unsigned int height,
+ unsigned char *out);
+
/*
* Font description
*/
diff --git a/lib/fonts/Makefile b/lib/fonts/Makefile
index 3268d344c0a1..32ece0e265c8 100644
--- a/lib/fonts/Makefile
+++ b/lib/fonts/Makefile
@@ -2,6 +2,7 @@
# Font handling
font-y := fonts.o
+font-$(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION) += font_rotate.o
# Built-in fonts
font-$(CONFIG_FONT_10x18) += font_10x18.o
diff --git a/lib/fonts/font_rotate.c b/lib/fonts/font_rotate.c
new file mode 100644
index 000000000000..3e0a19c889f3
--- /dev/null
+++ b/lib/fonts/font_rotate.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Font rotation
+ *
+ * Copyright (C) 2005 Antonino Daplas <adaplas @pol.net>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#include <linux/export.h>
+#include <linux/math.h>
+#include <linux/string.h>
+
+#include "font.h"
+
+static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat)
+{
+ u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
+
+ pat += index;
+ return (*pat) & (0x80 >> bit);
+}
+
+static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat)
+{
+ u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8;
+
+ pat += index;
+
+ (*pat) |= 0x80 >> bit;
+}
+
+static inline void rotate_cw(const char *in, char *out, u32 width, u32 height)
+{
+ int i, j, h = height, w = width;
+ int shift = (8 - (height % 8)) & 7;
+
+ width = (width + 7) & ~7;
+ height = (height + 7) & ~7;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ if (pattern_test_bit(j, i, width, in))
+ pattern_set_bit(height - 1 - i - shift, j,
+ height, out);
+ }
+ }
+}
+
+/**
+ * font_glyph_rotate_90 - Rotate a glyph pattern by 90° in clockwise direction
+ * @glyph: The glyph to rotate
+ * @width: The glyph width in bits per scanline
+ * @height: The number of scanlines in the glyph
+ * @out: The rotated glyph bitmap
+ *
+ * The parameters @width and @height refer to the input glyph given in @glyph.
+ * The caller has to provide the output buffer @out of sufficient size to hold
+ * the rotated glyph. Rotating by 90° flips the width and height for the output
+ * glyph. Depending on the glyph pitch, the size of the output glyph can be
+ * different then the size of the input. Caller shave to take this into account
+ * when allocating the output memory.
+ */
+void font_glyph_rotate_90(const unsigned char *glyph, unsigned int width, unsigned int height,
+ unsigned char *out)
+{
+ memset(out, 0, font_glyph_size(height, width)); /* flip width/height */
+
+ rotate_cw(glyph, out, width, height);
+}
+EXPORT_SYMBOL_GPL(font_glyph_rotate_90);
+
+static inline void rotate_ud(const char *in, char *out, u32 width, u32 height)
+{
+ int i, j;
+ int shift = (8 - (width % 8)) & 7;
+
+ width = (width + 7) & ~7;
+
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width - shift; j++) {
+ if (pattern_test_bit(j, i, width, in))
+ pattern_set_bit(width - (1 + j + shift),
+ height - (1 + i),
+ width, out);
+ }
+ }
+}
+
+/**
+ * font_glyph_rotate_180 - Rotate a glyph pattern by 180°
+ * @glyph: The glyph to rotate
+ * @width: The glyph width in bits per scanline
+ * @height: The number of scanlines in the glyph
+ * @out: The rotated glyph bitmap
+ *
+ * The parameters @width and @height refer to the input glyph given in @glyph.
+ * The caller has to provide the output buffer @out of sufficient size to hold
+ * the rotated glyph.
+ */
+void font_glyph_rotate_180(const unsigned char *glyph, unsigned int width, unsigned int height,
+ unsigned char *out)
+{
+ memset(out, 0, font_glyph_size(width, height));
+
+ rotate_ud(glyph, out, width, height);
+}
+EXPORT_SYMBOL_GPL(font_glyph_rotate_180);
+
+static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height)
+{
+ int i, j, h = height, w = width;
+ int shift = (8 - (width % 8)) & 7;
+
+ width = (width + 7) & ~7;
+ height = (height + 7) & ~7;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ if (pattern_test_bit(j, i, width, in))
+ pattern_set_bit(i, width - 1 - j - shift,
+ height, out);
+ }
+ }
+}
+
+/**
+ * font_glyph_rotate_270 - Rotate a glyph pattern by 270° in clockwise direction
+ * @glyph: The glyph to rotate
+ * @width: The glyph width in bits per scanline
+ * @height: The number of scanlines in the glyph
+ * @out: The rotated glyph bitmap
+ *
+ * The parameters @width and @height refer to the input glyph given in @glyph.
+ * The caller has to provide the output buffer @out of sufficient size to hold
+ * the rotated glyph. Rotating by 270° flips the width and height for the output
+ * glyph. Depending on the glyph pitch, the size of the output glyph can be
+ * different then the size of the input. Caller shave to take this into account
+ * when allocating the output memory.
+ */
+void font_glyph_rotate_270(const unsigned char *glyph, unsigned int width, unsigned int height,
+ unsigned char *out)
+{
+ memset(out, 0, font_glyph_size(height, width)); /* flip width/height */
+
+ rotate_ccw(glyph, out, width, height);
+}
+EXPORT_SYMBOL_GPL(font_glyph_rotate_270);
--
2.53.0
^ permalink raw reply related
* [PATCH 03/10] lib/fonts: Provide helpers for calculating glyph pitch and size
From: Thomas Zimmermann @ 2026-03-27 12:49 UTC (permalink / raw)
To: deller, gregkh, jirislaby, simona, sam
Cc: linux-fbdev, dri-devel, linux-kernel, linux-serial,
Thomas Zimmermann
In-Reply-To: <20260327130431.59481-1-tzimmermann@suse.de>
Implement pitch and size calculation for a single font glyph in the
new helpers font_glyph_pitch() and font_glyph_size(). Replace the
instances where the calculations are opencoded.
Note that in the case of fbcon console rotation, the parameters for
a glyph's width and height might be reversed. This is intentionally.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/tty/vt/vt.c | 5 ++--
drivers/video/fbdev/core/fbcon_ccw.c | 11 +++----
drivers/video/fbdev/core/fbcon_cw.c | 11 +++----
drivers/video/fbdev/core/fbcon_rotate.c | 6 ++--
drivers/video/fbdev/core/fbcon_ud.c | 7 +++--
include/linux/font.h | 40 +++++++++++++++++++++++++
lib/fonts/fonts.c | 2 +-
7 files changed, 61 insertions(+), 21 deletions(-)
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 3d89d30c9596..23b9683b52a5 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -71,7 +71,6 @@
* by Adam Tla/lka <atlka@pg.gda.pl>, Aug 2006
*/
-#include <linux/math.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sched/signal.h>
@@ -244,7 +243,7 @@ enum {
*/
unsigned int vc_font_pitch(const struct vc_font *font)
{
- return DIV_ROUND_UP(font->width, 8);
+ return font_glyph_pitch(font->width);
}
EXPORT_SYMBOL_GPL(vc_font_pitch);
@@ -261,7 +260,7 @@ EXPORT_SYMBOL_GPL(vc_font_pitch);
*/
unsigned int vc_font_size(const struct vc_font *font)
{
- return font->height * vc_font_pitch(font) * font->charcount;
+ return font_glyph_size(font->width, font->height) * font->charcount;
}
EXPORT_SYMBOL_GPL(vc_font_size);
diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c
index 2f394b5a17f7..96ef449ee6ac 100644
--- a/drivers/video/fbdev/core/fbcon_ccw.c
+++ b/drivers/video/fbdev/core/fbcon_ccw.c
@@ -26,7 +26,7 @@ static void ccw_update_attr(u8 *dst, u8 *src, int attribute,
struct vc_data *vc)
{
int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
- int width = (vc->vc_font.height + 7) >> 3;
+ int width = font_glyph_pitch(vc->vc_font.height);
int mod = vc->vc_font.height % 8;
u8 c, msk = ~(0xff << offset), msk1 = 0;
@@ -101,7 +101,7 @@ static inline void ccw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
{
struct fbcon_par *par = info->fbcon_par;
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- u32 idx = (vc->vc_font.height + 7) >> 3;
+ u32 idx = font_glyph_pitch(vc->vc_font.height);
u8 *src;
while (cnt--) {
@@ -131,7 +131,7 @@ static void ccw_putcs(struct vc_data *vc, struct fb_info *info,
{
struct fb_image image;
struct fbcon_par *par = info->fbcon_par;
- u32 width = (vc->vc_font.height + 7)/8;
+ u32 width = font_glyph_pitch(vc->vc_font.height);
u32 cellsize = width * vc->vc_font.width;
u32 maxcnt = info->pixmap.size/cellsize;
u32 scan_align = info->pixmap.scan_align - 1;
@@ -223,7 +223,8 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
struct fb_cursor cursor;
struct fbcon_par *par = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- int w = (vc->vc_font.height + 7) >> 3, c;
+ int w = font_glyph_pitch(vc->vc_font.height);
+ int c;
int y = real_y(par->p, vc->state.y);
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
int err = 1, dx, dy;
@@ -297,7 +298,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
char *tmp, *mask = kmalloc_array(w, vc->vc_font.width,
GFP_ATOMIC);
int cur_height, size, i = 0;
- int width = (vc->vc_font.width + 7)/8;
+ int width = font_glyph_pitch(vc->vc_font.width);
if (!mask)
return;
diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c
index 3c3ad3471ec4..ea712654edae 100644
--- a/drivers/video/fbdev/core/fbcon_cw.c
+++ b/drivers/video/fbdev/core/fbcon_cw.c
@@ -26,7 +26,7 @@ static void cw_update_attr(u8 *dst, u8 *src, int attribute,
struct vc_data *vc)
{
int i, j, offset = (vc->vc_font.height < 10) ? 1 : 2;
- int width = (vc->vc_font.height + 7) >> 3;
+ int width = font_glyph_pitch(vc->vc_font.height);
u8 c, msk = ~(0xff >> offset);
for (i = 0; i < vc->vc_font.width; i++) {
@@ -86,7 +86,7 @@ static inline void cw_putcs_aligned(struct vc_data *vc, struct fb_info *info,
{
struct fbcon_par *par = info->fbcon_par;
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- u32 idx = (vc->vc_font.height + 7) >> 3;
+ u32 idx = font_glyph_pitch(vc->vc_font.height);
u8 *src;
while (cnt--) {
@@ -116,7 +116,7 @@ static void cw_putcs(struct vc_data *vc, struct fb_info *info,
{
struct fb_image image;
struct fbcon_par *par = info->fbcon_par;
- u32 width = (vc->vc_font.height + 7)/8;
+ u32 width = font_glyph_pitch(vc->vc_font.height);
u32 cellsize = width * vc->vc_font.width;
u32 maxcnt = info->pixmap.size/cellsize;
u32 scan_align = info->pixmap.scan_align - 1;
@@ -206,7 +206,8 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
struct fb_cursor cursor;
struct fbcon_par *par = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- int w = (vc->vc_font.height + 7) >> 3, c;
+ int w = font_glyph_pitch(vc->vc_font.height);
+ int c;
int y = real_y(par->p, vc->state.y);
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
int err = 1, dx, dy;
@@ -280,7 +281,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
char *tmp, *mask = kmalloc_array(w, vc->vc_font.width,
GFP_ATOMIC);
int cur_height, size, i = 0;
- int width = (vc->vc_font.width + 7)/8;
+ int width = font_glyph_pitch(vc->vc_font.width);
if (!mask)
return;
diff --git a/drivers/video/fbdev/core/fbcon_rotate.c b/drivers/video/fbdev/core/fbcon_rotate.c
index 5348f6c6f57c..18575c5182db 100644
--- a/drivers/video/fbdev/core/fbcon_rotate.c
+++ b/drivers/video/fbdev/core/fbcon_rotate.c
@@ -33,14 +33,12 @@ int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
src = par->fontdata = vc->vc_font.data;
par->cur_rotate = par->p->con_rotate;
len = vc->vc_font.charcount;
- s_cellsize = ((vc->vc_font.width + 7)/8) *
- vc->vc_font.height;
+ s_cellsize = font_glyph_size(vc->vc_font.width, vc->vc_font.height);
d_cellsize = s_cellsize;
if (par->rotate == FB_ROTATE_CW ||
par->rotate == FB_ROTATE_CCW)
- d_cellsize = ((vc->vc_font.height + 7)/8) *
- vc->vc_font.width;
+ d_cellsize = font_glyph_size(vc->vc_font.height, vc->vc_font.width);
if (info->fbops->fb_sync)
info->fbops->fb_sync(info);
diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c
index 6fc30cad5b19..f7cd89c42b01 100644
--- a/drivers/video/fbdev/core/fbcon_ud.c
+++ b/drivers/video/fbdev/core/fbcon_ud.c
@@ -26,7 +26,7 @@ static void ud_update_attr(u8 *dst, u8 *src, int attribute,
struct vc_data *vc)
{
int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
- int width = (vc->vc_font.width + 7) >> 3;
+ int width = font_glyph_pitch(vc->vc_font.width);
unsigned int cellsize = vc->vc_font.height * width;
u8 c;
@@ -153,7 +153,7 @@ static void ud_putcs(struct vc_data *vc, struct fb_info *info,
{
struct fb_image image;
struct fbcon_par *par = info->fbcon_par;
- u32 width = (vc->vc_font.width + 7)/8;
+ u32 width = font_glyph_pitch(vc->vc_font.width);
u32 cellsize = width * vc->vc_font.height;
u32 maxcnt = info->pixmap.size/cellsize;
u32 scan_align = info->pixmap.scan_align - 1;
@@ -253,7 +253,8 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
struct fb_cursor cursor;
struct fbcon_par *par = info->fbcon_par;
unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- int w = (vc->vc_font.width + 7) >> 3, c;
+ int w = font_glyph_pitch(vc->vc_font.width);
+ int c;
int y = real_y(par->p, vc->state.y);
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
int err = 1, dx, dy;
diff --git a/include/linux/font.h b/include/linux/font.h
index 5401f07dd6ce..3bd49d914b22 100644
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -11,10 +11,50 @@
#ifndef _VIDEO_FONT_H
#define _VIDEO_FONT_H
+#include <linux/math.h>
#include <linux/types.h>
struct console_font;
+/*
+ * Glyphs
+ */
+
+/**
+ * font_glyph_pitch - Calculates the number of bytes per scanline
+ * @width: The glyph width in bits per scanline
+ *
+ * A glyph's pitch is the number of bytes in a single scanline, rounded
+ * up to the next full byte. The parameter @width receives the number
+ * of visible bits per scanline. For example, if width is 14 bytes per
+ * scanline, the pitch is 2 bytes per scanline. If width is 8 bits per
+ * scanline, the pitch is 1 byte per scanline.
+ *
+ * Returns:
+ * The number of bytes in a single scanline of the glyph
+ */
+static inline unsigned int font_glyph_pitch(unsigned int width)
+{
+ return DIV_ROUND_UP(width, 8);
+}
+
+/**
+ * font_glyph_size - Calculates the number of bytes per glyph
+ * @width: The glyph width in bits per scanline
+ * @vpitch: The number of scanlines in the glyph
+ *
+ * The number of bytes in a glyph depends on the pitch and the number
+ * of scanlines. font_glyph_size automatically calculates the pitch
+ * from the given width. The parameter @vpitch gives the number of
+ * scanlines, which is usually the glyph's height in scanlines. Fonts
+ * coming from user space can sometimes have a different vertical pitch
+ * with empty scanlines between two adjacent glyphs.
+ */
+static inline unsigned int font_glyph_size(unsigned int width, unsigned int vpitch)
+{
+ return font_glyph_pitch(width) * vpitch;
+}
+
/*
* font_data_t and helpers
*/
diff --git a/lib/fonts/fonts.c b/lib/fonts/fonts.c
index 5938f542906b..f5d5333450a0 100644
--- a/lib/fonts/fonts.c
+++ b/lib/fonts/fonts.c
@@ -26,7 +26,7 @@
#include "font.h"
-#define console_font_pitch(font) DIV_ROUND_UP((font)->width, 8)
+#define console_font_pitch(font) font_glyph_pitch((font)->width)
/*
* Helpers for font_data_t
--
2.53.0
^ permalink raw reply related
* [PATCH 02/10] vt: Implement helpers for struct vc_font in source file
From: Thomas Zimmermann @ 2026-03-27 12:49 UTC (permalink / raw)
To: deller, gregkh, jirislaby, simona, sam
Cc: linux-fbdev, dri-devel, linux-kernel, linux-serial,
Thomas Zimmermann
In-Reply-To: <20260327130431.59481-1-tzimmermann@suse.de>
Move the helpers vc_font_pitch() and vc_font_size() from the VT
header file into source file. They are not called very often, so
there's no benefit in keeping them in the headers. Also avoids
including <liux/math.h> from the header.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/tty/vt/vt.c | 35 ++++++++++++++++++++++++++++++++++
include/linux/console_struct.h | 30 ++---------------------------
2 files changed, 37 insertions(+), 28 deletions(-)
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index e2df99e3d458..3d89d30c9596 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -71,6 +71,7 @@
* by Adam Tla/lka <atlka@pg.gda.pl>, Aug 2006
*/
+#include <linux/math.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sched/signal.h>
@@ -230,6 +231,40 @@ enum {
blank_vesa_wait,
};
+/*
+ * struct vc_font
+ */
+
+/**
+ * vc_font_pitch - Calculates the number of bytes between two adjacent scanlines
+ * @font: The VC font
+ *
+ * Returns:
+ * The number of bytes between two adjacent scanlines in the font data
+ */
+unsigned int vc_font_pitch(const struct vc_font *font)
+{
+ return DIV_ROUND_UP(font->width, 8);
+}
+EXPORT_SYMBOL_GPL(vc_font_pitch);
+
+/**
+ * vc_font_size - Calculates the size of the font data in bytes
+ * @font: The VC font
+ *
+ * vc_font_size() calculates the number of bytes of font data in the
+ * font specified by @font. The function calculates the size from the
+ * font parameters.
+ *
+ * Returns:
+ * The size of the font data in bytes.
+ */
+unsigned int vc_font_size(const struct vc_font *font)
+{
+ return font->height * vc_font_pitch(font) * font->charcount;
+}
+EXPORT_SYMBOL_GPL(vc_font_size);
+
/*
* /sys/class/tty/tty0/
*
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index 6ce498b31855..fe915afdece5 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -13,7 +13,6 @@
#ifndef _LINUX_CONSOLE_STRUCT_H
#define _LINUX_CONSOLE_STRUCT_H
-#include <linux/math.h>
#include <linux/vt.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
@@ -83,33 +82,8 @@ struct vc_font {
const unsigned char *data;
};
-/**
- * vc_font_pitch - Calculates the number of bytes between two adjacent scanlines
- * @font: The VC font
- *
- * Returns:
- * The number of bytes between two adjacent scanlines in the font data
- */
-static inline unsigned int vc_font_pitch(const struct vc_font *font)
-{
- return DIV_ROUND_UP(font->width, 8);
-}
-
-/**
- * vc_font_size - Calculates the size of the font data in bytes
- * @font: The VC font
- *
- * vc_font_size() calculates the number of bytes of font data in the
- * font specified by @font. The function calculates the size from the
- * font parameters.
- *
- * Returns:
- * The size of the font data in bytes.
- */
-static inline unsigned int vc_font_size(const struct vc_font *font)
-{
- return font->height * vc_font_pitch(font) * font->charcount;
-}
+unsigned int vc_font_pitch(const struct vc_font *font);
+unsigned int vc_font_size(const struct vc_font *font);
/*
* Example: vc_data of a console that was scrolled 3 lines down.
--
2.53.0
^ permalink raw reply related
* [PATCH 00/10] fbcon,fonts: Refactor framebuffer console rotation
From: Thomas Zimmermann @ 2026-03-27 12:49 UTC (permalink / raw)
To: deller, gregkh, jirislaby, simona, sam
Cc: linux-fbdev, dri-devel, linux-kernel, linux-serial,
Thomas Zimmermann
Refactor the framebuffer console rotation into individual components
for glyphs, fonts and the overall fbcon state. Right now this is mixed
up in fbcon_rotate.{c,h}. Also build cursor rotation on top of the new
interfaces.
Start with an OOB fix in patch 1. If buffer allocation fails, fbcon
currently uses a too-small glyph buffer for output. Avoid that.
Patches 2 to 4 make a number of small improvements to the font library
and its callers.
Patches 5 to 8 refactor the font rotation. Fbcon rotation rotates each
individual glphy in a font buffer and uses the rotated buffer's glyphs
for output. The result looks like the console buffer has been rotated
as a whole. Split this into helpers that rotate individual glyphs and
a helper that rotates the font buffer of these. Then reimplement fbcon
rotation on top. Document the public font helpers.
Patch 9 rebuilds cursor rotation on top of the new glyph helpers. The
fbcon cursor is itself a glyph that has to be rotated in sync with the
font.
Patch 10 moves the state of fbcon rotation into a single place and makes
is a build-time conditional.
Tested with fbcon under bochs on Qemu.
Built upon the fbcon changes at [1].
[1] https://lore.kernel.org/linux-fbdev/20260309141723.137364-1-tzimmermann@suse.de/
Thomas Zimmermann (10):
fbcon: Avoid OOB font access if console rotation fails
vt: Implement helpers for struct vc_font in source file
lib/fonts: Provide helpers for calculating glyph pitch and size
lib/fonts: Clean up Makefile
lib/fonts: Implement glyph rotation
lib/fonts: Refactor glyph-pattern helpers
lib/fonts: Refactor glyph-rotation helpers
lib/fonts: Implement font rotation
fbcon: Fill cursor mask in helper function
fbcon: Put font-rotation state into separate struct
drivers/tty/vt/vt.c | 34 +++
drivers/video/fbdev/core/bitblit.c | 35 +--
drivers/video/fbdev/core/fbcon.c | 48 ++++-
drivers/video/fbdev/core/fbcon.h | 14 +-
drivers/video/fbdev/core/fbcon_ccw.c | 70 ++----
drivers/video/fbdev/core/fbcon_cw.c | 70 ++----
drivers/video/fbdev/core/fbcon_rotate.c | 88 ++------
drivers/video/fbdev/core/fbcon_rotate.h | 71 ------
drivers/video/fbdev/core/fbcon_ud.c | 67 ++----
include/linux/console_struct.h | 30 +--
include/linux/font.h | 51 +++++
lib/fonts/Makefile | 36 ++--
lib/fonts/font_rotate.c | 275 ++++++++++++++++++++++++
lib/fonts/fonts.c | 2 +-
14 files changed, 525 insertions(+), 366 deletions(-)
create mode 100644 lib/fonts/font_rotate.c
--
2.53.0
^ permalink raw reply
* [PATCH 01/10] fbcon: Avoid OOB font access if console rotation fails
From: Thomas Zimmermann @ 2026-03-27 12:49 UTC (permalink / raw)
To: deller, gregkh, jirislaby, simona, sam
Cc: linux-fbdev, dri-devel, linux-kernel, linux-serial,
Thomas Zimmermann, stable
In-Reply-To: <20260327130431.59481-1-tzimmermann@suse.de>
Clear the font buffer if the reallocation during console rotation fails
in fbcon_rotate_font(). The putcs implementations for the rotated buffer
will return early in this case. See [1] for an example.
Currently, fbcon_rotate_font() keeps the old buffer, which is to small
for the rotated font. Printing to the rotated console with a high-enough
character code will overflow the font buffer.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: 6cc50e1c5b57 ("[PATCH] fbcon: Console Rotation - Add support to rotate font bitmap")
Cc: <stable@vger.kernel.org> # v2.6.15+
Link: https://elixir.bootlin.com/linux/v6.19/source/drivers/video/fbdev/core/fbcon_ccw.c#L144 # [1]
---
drivers/video/fbdev/core/fbcon_rotate.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/core/fbcon_rotate.c b/drivers/video/fbdev/core/fbcon_rotate.c
index 1562a8f20b4f..5348f6c6f57c 100644
--- a/drivers/video/fbdev/core/fbcon_rotate.c
+++ b/drivers/video/fbdev/core/fbcon_rotate.c
@@ -46,6 +46,10 @@ int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
info->fbops->fb_sync(info);
if (par->fd_size < d_cellsize * len) {
+ kfree(par->fontbuffer);
+ par->fontbuffer = NULL;
+ par->fd_size = 0;
+
dst = kmalloc_array(len, d_cellsize, GFP_KERNEL);
if (dst == NULL) {
@@ -54,7 +58,6 @@ int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
}
par->fd_size = d_cellsize * len;
- kfree(par->fontbuffer);
par->fontbuffer = dst;
}
--
2.53.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox