From 7d0f2733797f3c1453e718c3b9f9da3c07708c15 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sat, 7 Jun 2025 23:11:17 +0200 Subject: [PATCH 1/5] clk: imx: add missing linux/bug.h header for WARN The WARN macro requires inclusion of linux/bug.h header. It does currently work as bitfield.h includes it indirectly but this will change when bitfield.h will be synced with new Linux version. Explicitly include the header to fix future compilation error. Signed-off-by: Christian Marangi --- drivers/clk/imx/clk-fracn-gppll.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c index 81e19d393cf..b3926564a22 100644 --- a/drivers/clk/imx/clk-fracn-gppll.c +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include From 1f1aafe0b526ae22b0b1673d440c58fa99d5d4bf Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sat, 7 Jun 2025 23:11:18 +0200 Subject: [PATCH 2/5] iommu: qcom-smmu: add missing linux/bug.h header for WARN_ON The WARN macro requires inclusion of linux/bug.h header. It does currently work as bitfield.h includes it indirectly but this will change when bitfield.h will be synced with new Linux version. Explicitly include the header to fix future compilation error. Signed-off-by: Christian Marangi --- drivers/iommu/qcom-hyp-smmu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iommu/qcom-hyp-smmu.c b/drivers/iommu/qcom-hyp-smmu.c index c1b95bc8b8c..2e51ce4f242 100644 --- a/drivers/iommu/qcom-hyp-smmu.c +++ b/drivers/iommu/qcom-hyp-smmu.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include From 5c734237ac56ed943221030cd027454d2b4d94cb Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sat, 7 Jun 2025 23:11:19 +0200 Subject: [PATCH 3/5] arm: apple: rtkit: add missing header linux/bug.h and linux/bitops.h The GENMASK/GENMASK_ULL macro requires inclusion of linux/bitops.h header. It does currently work as bitfield.h includes it indirectly but this will change when bitfield.h will be synced with new Linux version. Also raw printf require linux/bug.h header (also currently included indirectly by bitfield.h) Explicitly include the headers to fix future compilation error. Signed-off-by: Christian Marangi --- arch/arm/mach-apple/rtkit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-apple/rtkit.c b/arch/arm/mach-apple/rtkit.c index f3561543a35..251c6056cbd 100644 --- a/arch/arm/mach-apple/rtkit.c +++ b/arch/arm/mach-apple/rtkit.c @@ -9,7 +9,9 @@ #include #include +#include #include +#include #include #include #include From 01cc7046ad2a1537791cda5175bce281f0a0acfc Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sat, 7 Jun 2025 23:11:20 +0200 Subject: [PATCH 4/5] linux/bitfield.h: sync from Linux 6.15 Sync bitfield.h header with Linux 6.15 version. Mainly is to permit the introduction of FIELD_PREP_CONST. The bug.h header changed to build_bug.h doesn't cause any regression as we also ship split header similar to how it's done with in Linux. Signed-off-by: Christian Marangi --- include/linux/bitfield.h | 103 ++++++++++++++++++++++++++++----------- 1 file changed, 75 insertions(+), 28 deletions(-) diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h index 7ad02f8cbb9..63928f17322 100644 --- a/include/linux/bitfield.h +++ b/include/linux/bitfield.h @@ -1,21 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (C) 2014 Felix Fietkau * Copyright (C) 2004 - 2009 Ivo van Doorn - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef _LINUX_BITFIELD_H #define _LINUX_BITFIELD_H -#include +#include #include /* @@ -27,6 +19,9 @@ * * Example: * + * #include + * #include + * * #define REG_FIELD_A GENMASK(6, 0) * #define REG_FIELD_B BIT(7) * #define REG_FIELD_C GENMASK(15, 8) @@ -49,20 +44,51 @@ #define __bf_shf(x) (__builtin_ffsll(x) - 1) +#define __scalar_type_to_unsigned_cases(type) \ + unsigned type: (unsigned type)0, \ + signed type: (unsigned type)0 + +#define __unsigned_scalar_typeof(x) typeof( \ + _Generic((x), \ + char: (unsigned char)0, \ + __scalar_type_to_unsigned_cases(char), \ + __scalar_type_to_unsigned_cases(short), \ + __scalar_type_to_unsigned_cases(int), \ + __scalar_type_to_unsigned_cases(long), \ + __scalar_type_to_unsigned_cases(long long), \ + default: (x))) + +#define __bf_cast_unsigned(type, x) ((__unsigned_scalar_typeof(type))(x)) + #define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \ ({ \ BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \ _pfx "mask is not constant"); \ - BUILD_BUG_ON_MSG(!(_mask), _pfx "mask is zero"); \ + BUILD_BUG_ON_MSG((_mask) == 0, _pfx "mask is zero"); \ BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \ - ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \ + ~((_mask) >> __bf_shf(_mask)) & \ + (0 + (_val)) : 0, \ _pfx "value too large for the field"); \ - BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull, \ + BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) > \ + __bf_cast_unsigned(_reg, ~0ull), \ _pfx "type of reg too small for mask"); \ __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \ (1ULL << __bf_shf(_mask))); \ }) +/** + * FIELD_MAX() - produce the maximum value representable by a field + * @_mask: shifted mask defining the field's length and position + * + * FIELD_MAX() returns the maximum value that can be held in the field + * specified by @_mask. + */ +#define FIELD_MAX(_mask) \ + ({ \ + __BF_FIELD_CHECK(_mask, 0ULL, 0ULL, "FIELD_MAX: "); \ + (typeof(_mask))((_mask) >> __bf_shf(_mask)); \ + }) + /** * FIELD_FIT() - check if value fits in the field * @_mask: shifted mask defining the field's length and position @@ -72,7 +98,7 @@ */ #define FIELD_FIT(_mask, _val) \ ({ \ - __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_FIT: "); \ + __BF_FIELD_CHECK(_mask, 0ULL, 0ULL, "FIELD_FIT: "); \ !((((typeof(_mask))_val) << __bf_shf(_mask)) & ~(_mask)); \ }) @@ -90,10 +116,36 @@ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ }) +#define __BF_CHECK_POW2(n) BUILD_BUG_ON_ZERO(((n) & ((n) - 1)) != 0) + +/** + * FIELD_PREP_CONST() - prepare a constant bitfield element + * @_mask: shifted mask defining the field's length and position + * @_val: value to put in the field + * + * FIELD_PREP_CONST() masks and shifts up the value. The result should + * be combined with other fields of the bitfield using logical OR. + * + * Unlike FIELD_PREP() this is a constant expression and can therefore + * be used in initializers. Error checking is less comfortable for this + * version, and non-constant masks cannot be used. + */ +#define FIELD_PREP_CONST(_mask, _val) \ + ( \ + /* mask must be non-zero */ \ + BUILD_BUG_ON_ZERO((_mask) == 0) + \ + /* check if value fits */ \ + BUILD_BUG_ON_ZERO(~((_mask) >> __bf_shf(_mask)) & (_val)) + \ + /* check if mask is contiguous */ \ + __BF_CHECK_POW2((_mask) + (1ULL << __bf_shf(_mask))) + \ + /* and create the value */ \ + (((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)) \ + ) + /** * FIELD_GET() - extract a bitfield element * @_mask: shifted mask defining the field's length and position - * @_reg: 32bit value of entire bitfield + * @_reg: value of entire bitfield * * FIELD_GET() extracts the field specified by @_mask from the * bitfield passed in as @_reg by masking and shifting it down. @@ -108,20 +160,18 @@ extern void __compiletime_error("value doesn't fit into mask") __field_overflow(void); extern void __compiletime_error("bad bitfield mask") __bad_mask(void); - static __always_inline u64 field_multiplier(u64 field) { if ((field | (field - 1)) & ((field | (field - 1)) + 1)) __bad_mask(); return field & -field; } - static __always_inline u64 field_mask(u64 field) { return field / field_multiplier(field); } - -#define ____MAKE_OP(type, base, to, from) \ +#define field_max(field) ((typeof(field))field_mask(field)) +#define ____MAKE_OP(type,base,to,from) \ static __always_inline __##type type##_encode_bits(base v, base field) \ { \ if (__builtin_constant_p(v) && (v & ~field_mask(field))) \ @@ -133,26 +183,23 @@ static __always_inline __##type type##_replace_bits(__##type old, \ { \ return (old & ~to(field)) | type##_encode_bits(val, field); \ } \ -static __always_inline void type##p_replace_bits(__##type * p, \ +static __always_inline void type##p_replace_bits(__##type *p, \ base val, base field) \ { \ *p = (*p & ~to(field)) | type##_encode_bits(val, field); \ } \ static __always_inline base type##_get_bits(__##type v, base field) \ { \ - return (from(v) & field) / field_multiplier(field); \ + return (from(v) & field)/field_multiplier(field); \ } - #define __MAKE_OP(size) \ - ____MAKE_OP(le##size, u##size, cpu_to_le##size, le##size##_to_cpu) \ - ____MAKE_OP(be##size, u##size, cpu_to_be##size, be##size##_to_cpu) \ - ____MAKE_OP(u##size, u##size, ,) - -____MAKE_OP(u8, u8, ,) + ____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \ + ____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \ + ____MAKE_OP(u##size,u##size,,) +____MAKE_OP(u8,u8,,) __MAKE_OP(16) __MAKE_OP(32) __MAKE_OP(64) - #undef __MAKE_OP #undef ____MAKE_OP From fe37fb8214e40ea64cf03453d112527b629fb08a Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sat, 7 Jun 2025 23:11:21 +0200 Subject: [PATCH 5/5] mtd: spinand: winbond: add Winbond W25N04KV flash support Add Winbond W25N04KV flash support that use a different value to detect ECC bitflip. Signed-off-by: Christian Marangi --- drivers/mtd/nand/spi/winbond.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c index dd4ed257a83..16abf89dbbf 100644 --- a/drivers/mtd/nand/spi/winbond.c +++ b/drivers/mtd/nand/spi/winbond.c @@ -11,6 +11,7 @@ #include #include #endif +#include #include #include @@ -18,6 +19,8 @@ #define WINBOND_CFG_BUF_READ BIT(3) +#define W25N04KV_STATUS_ECC_5_8_BITFLIPS FIELD_PREP_CONST(STATUS_ECC_MASK, 0x3) + static SPINAND_OP_VARIANTS(read_cache_variants, SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), @@ -121,6 +124,7 @@ static int w25n02kv_ecc_get_status(struct spinand_device *spinand, return -EBADMSG; case STATUS_ECC_HAS_BITFLIPS: + case W25N04KV_STATUS_ECC_5_8_BITFLIPS: /* * Let's try to retrieve the real maximum number of bitflips * in order to avoid forcing the wear-leveling layer to move @@ -172,6 +176,15 @@ static const struct spinand_info winbond_spinand_table[] = { &update_cache_variants), 0, SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)), + SPINAND_INFO("W25N04KV", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x23), + NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 2, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + 0, + SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)), }; static int winbond_spinand_init(struct spinand_device *spinand)