Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nvmem: qfprom: switch to 4-byte aligned reads

All platforms since Snapdragon 8 Gen1 (SM8450) require using 4-byte
reads to access QFPROM data. While older platforms were more than happy
with 1-byte reads, change the qfprom driver to use 4-byte reads for all
the platforms. Specify stride and word size of 4 bytes. To retain
compatibility with the existing DT and to simplify porting data from
vendor kernels, use fixup_dt_cell_info in order to bump alignment
requirements.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20250411112251.68002-12-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Dmitry Baryshkov and committed by
Greg Kroah-Hartman
3566a737 67864842

+20 -6
+20 -6
drivers/nvmem/qfprom.c
··· 321 321 unsigned int reg, void *_val, size_t bytes) 322 322 { 323 323 struct qfprom_priv *priv = context; 324 - u8 *val = _val; 325 - int i = 0, words = bytes; 324 + u32 *val = _val; 326 325 void __iomem *base = priv->qfpcorrected; 326 + int words = DIV_ROUND_UP(bytes, sizeof(u32)); 327 + int i; 327 328 328 329 if (read_raw_data && priv->qfpraw) 329 330 base = priv->qfpraw; 330 331 331 - while (words--) 332 - *val++ = readb(base + reg + i++); 332 + for (i = 0; i < words; i++) 333 + *val++ = readl(base + reg + i * sizeof(u32)); 333 334 334 335 return 0; 336 + } 337 + 338 + /* Align reads to word boundary */ 339 + static void qfprom_fixup_dt_cell_info(struct nvmem_device *nvmem, 340 + struct nvmem_cell_info *cell) 341 + { 342 + unsigned int byte_offset = cell->offset % sizeof(u32); 343 + 344 + cell->bit_offset += byte_offset * BITS_PER_BYTE; 345 + cell->offset -= byte_offset; 346 + if (byte_offset && !cell->nbits) 347 + cell->nbits = cell->bytes * BITS_PER_BYTE; 335 348 } 336 349 337 350 static void qfprom_runtime_disable(void *data) ··· 371 358 struct nvmem_config econfig = { 372 359 .name = "qfprom", 373 360 .add_legacy_fixed_of_cells = true, 374 - .stride = 1, 375 - .word_size = 1, 361 + .stride = 4, 362 + .word_size = 4, 376 363 .id = NVMEM_DEVID_AUTO, 377 364 .reg_read = qfprom_reg_read, 365 + .fixup_dt_cell_info = qfprom_fixup_dt_cell_info, 378 366 }; 379 367 struct device *dev = &pdev->dev; 380 368 struct resource *res;