From 422222f5170ac399f0e5fd39290f8508ad777fcc Mon Sep 17 00:00:00 2001 From: Emanuele Ghidoli Date: Tue, 20 May 2025 11:09:17 +0200 Subject: linux/sizes.h: sync from kernel The kernel added new size definitions and substituted the boilerplate/reference to the license with a SPDX identifier. Drop a local SZ_8G definition in MediaTek MT7988 SoC board file. Signed-off-by: Emanuele Ghidoli Reviewed-by: Tom Rini Reviewed-by: Weijie Gao --- include/linux/sizes.h | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sizes.h b/include/linux/sizes.h index fbde0bc7e88..49039494076 100644 --- a/include/linux/sizes.h +++ b/include/linux/sizes.h @@ -1,9 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * include/linux/sizes.h - * - * 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. */ #ifndef __LINUX_SIZES_H__ #define __LINUX_SIZES_H__ @@ -26,17 +23,25 @@ #define SZ_4K 0x00001000 #define SZ_8K 0x00002000 #define SZ_16K 0x00004000 +#define SZ_24K 0x00006000 #define SZ_32K 0x00008000 #define SZ_64K 0x00010000 #define SZ_128K 0x00020000 +#define SZ_192K 0x00030000 #define SZ_256K 0x00040000 +#define SZ_384K 0x00060000 #define SZ_512K 0x00080000 #define SZ_1M 0x00100000 #define SZ_2M 0x00200000 +#define SZ_3M 0x00300000 #define SZ_4M 0x00400000 +#define SZ_6M 0x00600000 #define SZ_8M 0x00800000 +#define SZ_12M 0x00c00000 #define SZ_16M 0x01000000 +#define SZ_18M 0x01200000 +#define SZ_24M 0x01800000 #define SZ_32M 0x02000000 #define SZ_64M 0x04000000 #define SZ_128M 0x08000000 @@ -47,5 +52,20 @@ #define SZ_2G 0x80000000 #define SZ_4G _AC(0x100000000, ULL) +#define SZ_8G _AC(0x200000000, ULL) +#define SZ_16G _AC(0x400000000, ULL) +#define SZ_32G _AC(0x800000000, ULL) +#define SZ_64G _AC(0x1000000000, ULL) +#define SZ_128G _AC(0x2000000000, ULL) +#define SZ_256G _AC(0x4000000000, ULL) +#define SZ_512G _AC(0x8000000000, ULL) + +#define SZ_1T _AC(0x10000000000, ULL) +#define SZ_2T _AC(0x20000000000, ULL) +#define SZ_4T _AC(0x40000000000, ULL) +#define SZ_8T _AC(0x80000000000, ULL) +#define SZ_16T _AC(0x100000000000, ULL) +#define SZ_32T _AC(0x200000000000, ULL) +#define SZ_64T _AC(0x400000000000, ULL) #endif /* __LINUX_SIZES_H__ */ -- cgit v1.3.1 From 0846bad0d08b53f6abaa4c8afe812dba93057424 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 27 May 2025 15:27:46 +0200 Subject: clk: add CONFIG_CLK_AUTO_ID Add a new config CONFIG_CLK_AUTO_ID to support a unique clk id for all the clock providers, managed by clk uclass, when the clock reference arg[0] is the same. When the CONFIG is activated, the clock id is limited to the lower CLK_ID_SZ = 24 bits in default clock xlate function and the sequence number + 1 of the clk provider device is added for the 8 higher bits. We use sequence number + 1 to avoid the "dummy" clock id = 0, used for invalid clock when CCF is activated. When this config is activated, the new function clk_get_id() should be used to get back the internal reference to clock for the each clock provider. Signed-off-by: Patrick Delaunay Signed-off-by: Patrice Chotard Cc: Lukasz Majewski Cc: Sean Anderson Reviewed-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- drivers/clk/Kconfig | 10 ++++++++++ drivers/clk/clk-uclass.c | 9 +++++++-- drivers/clk/stm32/clk-stm32-core.c | 3 ++- include/clk.h | 24 ++++++++++++++++++++++++ include/linux/clk-provider.h | 9 ++++++++- 5 files changed, 51 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 19aa2ffa539..8dbcc35335f 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -10,6 +10,16 @@ config CLK feed into other clocks in a tree structure, with multiplexers to choose the source for each clock. +config CLK_AUTO_ID + bool "Enable support of an unique clock id with several provider" + depends on CLK + help + Add the uclass sequence number of clock provider in the 8 higher bits + of the clk id to guaranty an unique clock identifier in clk uclass + when several clock providers are present on the device and when + default xlate are used. + This feature limit each identifier for each clock providers (24 bits). + config SPL_CLK bool "Enable clock support in SPL" depends on CLK && SPL && SPL_DM diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index 2167cd5ad0f..7262e89b512 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -34,6 +34,11 @@ struct clk *dev_get_clk_ptr(struct udevice *dev) return (struct clk *)dev_get_uclass_priv(dev); } +ulong clk_get_id(const struct clk *clk) +{ + return (ulong)(clk->id & CLK_ID_MSK); +} + #if CONFIG_IS_ENABLED(OF_PLATDATA) int clk_get_by_phandle(struct udevice *dev, const struct phandle_1_arg *cells, struct clk *clk) @@ -43,7 +48,7 @@ int clk_get_by_phandle(struct udevice *dev, const struct phandle_1_arg *cells, ret = device_get_by_ofplat_idx(cells->idx, &clk->dev); if (ret) return ret; - clk->id = cells->arg[0]; + clk->id = CLK_ID(dev, cells->arg[0]); return 0; } @@ -61,7 +66,7 @@ static int clk_of_xlate_default(struct clk *clk, } if (args->args_count) - clk->id = args->args[0]; + clk->id = CLK_ID(clk->dev, args->args[0]); else clk->id = 0; diff --git a/drivers/clk/stm32/clk-stm32-core.c b/drivers/clk/stm32/clk-stm32-core.c index 358ee56682a..df3b35b1003 100644 --- a/drivers/clk/stm32/clk-stm32-core.c +++ b/drivers/clk/stm32/clk-stm32-core.c @@ -46,7 +46,8 @@ int stm32_rcc_init(struct udevice *dev, if (cfg->setup) { clk = cfg->setup(dev, cfg); - clk->id = cfg->id; + /* set identifier of clock provider*/ + dev_clk_dm(dev, cfg->id, clk); } else { dev_err(dev, "failed to register clock %s\n", cfg->name); return -ENOENT; diff --git a/include/clk.h b/include/clk.h index a6ef4e02692..f94135ff778 100644 --- a/include/clk.h +++ b/include/clk.h @@ -13,6 +13,15 @@ #include #include +#ifdef CONFIG_CLK_AUTO_ID +#define CLK_ID_SZ 24 +#define CLK_ID_MSK GENMASK(23, 0) +#define CLK_ID(dev, id) (((dev_seq(dev) + 1) << CLK_ID_SZ) | ((id) & CLK_ID_MSK)) +#else +#define CLK_ID_MSK (~0UL) +#define CLK_ID(dev, id) id +#endif + /** * DOC: Overview * @@ -570,6 +579,16 @@ int clk_get_by_id(ulong id, struct clk **clkp); */ bool clk_dev_binded(struct clk *clk); +/** + * clk_get_id - get clk id + * + * @clk: A clock struct + * + * Return: the clock identifier as it is defined by the clock provider in + * device tree or in platdata + */ +ulong clk_get_id(const struct clk *clk); + #else /* CONFIG_IS_ENABLED(CLK) */ static inline int clk_request(struct udevice *dev, struct clk *clk) @@ -641,6 +660,11 @@ static inline bool clk_dev_binded(struct clk *clk) { return false; } + +static inline ulong clk_get_id(const struct clk *clk) +{ + return 0; +} #endif /* CONFIG_IS_ENABLED(CLK) */ /** diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 267757939e0..2d754fa4287 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -15,10 +15,17 @@ struct udevice; +/* update clock ID for the dev = clock provider, compatible with CLK_AUTO_ID */ +static inline void dev_clk_dm(const struct udevice *dev, ulong id, struct clk *clk) +{ + if (!IS_ERR(clk)) + clk->id = CLK_ID(dev, id); +} + static inline void clk_dm(ulong id, struct clk *clk) { if (!IS_ERR(clk)) - clk->id = id; + clk->id = CLK_ID(clk->dev, id); } /* -- cgit v1.3.1 From 01cc7046ad2a1537791cda5175bce281f0a0acfc Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Sat, 7 Jun 2025 23:11:20 +0200 Subject: 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(-) (limited to 'include/linux') 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 -- cgit v1.3.1 From c1c2b5c6a4c09fe57933b70ec6289795f732ac83 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 7 May 2025 14:12:43 +0200 Subject: linux/list.h: drop use of prefetch() The use of prefetch() in these list helpers was dropped back in 2011 in linux (e66eed651fd1 ("list: remove prefetching from regular list iterators")). No arch in U-Boot defines any actual prefetch(), and as the referenced commit says, it's usually not a win anyway. Whole-sale sync of list.h is not really feasible, but we can synchronize the macros containing a prefetch() with their linux implementations as of v6.15-rc5, also importing the various helpers needed, e.g. list_is_head() and list_next_entry(). Signed-off-by: Rasmus Villemoes --- include/linux/list.h | 99 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 40 deletions(-) (limited to 'include/linux') diff --git a/include/linux/list.h b/include/linux/list.h index 0f9d939b05f..e21ae03b208 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -169,6 +169,16 @@ static inline int list_is_last(const struct list_head *list, return list->next == head; } +/** + * list_is_head - tests whether @list is the list @head + * @list: the entry to test + * @head: the head of the list + */ +static inline int list_is_head(const struct list_head *list, const struct list_head *head) +{ + return list == head; +} + /** * list_empty - tests whether a list is empty * @head: the list to test. @@ -363,26 +373,28 @@ static inline void list_splice_tail_init(struct list_head *list, }) /** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. + * list_next_entry - get the next element in list + * @pos: the type * to cursor + * @member: the name of the list_head within the struct. */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; prefetch(pos->next), pos != (head); \ - pos = pos->next) +#define list_next_entry(pos, member) \ + list_entry((pos)->member.next, typeof(*(pos)), member) + +/** + * list_prev_entry - get the prev element in list + * @pos: the type * to cursor + * @member: the name of the list_head within the struct. + */ +#define list_prev_entry(pos, member) \ + list_entry((pos)->member.prev, typeof(*(pos)), member) /** - * __list_for_each - iterate over a list + * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. - * - * This variant differs from list_for_each() in that it's the - * simplest possible list iteration code, no prefetching is done. - * Use this for code that knows the list to be very short (empty - * or 1 entry) most of the time. */ -#define __list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) +#define list_for_each(pos, head) \ + for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next) /** * list_for_each_prev - iterate over a list backwards @@ -390,8 +402,7 @@ static inline void list_splice_tail_init(struct list_head *list, * @head: the head for your list. */ #define list_for_each_prev(pos, head) \ - for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \ - pos = pos->prev) + for (pos = (head)->prev; !list_is_head(pos, (head)); pos = pos->prev) /** * list_for_each_safe - iterate over a list safe against removal of list entry @@ -411,30 +422,39 @@ static inline void list_splice_tail_init(struct list_head *list, */ #define list_for_each_prev_safe(pos, n, head) \ for (pos = (head)->prev, n = pos->prev; \ - prefetch(pos->prev), pos != (head); \ + !list_is_head(pos, (head)); \ pos = n, n = pos->prev) +/** + * list_entry_is_head - test if the entry points to the head of the list + * @pos: the type * to cursor + * @head: the head for your list. + * @member: the name of the list_head within the struct. + */ +#define list_entry_is_head(pos, head, member) \ + list_is_head(&pos->member, (head)) + /** * list_for_each_entry - iterate over list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) + for (pos = list_first_entry(head, typeof(*pos), member); \ + !list_entry_is_head(pos, head, member); \ + pos = list_next_entry(pos, member)) /** * list_for_each_entry_reverse - iterate backwards over list of given type. * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. */ #define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ - prefetch(pos->member.prev), &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) + for (pos = list_last_entry(head, typeof(*pos), member); \ + !list_entry_is_head(pos, head, member); \ + pos = list_prev_entry(pos, member)) /** * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue() @@ -451,41 +471,41 @@ static inline void list_splice_tail_init(struct list_head *list, * list_for_each_entry_continue - continue iteration over list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Continue to iterate over list of given type, continuing after * the current position. */ -#define list_for_each_entry_continue(pos, head, member) \ - for (pos = list_entry(pos->member.next, typeof(*pos), member); \ - prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) +#define list_for_each_entry_continue(pos, head, member) \ + for (pos = list_next_entry(pos, member); \ + !list_entry_is_head(pos, head, member); \ + pos = list_next_entry(pos, member)) /** * list_for_each_entry_continue_reverse - iterate backwards from the given point * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Start to iterate over list of given type backwards, continuing after * the current position. */ #define list_for_each_entry_continue_reverse(pos, head, member) \ - for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ - prefetch(pos->member.prev), &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) + for (pos = list_prev_entry(pos, member); \ + !list_entry_is_head(pos, head, member); \ + pos = list_prev_entry(pos, member)) /** * list_for_each_entry_from - iterate over list of given type from the current point * @pos: the type * to use as a loop cursor. * @head: the head for your list. - * @member: the name of the list_struct within the struct. + * @member: the name of the list_head within the struct. * * Iterate over list of given type, continuing from current position. */ -#define list_for_each_entry_from(pos, head, member) \ - for (; prefetch(pos->member.next), &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) +#define list_for_each_entry_from(pos, head, member) \ + for (; !list_entry_is_head(pos, head, member); \ + pos = list_next_entry(pos, member)) /** * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry @@ -654,8 +674,7 @@ static inline void hlist_add_after(struct hlist_node *n, #define hlist_entry(ptr, type, member) container_of(ptr,type,member) #define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \ - pos = pos->next) + for (pos = (head)->first; pos ; pos = pos->next) #define hlist_for_each_safe(pos, n, head) \ for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \ -- cgit v1.3.1 From 1d19bbcb68280814952bdc18d7dec6d083b2c0ef Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 7 May 2025 14:12:46 +0200 Subject: linux/list.h: drop fallback definition of prefetch() None of the list helpers use prefetch() anymore, and no C code relies on getting this definition from list.h. In any case, such an arch/cpu specific thing does not belong in a header that just consists of cpp helper macros. Signed-off-by: Rasmus Villemoes --- include/linux/list.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/list.h b/include/linux/list.h index e21ae03b208..3dc38279716 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -4,11 +4,6 @@ #include #include -#ifndef ARCH_HAS_PREFETCH -#define ARCH_HAS_PREFETCH -static inline void prefetch(const void *x) {;} -#endif - /* * Simple doubly linked list implementation. * -- cgit v1.3.1 From 3bc174031d3cbcf176b22fc2869b486011fa194c Mon Sep 17 00:00:00 2001 From: Moteen Shah Date: Mon, 9 Jun 2025 13:44:29 +0530 Subject: ti_sci_*: Add utility to access tisci firmware and SOC capability Introduce response and request structs for receiving information regarding FW/SOC capability from DM. The received capability can further be used to call certain API's based on the feature supoorted by the DM firmware. Signed-off-by: Moteen Shah Reviewed-by: Neha Malcom Francis Reviewed-by: Dhruva Gole --- drivers/firmware/ti_sci.h | 13 +++++++++++++ include/linux/soc/ti/ti_sci_protocol.h | 13 +++++++++++++ 2 files changed, 26 insertions(+) (limited to 'include/linux') diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index bb8bc7beead..292f7cd578a 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -27,6 +27,7 @@ #define TI_SCI_MSG_BOARD_CONFIG_SECURITY 0x000d #define TI_SCI_MSG_BOARD_CONFIG_PM 0x000e #define TISCI_MSG_QUERY_MSMC 0x0020 +#define TI_SCI_MSG_QUERY_FW_CAPS 0x0022 /* Device requests */ #define TI_SCI_MSG_SET_DEVICE_STATE 0x0200 @@ -134,6 +135,18 @@ struct ti_sci_msg_resp_version { u8 abi_minor; } __packed; +/** + * struct ti_sci_query_fw_caps_resp - Response for a message + * @hdr: Generic header + * @fw_caps: 64-bit value representing the FW/SOC capabilities. + * + * Response to a message with message type TI_SCI_MSG_QUERY_FW_CAPS + */ +struct ti_sci_query_fw_caps_resp { + struct ti_sci_msg_hdr hdr; + u64 fw_caps; +} __packed; + /** * struct ti_sci_msg_req_reboot - Reboot the SoC * @hdr: Generic Header diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index aa4d105ee98..f967077b756 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -261,6 +261,18 @@ struct ti_sci_core_ops { u64 *msmc_start, u64 *msmc_end); }; +/** + * struct ti_sci_firmware_ops - DM firmware operations + * @query_dm_cap: Query the DM capabilities + * Return 0 for successful query else appropriate error value. + */ +struct ti_sci_firmware_ops { + int (*query_dm_cap)(struct ti_sci_handle *handle, + u64 *dm_cap); +}; + +#define TI_SCI_MSG_FLAG_FW_CAP_DM 0x100 + /** * struct ti_sci_proc_ops - Processor specific operations. * @@ -609,6 +621,7 @@ struct ti_sci_ops { struct ti_sci_dev_ops dev_ops; struct ti_sci_clk_ops clk_ops; struct ti_sci_core_ops core_ops; + struct ti_sci_firmware_ops fw_ops; struct ti_sci_proc_ops proc_ops; struct ti_sci_rm_core_ops rm_core_ops; struct ti_sci_rm_ringacc_ops rm_ring_ops; -- cgit v1.3.1 From 33fc7751b9adce0bc76989f399107078b2c21fd8 Mon Sep 17 00:00:00 2001 From: Moteen Shah Date: Mon, 9 Jun 2025 13:44:30 +0530 Subject: ti_sci_* : Add capability to access DM firmware's metadata Introduce response and request structs to receive and request information regarding DM version, etc from TI SCI. Signed-off-by: Moteen Shah Reviewed-by: Neha Malcom Francis Reviewed-by: Dhruva Gole --- drivers/firmware/ti_sci.h | 29 +++++++++++++++++++++++++++++ include/linux/soc/ti/ti_sci_protocol.h | 26 ++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) (limited to 'include/linux') diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index 292f7cd578a..ce50bf6800e 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -26,6 +26,7 @@ #define TI_SCI_MSG_BOARD_CONFIG_RM 0x000c #define TI_SCI_MSG_BOARD_CONFIG_SECURITY 0x000d #define TI_SCI_MSG_BOARD_CONFIG_PM 0x000e +#define TI_SCI_MSG_DM_VERSION 0x000f #define TISCI_MSG_QUERY_MSMC 0x0020 #define TI_SCI_MSG_QUERY_FW_CAPS 0x0022 @@ -135,6 +136,34 @@ struct ti_sci_msg_resp_version { u8 abi_minor; } __packed; +/** + * struct ti_sci_msg_dm_resp_version - Response for a message + * @hdr: Generic header + * @version: Version number of the firmware + * @sub_version: Sub-version number of the firmware + * @patch_version: Patch version number of the firmware + * @abi_major: Major version of the ABI that firmware supports + * @abi_minor: Minor version of the ABI that firmware supports + * @sci_server_version: String describing the SCI server version + * @rm_pm_hal_version: String describing the RM PM HAL version + * + * In general, ABI version changes follow the rule that minor version increments + * are backward compatible. Major revision changes in ABI may not be + * backward compatible. + * + * Response to a message with message type TI_SCI_MSG_DM_VERSION + */ +struct ti_sci_msg_dm_resp_version { + struct ti_sci_msg_hdr hdr; + u16 version; + u8 sub_version; + u8 patch_version; + u8 abi_major; + u8 abi_minor; + char rm_pm_hal_version[12]; + char sci_server_version[26]; +} __packed; + /** * struct ti_sci_query_fw_caps_resp - Response for a message * @hdr: Generic header diff --git a/include/linux/soc/ti/ti_sci_protocol.h b/include/linux/soc/ti/ti_sci_protocol.h index f967077b756..52696763ecf 100644 --- a/include/linux/soc/ti/ti_sci_protocol.h +++ b/include/linux/soc/ti/ti_sci_protocol.h @@ -30,6 +30,28 @@ struct ti_sci_version_info { char firmware_description[32]; }; +/** + * struct ti_sci_dm_version_info - version information structure + * @abi_major: Major ABI version. Change here implies risk of backward + * compatibility break. + * @abi_minor: Minor ABI version. Change here implies new feature addition, + * or compatible change in ABI. + * @patch_ver: Patch version of the firmware. + * @sub_ver: Sub-version of the firmware. + * @dm_ver: DM version. + * @sci_server_version: Version string of the SCI server. + * @rm_pm_hal_version: Version string of the RM PM HAL. + */ +struct ti_sci_dm_version_info { + u8 abi_major; + u8 abi_minor; + u8 patch_ver; + u8 sub_ver; + u16 dm_ver; + char rm_pm_hal_version[12]; + char sci_server_version[26]; +}; + struct ti_sci_handle; /** @@ -265,10 +287,14 @@ struct ti_sci_core_ops { * struct ti_sci_firmware_ops - DM firmware operations * @query_dm_cap: Query the DM capabilities * Return 0 for successful query else appropriate error value. + * @get_dm_version: Get the DM version. + * Return 0 for successful request else appropriate error value. */ struct ti_sci_firmware_ops { int (*query_dm_cap)(struct ti_sci_handle *handle, u64 *dm_cap); + int (*get_dm_version)(struct ti_sci_handle *handle, + struct ti_sci_dm_version_info *get_dm_version); }; #define TI_SCI_MSG_FLAG_FW_CAP_DM 0x100 -- cgit v1.3.1