[PATCH] staging: sm750fb: Refactor init_status to use initchip_param
MishraMohit21 <[email protected]> Mon, 20 Jul 2026 01:28:39 +0530
| Newsgroups | org.kernel.vger.linux-fbdev,dev.linux.lists.linux-staging,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
The driver initializes the hardware by casting 'struct init_status *' to 'struct initchip_param *' in ddk750_init_hw(). This is technically undefined behavior, violates strict-aliasing rules, and is fragile. Furthermore, 'struct init_status' defines the 'reset_memory' field as a 2-byte 'ushort', while 'struct initchip_param' defines it as a 1-byte 'unsigned char'. On little-endian architectures, reading the low byte of the ushort happens to evaluate to the correct value (0 or 1) by accident. However, on big-endian architectures, casting and reading this field reads the high byte (0x00) instead, causing a silent failure where the memory controller is never reset. This endianness layout mismatch was empirically verified using a standalone test harness (scratch/be_test.c) compiled under a mips-linux-gnu-gcc cross-compiler and executed under qemu-mips. Resolve this by removing the duplicate 'struct init_status' entirely and using 'struct initchip_param' directly. This removes the unsafe pointer cast and ensures endian-safe hardware initialization. This change has been compile-tested only. No hardware was available to verify runtime behavior. Signed-off-by: MishraMohit21 <[email protected]> --- drivers/staging/sm750fb/sm750.c | 8 ++++---- drivers/staging/sm750fb/sm750.h | 12 ++---------- drivers/staging/sm750fb/sm750_hw.c | 16 ++++++++-------- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index 89c811e0806c..5986dbef67c0 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -844,11 +844,11 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src) swap = 0; - 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.chip_clock = 0; + sm750_dev->init_parm.mem_clock = 0; + sm750_dev->init_parm.master_clock = 0; sm750_dev->init_parm.power_mode = 0; - sm750_dev->init_parm.setAllEngOff = 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 */ diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h index d2c522e67f26..313c2683bf6c 100644 --- a/drivers/staging/sm750fb/sm750.h +++ b/drivers/staging/sm750fb/sm750.h @@ -38,15 +38,7 @@ enum sm750_path { sm750_pnc = 3, /* panel and crt */ }; -struct init_status { - ushort power_mode; - /* below three clocks are in unit of MHZ*/ - ushort chip_clk; - ushort mem_clk; - ushort master_clk; - ushort setAllEngOff; - ushort reset_memory; -}; +#include "ddk750_chip.h" struct lynx_accel { /* base virtual address of DPR registers */ @@ -102,7 +94,7 @@ struct sm750_dev { /* locks*/ spinlock_t slock; - struct init_status init_parm; + struct initchip_param init_parm; enum sm750_pnltype pnltype; enum sm750_dataflow dataflow; int nocrt; diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c index 34a837fb4b64..54c1b241ae6e 100644 --- a/drivers/staging/sm750fb/sm750_hw.c +++ b/drivers/staging/sm750fb/sm750_hw.c @@ -66,20 +66,20 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev) int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev) { - struct init_status *parm; + struct initchip_param *parm; parm = &sm750_dev->init_parm; - if (parm->chip_clk == 0) - parm->chip_clk = (sm750_get_chip_type() == SM750LE) ? + if (parm->chip_clock == 0) + parm->chip_clock = (sm750_get_chip_type() == SM750LE) ? DEFAULT_SM750LE_CHIP_CLOCK : DEFAULT_SM750_CHIP_CLOCK; - if (parm->mem_clk == 0) - parm->mem_clk = parm->chip_clk; - if (parm->master_clk == 0) - parm->master_clk = parm->chip_clk / 3; + if (parm->mem_clock == 0) + parm->mem_clock = parm->chip_clock; + if (parm->master_clock == 0) + parm->master_clock = parm->chip_clock / 3; - ddk750_init_hw((struct initchip_param *)&sm750_dev->init_parm); + ddk750_init_hw(&sm750_dev->init_parm); /* for sm718, open pci burst */ if (sm750_dev->devid == 0x718) { poke32(SYSTEM_CTRL, -- 2.43.0