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

mtd: mtk: avoid warning in mtk_ecc_encode

When building with -Wmaybe-uninitialized, gcc produces a silly false positive
warning for the mtk_ecc_encode function:

drivers/mtd/nand/mtk_ecc.c: In function 'mtk_ecc_encode':
drivers/mtd/nand/mtk_ecc.c:402:15: error: 'val' may be used uninitialized in this function [-Werror=maybe-uninitialized]

The function for some reason contains a double byte swap on big-endian
builds to get the OOB data into the correct order again, and is written
in a slightly confusing way.

Using a simple memcpy32_fromio() to read the data simplifies it a lot
so it becomes more readable and produces no warning. However, the
output might not have 32-bit alignment, so we have to use another
memcpy to avoid taking alignment faults or writing beyond the end
of the array.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Tested-by: RogerCC Lin <rogercc.lin@mediatek.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>

authored by

Arnd Bergmann and committed by
Boris Brezillon
8ff0513b 73f907fd

+9 -10
+9 -10
drivers/mtd/nand/mtk_ecc.c
··· 86 86 struct completion done; 87 87 struct mutex lock; 88 88 u32 sectors; 89 + 90 + u8 eccdata[112]; 89 91 }; 90 92 91 93 static inline void mtk_ecc_wait_idle(struct mtk_ecc *ecc, ··· 368 366 u8 *data, u32 bytes) 369 367 { 370 368 dma_addr_t addr; 371 - u8 *p; 372 - u32 len, i, val; 373 - int ret = 0; 369 + u32 len; 370 + int ret; 374 371 375 372 addr = dma_map_single(ecc->dev, data, bytes, DMA_TO_DEVICE); 376 373 ret = dma_mapping_error(ecc->dev, addr); ··· 394 393 395 394 /* Program ECC bytes to OOB: per sector oob = FDM + ECC + SPARE */ 396 395 len = (config->strength * ECC_PARITY_BITS + 7) >> 3; 397 - p = data + bytes; 398 396 399 - /* write the parity bytes generated by the ECC back to the OOB region */ 400 - for (i = 0; i < len; i++) { 401 - if ((i % 4) == 0) 402 - val = readl(ecc->regs + ECC_ENCPAR(i / 4)); 403 - p[i] = (val >> ((i % 4) * 8)) & 0xff; 404 - } 397 + /* write the parity bytes generated by the ECC back to temp buffer */ 398 + __ioread32_copy(ecc->eccdata, ecc->regs + ECC_ENCPAR(0), round_up(len, 4)); 399 + 400 + /* copy into possibly unaligned OOB region with actual length */ 401 + memcpy(data + bytes, ecc->eccdata, len); 405 402 timeout: 406 403 407 404 dma_unmap_single(ecc->dev, addr, bytes, DMA_TO_DEVICE);