Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] firmware: arm_scmi: Fix incorrect alloc_workqueue() invocation
From: Sudeep Holla @ 2023-04-21  9:27 UTC (permalink / raw)
  To: Cristian Marussi
  Cc: Tejun Heo, linux-arm-kernel, Sudeep Holla, linux-kernel,
	kernel-team
In-Reply-To: <ZEJNU1om5IhQHB2J@e120937-lin>

On Fri, Apr 21, 2023 at 09:46:11AM +0100, Cristian Marussi wrote:
> On Thu, Apr 20, 2023 at 09:33:49AM -1000, Tejun Heo wrote:
> > scmi_xfer_raw_worker_init() is specifying a flag, WQ_SYSFS, as @max_active.
> > Fix it by or'ing WQ_SYSFS into @flags so that it actually enables sysfs
> > interface and using 0 for @max_active for the default setting.
> >

Thanks, good catch, very hard to notice.

> 
> Hi Tejun,
> 
> my bad I messed up the params in the call.
>

Hi Cristian,

I think it deserves the fixes tag, right ?

Fixes: 3c3d818a9317 ("firmware: arm_scmi: Add core raw transmission support")

-- 
Regards,
Sudeep

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v5 06/11] dt-bindings: PCI: Update the RK3399 example to a valid one
From: Lorenzo Pieralisi @ 2023-04-21  9:26 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Rick Wertenbroek, alberto.dassatti, xxm, dlemoal, Shawn Lin,
	Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas,
	Krzysztof Kozlowski, Heiko Stuebner, Caleb Connolly,
	Corentin Labbe, Brian Norris, Johan Jonker, Judy Hsiao,
	Sascha Hauer, Hugh Cole-Baker, Arnaud Ferraris, linux-pci,
	linux-rockchip, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <172c46b7-256e-b09d-3940-880fa8989b49@linaro.org>

On Wed, Apr 19, 2023 at 10:01:25PM +0200, Krzysztof Kozlowski wrote:
> On 18/04/2023 09:46, Rick Wertenbroek wrote:
> > Update the example in the documentation to a valid example.
> > Address for mem-base was invalid, it pointed to address
> > 0x8000'0000 which is the upper region of the DDR which
> > is not necessarily populated depending on the board.
> > This address should point to the base of the memory
> > window region of the controller which is 0xfa00'0000.
> > Add missing pinctrl.
> > 
> > Signed-off-by: Rick Wertenbroek <rick.wertenbroek@gmail.com>
> > ---
> >  .../devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml      | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml b/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
> > index 88386a6d7011..6b62f6f58efe 100644
> > --- a/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
> > +++ b/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie-ep.yaml
> > @@ -47,7 +47,7 @@ examples:
> >  
> >          pcie-ep@f8000000 {
> >              compatible = "rockchip,rk3399-pcie-ep";
> > -            reg = <0x0 0xfd000000 0x0 0x1000000>, <0x0 0x80000000 0x0 0x20000>;
> > +            reg = <0x0 0xfd000000 0x0 0x1000000>, <0x0 0xfa000000 0x0 0x2000000>;
> >              reg-names = "apb-base", "mem-base";
> >              clocks = <&cru ACLK_PCIE>, <&cru ACLK_PERF_PCIE>,
> >                <&cru PCLK_PCIE>, <&cru SCLK_PCIE_PM>;
> > @@ -63,6 +63,8 @@ examples:
> >              phys = <&pcie_phy 0>, <&pcie_phy 1>, <&pcie_phy 2>, <&pcie_phy 3>;
> >              phy-names = "pcie-phy-0", "pcie-phy-1", "pcie-phy-2", "pcie-phy-3";
> >              rockchip,max-outbound-regions = <16>;
> > +            pinctrl-names = "default";
> > +            pinctrl-0 = <&pcie_clkreqnb_cpm>;
> 
> This is just example of the binding, you do not need to fill all
> unrelated (generic) properties like pinctrl.

Should I merge it as-is ?

Thanks,
Lorenzo

> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
> 
> Best regards,
> Krzysztof
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v7 4/5] arm64: dts: imx8mp: Add SAI, SDMA, AudioMIX
From: Marco Felsch @ 2023-04-21  9:26 UTC (permalink / raw)
  To: Richard Leitner
  Cc: Marek Vasut, linux-clk, Peng Fan, Fabio Estevam, Luca Ceresoli,
	Adam Ford, Alexander Stein, Abel Vesa, Jacky Bai,
	Krzysztof Kozlowski, Laurent Pinchart, Lucas Stach,
	Michael Turquette, NXP Linux Team, Pengutronix Kernel Team,
	Richard Cochran, Rob Herring, Sascha Hauer, Shawn Guo,
	Stephen Boyd, devicetree, linux-arm-kernel
In-Reply-To: <ZACNuAOJd+uXBKyJ@g0hl1n.net>

Hi Shawn,

On 23-03-02, Richard Leitner wrote:
> On Wed, Mar 01, 2023 at 05:32:56PM +0100, Marek Vasut wrote:
> > Add all SAI nodes, SDMA2 and SDMA3 nodes, and AudioMIX node. This is
> > needed to get audio operational on i.MX8MP .
> > 
> > Acked-by: Peng Fan <peng.fan@nxp.com>
> > Reviewed-by: Fabio Estevam <festevam@gmail.com>
> > Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
> > Reviewed-by: Marco Felsch <m.felsch@pengutronix.de>
> > Tested-by: Adam Ford <aford173@gmail.com> #imx8mp-beacon-kit
> > Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
> > Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
> > Signed-off-by: Marek Vasut <marex@denx.de>
> 
> Hi Marek,
> I've successfully tested this patch on a custom i.MX8MP board. Therefore
> please feel free to add:
> 
> Tested-by: Richard Leitner <richard.leitner@skidata.com>

Can you please pick patch 4 and 5? Patch 1-3 is already picked by Abel.

Thanks,
  Marco

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH] counter: stm32-timer-cnt: Reset TIM_TISEL and TIM_SMCR to their default value
From: Uwe Kleine-König @ 2023-04-21  9:24 UTC (permalink / raw)
  To: Lee Jones
  Cc: kernel, Maxime Coquelin, linux-iio, William Breathitt Gray,
	Alexandre Torgue, linux-kernel, Fabrice Gasnier, Thierry Reding,
	Olivier Moysan, linux-stm32, linux-arm-kernel
In-Reply-To: <20230420110111.GM9904@google.com>


[-- Attachment #1.1: Type: text/plain, Size: 1618 bytes --]

Hello Lee,

On Thu, Apr 20, 2023 at 12:01:11PM +0100, Lee Jones wrote:
> On Wed, 12 Apr 2023, Uwe Kleine-König wrote:
> 
> > The driver assumes that the input selection register (TIM_TISEL) is at
> > its reset default value. Usually this is the case, but the bootloader
> > might have modified it. Also reset the SMCR register while at it.
> > 
> > This bases on the effectively same patch submitted by Olivier Moysan for
> > pwm-stm32.
> > 
> > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> > ---
> > Hello,
> > 
> > note that the patch by Olivier Moysan[1] for pwm-stm32 is expected to
> > appear in Thierry's tree soon. It added the definition of TIM_TISEL in
> > the same way, so the two patches should merge just fine. Alternatively
> > you can commit it to a tree that already has the pwm change (and then
> > drop the change to include/linux/mfd/stm32-timers.h from this one).
> > 
> > Best regards
> > Uwe
> > 
> > [1] https://lore.kernel.org/linux-pwm/20221213102707.1096345-1-olivier.moysan@foss.st.com
> > 
> >  drivers/counter/stm32-timer-cnt.c | 4 ++++
> 
> >  include/linux/mfd/stm32-timers.h  | 1 +
> 
> Acked-by: Lee Jones <lee@kernel.org>

Note there is a v2 at
https://lore.kernel.org/r/20230413212339.3611722-1-u.kleine-koenig@pengutronix.de,
William wrote that he already applied it, so replying with tag in that
thread might be already to late, too.

(nevertheless) Thanks
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v2] wifi: mt7601u: delete dead code checking debugfs returns
From: Wang Jikai @ 2023-04-21  9:22 UTC (permalink / raw)
  To: Jakub Kicinski, Kalle Valo, David S. Miller, Eric Dumazet,
	Paolo Abeni, Matthias Brugger, AngeloGioacchino Del Regno
  Cc: hust-os-kernel-patches, Wang Jikai, linux-wireless, netdev,
	linux-kernel, linux-arm-kernel, linux-mediatek

Smatch reports that:
drivers/net/wireless/mediatek/mt7601u/debugfs.c:130
mt7601u_init_debugfs() warn: 'dir' is an error pointer or valid".

Debugfs code is not supposed to need error checking so instead of
changing this to if (IS_ERR()) the correct thing is to just delete
the dead code.

Signed-off-by: Wang Jikai <wangjikai@hust.edu.cn>
---
v1 -> v2: not add redundant removal of debugfs dir. remove fixes
tag.

The issue is found by static analysis and remains untested.
---
 drivers/net/wireless/mediatek/mt7601u/debugfs.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt7601u/debugfs.c b/drivers/net/wireless/mediatek/mt7601u/debugfs.c
index 230b0e1061a7..dbddf256921b 100644
--- a/drivers/net/wireless/mediatek/mt7601u/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt7601u/debugfs.c
@@ -127,8 +127,6 @@ void mt7601u_init_debugfs(struct mt7601u_dev *dev)
 	struct dentry *dir;
 
 	dir = debugfs_create_dir("mt7601u", dev->hw->wiphy->debugfsdir);
-	if (!dir)
-		return;
 
 	debugfs_create_u8("temperature", 0400, dir, &dev->raw_temp);
 	debugfs_create_u32("temp_mode", 0400, dir, &dev->temp_mode);
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH] kasan: use internal prototypes matching gcc-13 builtins
From: Marco Elver @ 2023-04-21  9:19 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Andrey Ryabinin, Andrew Morton, Arnd Bergmann, Catalin Marinas,
	Will Deacon, Alexander Potapenko, Andrey Konovalov, Dmitry Vyukov,
	Vincenzo Frascino, Mark Rutland, Kees Cook, Ard Biesheuvel,
	Marc Zyngier, Matthew Wilcox (Oracle), Vlastimil Babka,
	Peter Zijlstra (Intel), linux-arm-kernel, linux-kernel, kasan-dev,
	linux-mm
In-Reply-To: <20230421082026.2115712-1-arnd@kernel.org>

On Fri, 21 Apr 2023 at 10:20, Arnd Bergmann <arnd@kernel.org> wrote:
>
> From: Arnd Bergmann <arnd@arndb.de>
>
> gcc-13 warns about function definitions for builtin interfaces
> that have a different prototype, e.g.:
>
> In file included from kasan_test.c:31:
> kasan.h:574:6: error: conflicting types for built-in function '__asan_register_globals'; expected 'void(void *, long int)' [-Werror=builtin-declaration-mismatch]
>   574 | void __asan_register_globals(struct kasan_global *globals, size_t size);
> kasan.h:577:6: error: conflicting types for built-in function '__asan_alloca_poison'; expected 'void(void *, long int)' [-Werror=builtin-declaration-mismatch]
>   577 | void __asan_alloca_poison(unsigned long addr, size_t size);
> kasan.h:580:6: error: conflicting types for built-in function '__asan_load1'; expected 'void(void *)' [-Werror=builtin-declaration-mismatch]
>   580 | void __asan_load1(unsigned long addr);
> kasan.h:581:6: error: conflicting types for built-in function '__asan_store1'; expected 'void(void *)' [-Werror=builtin-declaration-mismatch]
>   581 | void __asan_store1(unsigned long addr);
> kasan.h:643:6: error: conflicting types for built-in function '__hwasan_tag_memory'; expected 'void(void *, unsigned char,  long int)' [-Werror=builtin-declaration-mismatch]
>   643 | void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size);
>
> The two problems are:
>
>  - Addresses are passes as 'unsigned long' in the kernel, but gcc-13
>    expects a 'void *'.
>
>  - sizes are expected to be the built-in ssize_t type, not the one that
>    is provided by the kernel. On 32-bit architectures, this is usually
>    a signed 'int' rather than 'unsigned long.
>
> Change all the prototypes to match these, using a custom 'kasan_size_t'
> that is defined the way that gcc expects it regardless of the kernel's
> size_t/ssize_t. Using 'void *' consistently for addresses gets rid of
> a couple of type casts, so push that down to the leaf functions where
> possible.
>
> This now passes all randconfig builds on arm, arm64 and x86, but I have
> not tested it on the other architectures that support kasan, since they
> tend to fail randconfig builds in other ways. This might fail if any
> of the 32-bit architectures expect a 'long' instead of 'int' for the size
> argument.
>
> The __asan_allocas_unpoison() function prototype is somewhat weird,
> since it uses a pointer for 'stack_top' and an size_t for 'stack_bottom'.
> This looks like it is meant to be 'addr' and 'size' like the others,
> but the implementation clearly treats them as 'top' and 'bottom'.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>

Does it work with Clang?

I don't mind either way, but the custom kasan_size_t change seems to
just be needed to workaround the subtle inconsistency in type
definition, but in reality there should never be a problem. I'd rather
the KASAN code just uses normal kernel types and we just make the
compiler be quiet about it.

To do that, another option is -Wno-builtin-declaration-mismatch for
mm/kasan/ which just shuts up the compiler, and allows us to keep the
code as-is. Does it have any downsides?

> ---
>  arch/arm64/kernel/traps.c |   2 +-
>  arch/arm64/mm/fault.c     |   2 +-
>  include/linux/kasan.h     |   2 +-
>  mm/kasan/common.c         |   2 +-
>  mm/kasan/generic.c        |  72 ++++++++---------
>  mm/kasan/kasan.h          | 166 ++++++++++++++++++++------------------
>  mm/kasan/report.c         |  17 ++--
>  mm/kasan/report_generic.c |  12 +--
>  mm/kasan/report_hw_tags.c |   2 +-
>  mm/kasan/report_sw_tags.c |   2 +-
>  mm/kasan/shadow.c         |  36 ++++-----
>  mm/kasan/sw_tags.c        |  20 ++---
>  12 files changed, 170 insertions(+), 165 deletions(-)
>
> diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
> index 35a95b78b14f..3f5a21e5968e 100644
> --- a/arch/arm64/kernel/traps.c
> +++ b/arch/arm64/kernel/traps.c
> @@ -1044,7 +1044,7 @@ static int kasan_handler(struct pt_regs *regs, unsigned long esr)
>         bool recover = esr & KASAN_ESR_RECOVER;
>         bool write = esr & KASAN_ESR_WRITE;
>         size_t size = KASAN_ESR_SIZE(esr);
> -       u64 addr = regs->regs[0];
> +       void *addr = (void *)regs->regs[0];
>         u64 pc = regs->pc;
>
>         kasan_report(addr, size, write, pc);
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index f4418382be98..940391ec5e1e 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -317,7 +317,7 @@ static void report_tag_fault(unsigned long addr, unsigned long esr,
>          * find out access size.
>          */
>         bool is_write = !!(esr & ESR_ELx_WNR);
> -       kasan_report(addr, 0, is_write, regs->pc);
> +       kasan_report((void *)addr, 0, is_write, regs->pc);
>  }
>  #else
>  /* Tag faults aren't enabled without CONFIG_KASAN_HW_TAGS. */
> diff --git a/include/linux/kasan.h b/include/linux/kasan.h
> index f7ef70661ce2..819b6bc8ac08 100644
> --- a/include/linux/kasan.h
> +++ b/include/linux/kasan.h
> @@ -343,7 +343,7 @@ static inline void *kasan_reset_tag(const void *addr)
>   * @is_write: whether the bad access is a write or a read
>   * @ip: instruction pointer for the accessibility check or the bad access itself
>   */
> -bool kasan_report(unsigned long addr, size_t size,
> +bool kasan_report(const void *addr, size_t size,
>                 bool is_write, unsigned long ip);
>
>  #else /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */
> diff --git a/mm/kasan/common.c b/mm/kasan/common.c
> index b376a5d055e5..256930da578a 100644
> --- a/mm/kasan/common.c
> +++ b/mm/kasan/common.c
> @@ -445,7 +445,7 @@ void * __must_check __kasan_krealloc(const void *object, size_t size, gfp_t flag
>  bool __kasan_check_byte(const void *address, unsigned long ip)
>  {
>         if (!kasan_byte_accessible(address)) {
> -               kasan_report((unsigned long)address, 1, false, ip);
> +               kasan_report(address, 1, false, ip);
>                 return false;
>         }
>         return true;
> diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c
> index e5eef670735e..c0cab050fbf7 100644
> --- a/mm/kasan/generic.c
> +++ b/mm/kasan/generic.c
> @@ -40,39 +40,39 @@
>   * depending on memory access size X.
>   */
>
> -static __always_inline bool memory_is_poisoned_1(unsigned long addr)
> +static __always_inline bool memory_is_poisoned_1(const void *addr)
>  {
> -       s8 shadow_value = *(s8 *)kasan_mem_to_shadow((void *)addr);
> +       s8 shadow_value = *(s8 *)kasan_mem_to_shadow(addr);
>
>         if (unlikely(shadow_value)) {
> -               s8 last_accessible_byte = addr & KASAN_GRANULE_MASK;
> +               s8 last_accessible_byte = (unsigned long)addr & KASAN_GRANULE_MASK;
>                 return unlikely(last_accessible_byte >= shadow_value);
>         }
>
>         return false;
>  }
>
> -static __always_inline bool memory_is_poisoned_2_4_8(unsigned long addr,
> +static __always_inline bool memory_is_poisoned_2_4_8(const void *addr,
>                                                 unsigned long size)
>  {
> -       u8 *shadow_addr = (u8 *)kasan_mem_to_shadow((void *)addr);
> +       u8 *shadow_addr = (u8 *)kasan_mem_to_shadow(addr);
>
>         /*
>          * Access crosses 8(shadow size)-byte boundary. Such access maps
>          * into 2 shadow bytes, so we need to check them both.
>          */
> -       if (unlikely(((addr + size - 1) & KASAN_GRANULE_MASK) < size - 1))
> +       if (unlikely((((unsigned long)addr + size - 1) & KASAN_GRANULE_MASK) < size - 1))
>                 return *shadow_addr || memory_is_poisoned_1(addr + size - 1);
>
>         return memory_is_poisoned_1(addr + size - 1);
>  }
>
> -static __always_inline bool memory_is_poisoned_16(unsigned long addr)
> +static __always_inline bool memory_is_poisoned_16(const void *addr)
>  {
> -       u16 *shadow_addr = (u16 *)kasan_mem_to_shadow((void *)addr);
> +       u16 *shadow_addr = (u16 *)kasan_mem_to_shadow(addr);
>
>         /* Unaligned 16-bytes access maps into 3 shadow bytes. */
> -       if (unlikely(!IS_ALIGNED(addr, KASAN_GRANULE_SIZE)))
> +       if (unlikely(!IS_ALIGNED((unsigned long)addr, KASAN_GRANULE_SIZE)))
>                 return *shadow_addr || memory_is_poisoned_1(addr + 15);
>
>         return *shadow_addr;
> @@ -120,26 +120,25 @@ static __always_inline unsigned long memory_is_nonzero(const void *start,
>         return bytes_is_nonzero(start, (end - start) % 8);
>  }
>
> -static __always_inline bool memory_is_poisoned_n(unsigned long addr,
> -                                               size_t size)
> +static __always_inline bool memory_is_poisoned_n(const void *addr, size_t size)
>  {
>         unsigned long ret;
>
> -       ret = memory_is_nonzero(kasan_mem_to_shadow((void *)addr),
> -                       kasan_mem_to_shadow((void *)addr + size - 1) + 1);
> +       ret = memory_is_nonzero(kasan_mem_to_shadow(addr),
> +                       kasan_mem_to_shadow(addr + size - 1) + 1);
>
>         if (unlikely(ret)) {
> -               unsigned long last_byte = addr + size - 1;
> -               s8 *last_shadow = (s8 *)kasan_mem_to_shadow((void *)last_byte);
> +               const void *last_byte = addr + size - 1;
> +               s8 *last_shadow = (s8 *)kasan_mem_to_shadow(last_byte);
>
>                 if (unlikely(ret != (unsigned long)last_shadow ||
> -                       ((long)(last_byte & KASAN_GRANULE_MASK) >= *last_shadow)))
> +                       (((long)last_byte & KASAN_GRANULE_MASK) >= *last_shadow)))
>                         return true;
>         }
>         return false;
>  }
>
> -static __always_inline bool memory_is_poisoned(unsigned long addr, size_t size)
> +static __always_inline bool memory_is_poisoned(const void *addr, size_t size)
>  {
>         if (__builtin_constant_p(size)) {
>                 switch (size) {
> @@ -159,7 +158,7 @@ static __always_inline bool memory_is_poisoned(unsigned long addr, size_t size)
>         return memory_is_poisoned_n(addr, size);
>  }
>
> -static __always_inline bool check_region_inline(unsigned long addr,
> +static __always_inline bool check_region_inline(const void *addr,
>                                                 size_t size, bool write,
>                                                 unsigned long ret_ip)
>  {
> @@ -172,7 +171,7 @@ static __always_inline bool check_region_inline(unsigned long addr,
>         if (unlikely(addr + size < addr))
>                 return !kasan_report(addr, size, write, ret_ip);
>
> -       if (unlikely(!addr_has_metadata((void *)addr)))
> +       if (unlikely(!addr_has_metadata(addr)))
>                 return !kasan_report(addr, size, write, ret_ip);
>
>         if (likely(!memory_is_poisoned(addr, size)))
> @@ -181,7 +180,7 @@ static __always_inline bool check_region_inline(unsigned long addr,
>         return !kasan_report(addr, size, write, ret_ip);
>  }
>
> -bool kasan_check_range(unsigned long addr, size_t size, bool write,
> +bool kasan_check_range(const void *addr, size_t size, bool write,
>                                         unsigned long ret_ip)
>  {
>         return check_region_inline(addr, size, write, ret_ip);
> @@ -221,36 +220,37 @@ static void register_global(struct kasan_global *global)
>                      KASAN_GLOBAL_REDZONE, false);
>  }
>
> -void __asan_register_globals(struct kasan_global *globals, size_t size)
> +void __asan_register_globals(void *ptr, kasan_size_t size)
>  {
>         int i;
> +       struct kasan_global *globals = ptr;
>
>         for (i = 0; i < size; i++)
>                 register_global(&globals[i]);
>  }
>  EXPORT_SYMBOL(__asan_register_globals);
>
> -void __asan_unregister_globals(struct kasan_global *globals, size_t size)
> +void __asan_unregister_globals(void *ptr, kasan_size_t size)
>  {
>  }
>  EXPORT_SYMBOL(__asan_unregister_globals);
>
>  #define DEFINE_ASAN_LOAD_STORE(size)                                   \
> -       void __asan_load##size(unsigned long addr)                      \
> +       void __asan_load##size(void *addr)                              \
>         {                                                               \
>                 check_region_inline(addr, size, false, _RET_IP_);       \
>         }                                                               \
>         EXPORT_SYMBOL(__asan_load##size);                               \
>         __alias(__asan_load##size)                                      \
> -       void __asan_load##size##_noabort(unsigned long);                \
> +       void __asan_load##size##_noabort(void *);                       \
>         EXPORT_SYMBOL(__asan_load##size##_noabort);                     \
> -       void __asan_store##size(unsigned long addr)                     \
> +       void __asan_store##size(void *addr)                             \
>         {                                                               \
>                 check_region_inline(addr, size, true, _RET_IP_);        \
>         }                                                               \
>         EXPORT_SYMBOL(__asan_store##size);                              \
>         __alias(__asan_store##size)                                     \
> -       void __asan_store##size##_noabort(unsigned long);               \
> +       void __asan_store##size##_noabort(void *);                      \
>         EXPORT_SYMBOL(__asan_store##size##_noabort)
>
>  DEFINE_ASAN_LOAD_STORE(1);
> @@ -259,24 +259,24 @@ DEFINE_ASAN_LOAD_STORE(4);
>  DEFINE_ASAN_LOAD_STORE(8);
>  DEFINE_ASAN_LOAD_STORE(16);
>
> -void __asan_loadN(unsigned long addr, size_t size)
> +void __asan_loadN(void *addr, kasan_size_t size)
>  {
>         kasan_check_range(addr, size, false, _RET_IP_);
>  }
>  EXPORT_SYMBOL(__asan_loadN);
>
>  __alias(__asan_loadN)
> -void __asan_loadN_noabort(unsigned long, size_t);
> +void __asan_loadN_noabort(void *, kasan_size_t);
>  EXPORT_SYMBOL(__asan_loadN_noabort);
>
> -void __asan_storeN(unsigned long addr, size_t size)
> +void __asan_storeN(void *addr, kasan_size_t size)
>  {
>         kasan_check_range(addr, size, true, _RET_IP_);
>  }
>  EXPORT_SYMBOL(__asan_storeN);
>
>  __alias(__asan_storeN)
> -void __asan_storeN_noabort(unsigned long, size_t);
> +void __asan_storeN_noabort(void *, kasan_size_t);
>  EXPORT_SYMBOL(__asan_storeN_noabort);
>
>  /* to shut up compiler complaints */
> @@ -284,7 +284,7 @@ void __asan_handle_no_return(void) {}
>  EXPORT_SYMBOL(__asan_handle_no_return);
>
>  /* Emitted by compiler to poison alloca()ed objects. */
> -void __asan_alloca_poison(unsigned long addr, size_t size)
> +void __asan_alloca_poison(void *addr, kasan_size_t size)
>  {
>         size_t rounded_up_size = round_up(size, KASAN_GRANULE_SIZE);
>         size_t padding_size = round_up(size, KASAN_ALLOCA_REDZONE_SIZE) -
> @@ -295,7 +295,7 @@ void __asan_alloca_poison(unsigned long addr, size_t size)
>                         KASAN_ALLOCA_REDZONE_SIZE);
>         const void *right_redzone = (const void *)(addr + rounded_up_size);
>
> -       WARN_ON(!IS_ALIGNED(addr, KASAN_ALLOCA_REDZONE_SIZE));
> +       WARN_ON(!IS_ALIGNED((unsigned long)addr, KASAN_ALLOCA_REDZONE_SIZE));
>
>         kasan_unpoison((const void *)(addr + rounded_down_size),
>                         size - rounded_down_size, false);
> @@ -307,18 +307,18 @@ void __asan_alloca_poison(unsigned long addr, size_t size)
>  EXPORT_SYMBOL(__asan_alloca_poison);
>
>  /* Emitted by compiler to unpoison alloca()ed areas when the stack unwinds. */
> -void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom)
> +void __asan_allocas_unpoison(void *stack_top, kasan_size_t stack_bottom)
>  {
> -       if (unlikely(!stack_top || stack_top > stack_bottom))
> +       if (unlikely(!stack_top || stack_top > (void *)stack_bottom))
>                 return;
>
> -       kasan_unpoison(stack_top, stack_bottom - stack_top, false);
> +       kasan_unpoison(stack_top, (void *)stack_bottom - stack_top, false);
>  }
>  EXPORT_SYMBOL(__asan_allocas_unpoison);
>
>  /* Emitted by the compiler to [un]poison local variables. */
>  #define DEFINE_ASAN_SET_SHADOW(byte) \
> -       void __asan_set_shadow_##byte(const void *addr, size_t size)    \
> +       void __asan_set_shadow_##byte(const void *addr, kasan_size_t size)      \
>         {                                                               \
>                 __memset((void *)addr, 0x##byte, size);                 \
>         }                                                               \
> diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
> index cd846ca34f44..cce8fd1b33fb 100644
> --- a/mm/kasan/kasan.h
> +++ b/mm/kasan/kasan.h
> @@ -198,13 +198,13 @@ enum kasan_report_type {
>  struct kasan_report_info {
>         /* Filled in by kasan_report_*(). */
>         enum kasan_report_type type;
> -       void *access_addr;
> +       const void *access_addr;
>         size_t access_size;
>         bool is_write;
>         unsigned long ip;
>
>         /* Filled in by the common reporting code. */
> -       void *first_bad_addr;
> +       const void *first_bad_addr;
>         struct kmem_cache *cache;
>         void *object;
>         size_t alloc_size;
> @@ -289,6 +289,12 @@ struct kasan_stack_ring {
>
>  #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */
>
> +#ifdef CONFIG_64BIT
> +typedef ssize_t kasan_size_t;
> +#else
> +typedef int kasan_size_t;
> +#endif
> +
>  #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
>
>  static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
> @@ -311,7 +317,7 @@ static __always_inline bool addr_has_metadata(const void *addr)
>   * @ret_ip: return address
>   * @return: true if access was valid, false if invalid
>   */
> -bool kasan_check_range(unsigned long addr, size_t size, bool write,
> +bool kasan_check_range(const void *addr, size_t size, bool write,
>                                 unsigned long ret_ip);
>
>  #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
> @@ -323,7 +329,7 @@ static __always_inline bool addr_has_metadata(const void *addr)
>
>  #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
>
> -void *kasan_find_first_bad_addr(void *addr, size_t size);
> +const void *kasan_find_first_bad_addr(const void *addr, size_t size);
>  size_t kasan_get_alloc_size(void *object, struct kmem_cache *cache);
>  void kasan_complete_mode_report_info(struct kasan_report_info *info);
>  void kasan_metadata_fetch_row(char *buffer, void *row);
> @@ -346,7 +352,7 @@ void kasan_print_aux_stacks(struct kmem_cache *cache, const void *object);
>  static inline void kasan_print_aux_stacks(struct kmem_cache *cache, const void *object) { }
>  #endif
>
> -bool kasan_report(unsigned long addr, size_t size,
> +bool kasan_report(const void *addr, size_t size,
>                 bool is_write, unsigned long ip);
>  void kasan_report_invalid_free(void *object, unsigned long ip, enum kasan_report_type type);
>
> @@ -571,82 +577,82 @@ void kasan_restore_multi_shot(bool enabled);
>   */
>
>  asmlinkage void kasan_unpoison_task_stack_below(const void *watermark);
> -void __asan_register_globals(struct kasan_global *globals, size_t size);
> -void __asan_unregister_globals(struct kasan_global *globals, size_t size);
> +void __asan_register_globals(void *globals, kasan_size_t size);
> +void __asan_unregister_globals(void *globals, kasan_size_t size);
>  void __asan_handle_no_return(void);
> -void __asan_alloca_poison(unsigned long addr, size_t size);
> -void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom);
> -
> -void __asan_load1(unsigned long addr);
> -void __asan_store1(unsigned long addr);
> -void __asan_load2(unsigned long addr);
> -void __asan_store2(unsigned long addr);
> -void __asan_load4(unsigned long addr);
> -void __asan_store4(unsigned long addr);
> -void __asan_load8(unsigned long addr);
> -void __asan_store8(unsigned long addr);
> -void __asan_load16(unsigned long addr);
> -void __asan_store16(unsigned long addr);
> -void __asan_loadN(unsigned long addr, size_t size);
> -void __asan_storeN(unsigned long addr, size_t size);
> -
> -void __asan_load1_noabort(unsigned long addr);
> -void __asan_store1_noabort(unsigned long addr);
> -void __asan_load2_noabort(unsigned long addr);
> -void __asan_store2_noabort(unsigned long addr);
> -void __asan_load4_noabort(unsigned long addr);
> -void __asan_store4_noabort(unsigned long addr);
> -void __asan_load8_noabort(unsigned long addr);
> -void __asan_store8_noabort(unsigned long addr);
> -void __asan_load16_noabort(unsigned long addr);
> -void __asan_store16_noabort(unsigned long addr);
> -void __asan_loadN_noabort(unsigned long addr, size_t size);
> -void __asan_storeN_noabort(unsigned long addr, size_t size);
> -
> -void __asan_report_load1_noabort(unsigned long addr);
> -void __asan_report_store1_noabort(unsigned long addr);
> -void __asan_report_load2_noabort(unsigned long addr);
> -void __asan_report_store2_noabort(unsigned long addr);
> -void __asan_report_load4_noabort(unsigned long addr);
> -void __asan_report_store4_noabort(unsigned long addr);
> -void __asan_report_load8_noabort(unsigned long addr);
> -void __asan_report_store8_noabort(unsigned long addr);
> -void __asan_report_load16_noabort(unsigned long addr);
> -void __asan_report_store16_noabort(unsigned long addr);
> -void __asan_report_load_n_noabort(unsigned long addr, size_t size);
> -void __asan_report_store_n_noabort(unsigned long addr, size_t size);
> -
> -void __asan_set_shadow_00(const void *addr, size_t size);
> -void __asan_set_shadow_f1(const void *addr, size_t size);
> -void __asan_set_shadow_f2(const void *addr, size_t size);
> -void __asan_set_shadow_f3(const void *addr, size_t size);
> -void __asan_set_shadow_f5(const void *addr, size_t size);
> -void __asan_set_shadow_f8(const void *addr, size_t size);
> -
> -void *__asan_memset(void *addr, int c, size_t len);
> -void *__asan_memmove(void *dest, const void *src, size_t len);
> -void *__asan_memcpy(void *dest, const void *src, size_t len);
> -
> -void __hwasan_load1_noabort(unsigned long addr);
> -void __hwasan_store1_noabort(unsigned long addr);
> -void __hwasan_load2_noabort(unsigned long addr);
> -void __hwasan_store2_noabort(unsigned long addr);
> -void __hwasan_load4_noabort(unsigned long addr);
> -void __hwasan_store4_noabort(unsigned long addr);
> -void __hwasan_load8_noabort(unsigned long addr);
> -void __hwasan_store8_noabort(unsigned long addr);
> -void __hwasan_load16_noabort(unsigned long addr);
> -void __hwasan_store16_noabort(unsigned long addr);
> -void __hwasan_loadN_noabort(unsigned long addr, size_t size);
> -void __hwasan_storeN_noabort(unsigned long addr, size_t size);
> -
> -void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size);
> -
> -void *__hwasan_memset(void *addr, int c, size_t len);
> -void *__hwasan_memmove(void *dest, const void *src, size_t len);
> -void *__hwasan_memcpy(void *dest, const void *src, size_t len);
> -
> -void kasan_tag_mismatch(unsigned long addr, unsigned long access_info,
> +void __asan_alloca_poison(void *, kasan_size_t size);
> +void __asan_allocas_unpoison(void *stack_top, kasan_size_t stack_bottom);
> +
> +void __asan_load1(void *);
> +void __asan_store1(void *);
> +void __asan_load2(void *);
> +void __asan_store2(void *);
> +void __asan_load4(void *);
> +void __asan_store4(void *);
> +void __asan_load8(void *);
> +void __asan_store8(void *);
> +void __asan_load16(void *);
> +void __asan_store16(void *);
> +void __asan_loadN(void *, kasan_size_t size);
> +void __asan_storeN(void *, kasan_size_t size);
> +
> +void __asan_load1_noabort(void *);
> +void __asan_store1_noabort(void *);
> +void __asan_load2_noabort(void *);
> +void __asan_store2_noabort(void *);
> +void __asan_load4_noabort(void *);
> +void __asan_store4_noabort(void *);
> +void __asan_load8_noabort(void *);
> +void __asan_store8_noabort(void *);
> +void __asan_load16_noabort(void *);
> +void __asan_store16_noabort(void *);
> +void __asan_loadN_noabort(void *, kasan_size_t size);
> +void __asan_storeN_noabort(void *, kasan_size_t size);
> +
> +void __asan_report_load1_noabort(void *);
> +void __asan_report_store1_noabort(void *);
> +void __asan_report_load2_noabort(void *);
> +void __asan_report_store2_noabort(void *);
> +void __asan_report_load4_noabort(void *);
> +void __asan_report_store4_noabort(void *);
> +void __asan_report_load8_noabort(void *);
> +void __asan_report_store8_noabort(void *);
> +void __asan_report_load16_noabort(void *);
> +void __asan_report_store16_noabort(void *);
> +void __asan_report_load_n_noabort(void *, kasan_size_t size);
> +void __asan_report_store_n_noabort(void *, kasan_size_t size);
> +
> +void __asan_set_shadow_00(const void *addr, kasan_size_t size);
> +void __asan_set_shadow_f1(const void *addr, kasan_size_t size);
> +void __asan_set_shadow_f2(const void *addr, kasan_size_t size);
> +void __asan_set_shadow_f3(const void *addr, kasan_size_t size);
> +void __asan_set_shadow_f5(const void *addr, kasan_size_t size);
> +void __asan_set_shadow_f8(const void *addr, kasan_size_t size);
> +
> +void *__asan_memset(void *addr, int c, kasan_size_t len);
> +void *__asan_memmove(void *dest, const void *src, kasan_size_t len);
> +void *__asan_memcpy(void *dest, const void *src, kasan_size_t len);
> +
> +void __hwasan_load1_noabort(void *);
> +void __hwasan_store1_noabort(void *);
> +void __hwasan_load2_noabort(void *);
> +void __hwasan_store2_noabort(void *);
> +void __hwasan_load4_noabort(void *);
> +void __hwasan_store4_noabort(void *);
> +void __hwasan_load8_noabort(void *);
> +void __hwasan_store8_noabort(void *);
> +void __hwasan_load16_noabort(void *);
> +void __hwasan_store16_noabort(void *);
> +void __hwasan_loadN_noabort(void *, kasan_size_t size);
> +void __hwasan_storeN_noabort(void *, kasan_size_t size);
> +
> +void __hwasan_tag_memory(void *, u8 tag, kasan_size_t size);
> +
> +void *__hwasan_memset(void *addr, int c, kasan_size_t len);
> +void *__hwasan_memmove(void *dest, const void *src, kasan_size_t len);
> +void *__hwasan_memcpy(void *dest, const void *src, kasan_size_t len);
> +
> +void kasan_tag_mismatch(void *addr, unsigned long access_info,
>                         unsigned long ret_ip);
>
>  #endif /* __MM_KASAN_KASAN_H */
> diff --git a/mm/kasan/report.c b/mm/kasan/report.c
> index 892a9dc9d4d3..84d9f3b37014 100644
> --- a/mm/kasan/report.c
> +++ b/mm/kasan/report.c
> @@ -211,7 +211,7 @@ static void start_report(unsigned long *flags, bool sync)
>         pr_err("==================================================================\n");
>  }
>
> -static void end_report(unsigned long *flags, void *addr)
> +static void end_report(unsigned long *flags, const void *addr)
>  {
>         if (addr)
>                 trace_error_report_end(ERROR_DETECTOR_KASAN,
> @@ -450,8 +450,8 @@ static void print_memory_metadata(const void *addr)
>
>  static void print_report(struct kasan_report_info *info)
>  {
> -       void *addr = kasan_reset_tag(info->access_addr);
> -       u8 tag = get_tag(info->access_addr);
> +       void *addr = kasan_reset_tag((void *)info->access_addr);
> +       u8 tag = get_tag((void *)info->access_addr);
>
>         print_error_description(info);
>         if (addr_has_metadata(addr))
> @@ -468,12 +468,12 @@ static void print_report(struct kasan_report_info *info)
>
>  static void complete_report_info(struct kasan_report_info *info)
>  {
> -       void *addr = kasan_reset_tag(info->access_addr);
> +       void *addr = kasan_reset_tag((void *)info->access_addr);
>         struct slab *slab;
>
>         if (info->type == KASAN_REPORT_ACCESS)
>                 info->first_bad_addr = kasan_find_first_bad_addr(
> -                                       info->access_addr, info->access_size);
> +                                       (void *)info->access_addr, info->access_size);
>         else
>                 info->first_bad_addr = addr;
>
> @@ -544,11 +544,10 @@ void kasan_report_invalid_free(void *ptr, unsigned long ip, enum kasan_report_ty
>   * user_access_save/restore(): kasan_report_invalid_free() cannot be called
>   * from a UACCESS region, and kasan_report_async() is not used on x86.
>   */
> -bool kasan_report(unsigned long addr, size_t size, bool is_write,
> +bool kasan_report(const void *addr, size_t size, bool is_write,
>                         unsigned long ip)
>  {
>         bool ret = true;
> -       void *ptr = (void *)addr;
>         unsigned long ua_flags = user_access_save();
>         unsigned long irq_flags;
>         struct kasan_report_info info;
> @@ -562,7 +561,7 @@ bool kasan_report(unsigned long addr, size_t size, bool is_write,
>
>         memset(&info, 0, sizeof(info));
>         info.type = KASAN_REPORT_ACCESS;
> -       info.access_addr = ptr;
> +       info.access_addr = addr;
>         info.access_size = size;
>         info.is_write = is_write;
>         info.ip = ip;
> @@ -571,7 +570,7 @@ bool kasan_report(unsigned long addr, size_t size, bool is_write,
>
>         print_report(&info);
>
> -       end_report(&irq_flags, ptr);
> +       end_report(&irq_flags, (void *)addr);
>
>  out:
>         user_access_restore(ua_flags);
> diff --git a/mm/kasan/report_generic.c b/mm/kasan/report_generic.c
> index 87d39bc0a673..080c73acbfcc 100644
> --- a/mm/kasan/report_generic.c
> +++ b/mm/kasan/report_generic.c
> @@ -30,9 +30,9 @@
>  #include "kasan.h"
>  #include "../slab.h"
>
> -void *kasan_find_first_bad_addr(void *addr, size_t size)
> +const void *kasan_find_first_bad_addr(const void *addr, size_t size)
>  {
> -       void *p = addr;
> +       const void *p = addr;
>
>         if (!addr_has_metadata(p))
>                 return p;
> @@ -362,14 +362,14 @@ void kasan_print_address_stack_frame(const void *addr)
>  #endif /* CONFIG_KASAN_STACK */
>
>  #define DEFINE_ASAN_REPORT_LOAD(size)                     \
> -void __asan_report_load##size##_noabort(unsigned long addr) \
> +void __asan_report_load##size##_noabort(void *addr) \
>  {                                                         \
>         kasan_report(addr, size, false, _RET_IP_);        \
>  }                                                         \
>  EXPORT_SYMBOL(__asan_report_load##size##_noabort)
>
>  #define DEFINE_ASAN_REPORT_STORE(size)                     \
> -void __asan_report_store##size##_noabort(unsigned long addr) \
> +void __asan_report_store##size##_noabort(void *addr) \
>  {                                                          \
>         kasan_report(addr, size, true, _RET_IP_);          \
>  }                                                          \
> @@ -386,13 +386,13 @@ DEFINE_ASAN_REPORT_STORE(4);
>  DEFINE_ASAN_REPORT_STORE(8);
>  DEFINE_ASAN_REPORT_STORE(16);
>
> -void __asan_report_load_n_noabort(unsigned long addr, size_t size)
> +void __asan_report_load_n_noabort(void *addr, kasan_size_t size)
>  {
>         kasan_report(addr, size, false, _RET_IP_);
>  }
>  EXPORT_SYMBOL(__asan_report_load_n_noabort);
>
> -void __asan_report_store_n_noabort(unsigned long addr, size_t size)
> +void __asan_report_store_n_noabort(void *addr, kasan_size_t size)
>  {
>         kasan_report(addr, size, true, _RET_IP_);
>  }
> diff --git a/mm/kasan/report_hw_tags.c b/mm/kasan/report_hw_tags.c
> index 32e80f78de7d..065e1b2fc484 100644
> --- a/mm/kasan/report_hw_tags.c
> +++ b/mm/kasan/report_hw_tags.c
> @@ -15,7 +15,7 @@
>
>  #include "kasan.h"
>
> -void *kasan_find_first_bad_addr(void *addr, size_t size)
> +const void *kasan_find_first_bad_addr(const void *addr, size_t size)
>  {
>         /*
>          * Hardware Tag-Based KASAN only calls this function for normal memory
> diff --git a/mm/kasan/report_sw_tags.c b/mm/kasan/report_sw_tags.c
> index 8b1f5a73ee6d..689e94f9fe3c 100644
> --- a/mm/kasan/report_sw_tags.c
> +++ b/mm/kasan/report_sw_tags.c
> @@ -30,7 +30,7 @@
>  #include "kasan.h"
>  #include "../slab.h"
>
> -void *kasan_find_first_bad_addr(void *addr, size_t size)
> +const void *kasan_find_first_bad_addr(const void *addr, size_t size)
>  {
>         u8 tag = get_tag(addr);
>         void *p = kasan_reset_tag(addr);
> diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
> index c8b86f3273b5..dccef3e9ad2d 100644
> --- a/mm/kasan/shadow.c
> +++ b/mm/kasan/shadow.c
> @@ -28,13 +28,13 @@
>
>  bool __kasan_check_read(const volatile void *p, unsigned int size)
>  {
> -       return kasan_check_range((unsigned long)p, size, false, _RET_IP_);
> +       return kasan_check_range((void *)p, size, false, _RET_IP_);
>  }
>  EXPORT_SYMBOL(__kasan_check_read);
>
>  bool __kasan_check_write(const volatile void *p, unsigned int size)
>  {
> -       return kasan_check_range((unsigned long)p, size, true, _RET_IP_);
> +       return kasan_check_range((void *)p, size, true, _RET_IP_);
>  }
>  EXPORT_SYMBOL(__kasan_check_write);
>
> @@ -50,7 +50,7 @@ EXPORT_SYMBOL(__kasan_check_write);
>  #undef memset
>  void *memset(void *addr, int c, size_t len)
>  {
> -       if (!kasan_check_range((unsigned long)addr, len, true, _RET_IP_))
> +       if (!kasan_check_range(addr, len, true, _RET_IP_))
>                 return NULL;
>
>         return __memset(addr, c, len);
> @@ -60,8 +60,8 @@ void *memset(void *addr, int c, size_t len)
>  #undef memmove
>  void *memmove(void *dest, const void *src, size_t len)
>  {
> -       if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) ||
> -           !kasan_check_range((unsigned long)dest, len, true, _RET_IP_))
> +       if (!kasan_check_range(src, len, false, _RET_IP_) ||
> +           !kasan_check_range(dest, len, true, _RET_IP_))
>                 return NULL;
>
>         return __memmove(dest, src, len);
> @@ -71,17 +71,17 @@ void *memmove(void *dest, const void *src, size_t len)
>  #undef memcpy
>  void *memcpy(void *dest, const void *src, size_t len)
>  {
> -       if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) ||
> -           !kasan_check_range((unsigned long)dest, len, true, _RET_IP_))
> +       if (!kasan_check_range(src, len, false, _RET_IP_) ||
> +           !kasan_check_range(dest, len, true, _RET_IP_))
>                 return NULL;
>
>         return __memcpy(dest, src, len);
>  }
>  #endif
>
> -void *__asan_memset(void *addr, int c, size_t len)
> +void *__asan_memset(void *addr, int c, kasan_size_t len)
>  {
> -       if (!kasan_check_range((unsigned long)addr, len, true, _RET_IP_))
> +       if (!kasan_check_range(addr, len, true, _RET_IP_))
>                 return NULL;
>
>         return __memset(addr, c, len);
> @@ -89,10 +89,10 @@ void *__asan_memset(void *addr, int c, size_t len)
>  EXPORT_SYMBOL(__asan_memset);
>
>  #ifdef __HAVE_ARCH_MEMMOVE
> -void *__asan_memmove(void *dest, const void *src, size_t len)
> +void *__asan_memmove(void *dest, const void *src, kasan_size_t len)
>  {
> -       if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) ||
> -           !kasan_check_range((unsigned long)dest, len, true, _RET_IP_))
> +       if (!kasan_check_range(src, len, false, _RET_IP_) ||
> +           !kasan_check_range(dest, len, true, _RET_IP_))
>                 return NULL;
>
>         return __memmove(dest, src, len);
> @@ -100,10 +100,10 @@ void *__asan_memmove(void *dest, const void *src, size_t len)
>  EXPORT_SYMBOL(__asan_memmove);
>  #endif
>
> -void *__asan_memcpy(void *dest, const void *src, size_t len)
> +void *__asan_memcpy(void *dest, const void *src, kasan_size_t len)
>  {
> -       if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) ||
> -           !kasan_check_range((unsigned long)dest, len, true, _RET_IP_))
> +       if (!kasan_check_range(src, len, false, _RET_IP_) ||
> +           !kasan_check_range(dest, len, true, _RET_IP_))
>                 return NULL;
>
>         return __memcpy(dest, src, len);
> @@ -111,13 +111,13 @@ void *__asan_memcpy(void *dest, const void *src, size_t len)
>  EXPORT_SYMBOL(__asan_memcpy);
>
>  #ifdef CONFIG_KASAN_SW_TAGS
> -void *__hwasan_memset(void *addr, int c, size_t len) __alias(__asan_memset);
> +void *__hwasan_memset(void *addr, int c, kasan_size_t len) __alias(__asan_memset);
>  EXPORT_SYMBOL(__hwasan_memset);
>  #ifdef __HAVE_ARCH_MEMMOVE
> -void *__hwasan_memmove(void *dest, const void *src, size_t len) __alias(__asan_memmove);
> +void *__hwasan_memmove(void *dest, const void *src, kasan_size_t len) __alias(__asan_memmove);
>  EXPORT_SYMBOL(__hwasan_memmove);
>  #endif
> -void *__hwasan_memcpy(void *dest, const void *src, size_t len) __alias(__asan_memcpy);
> +void *__hwasan_memcpy(void *dest, const void *src, kasan_size_t len) __alias(__asan_memcpy);
>  EXPORT_SYMBOL(__hwasan_memcpy);
>  #endif
>
> diff --git a/mm/kasan/sw_tags.c b/mm/kasan/sw_tags.c
> index 30da65fa02a1..ae8d26beb3a4 100644
> --- a/mm/kasan/sw_tags.c
> +++ b/mm/kasan/sw_tags.c
> @@ -70,8 +70,8 @@ u8 kasan_random_tag(void)
>         return (u8)(state % (KASAN_TAG_MAX + 1));
>  }
>
> -bool kasan_check_range(unsigned long addr, size_t size, bool write,
> -                               unsigned long ret_ip)
> +bool kasan_check_range(const void *addr, size_t size, bool write,
> +                       unsigned long ret_ip)
>  {
>         u8 tag;
>         u8 *shadow_first, *shadow_last, *shadow;
> @@ -133,12 +133,12 @@ bool kasan_byte_accessible(const void *addr)
>  }
>
>  #define DEFINE_HWASAN_LOAD_STORE(size)                                 \
> -       void __hwasan_load##size##_noabort(unsigned long addr)          \
> +       void __hwasan_load##size##_noabort(void *addr)                  \
>         {                                                               \
> -               kasan_check_range(addr, size, false, _RET_IP_); \
> +               kasan_check_range(addr, size, false, _RET_IP_);         \
>         }                                                               \
>         EXPORT_SYMBOL(__hwasan_load##size##_noabort);                   \
> -       void __hwasan_store##size##_noabort(unsigned long addr)         \
> +       void __hwasan_store##size##_noabort(void *addr)                 \
>         {                                                               \
>                 kasan_check_range(addr, size, true, _RET_IP_);          \
>         }                                                               \
> @@ -150,25 +150,25 @@ DEFINE_HWASAN_LOAD_STORE(4);
>  DEFINE_HWASAN_LOAD_STORE(8);
>  DEFINE_HWASAN_LOAD_STORE(16);
>
> -void __hwasan_loadN_noabort(unsigned long addr, unsigned long size)
> +void __hwasan_loadN_noabort(void *addr, kasan_size_t size)
>  {
>         kasan_check_range(addr, size, false, _RET_IP_);
>  }
>  EXPORT_SYMBOL(__hwasan_loadN_noabort);
>
> -void __hwasan_storeN_noabort(unsigned long addr, unsigned long size)
> +void __hwasan_storeN_noabort(void *addr, kasan_size_t size)
>  {
>         kasan_check_range(addr, size, true, _RET_IP_);
>  }
>  EXPORT_SYMBOL(__hwasan_storeN_noabort);
>
> -void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size)
> +void __hwasan_tag_memory(void *addr, u8 tag, kasan_size_t size)
>  {
> -       kasan_poison((void *)addr, size, tag, false);
> +       kasan_poison(addr, size, tag, false);
>  }
>  EXPORT_SYMBOL(__hwasan_tag_memory);
>
> -void kasan_tag_mismatch(unsigned long addr, unsigned long access_info,
> +void kasan_tag_mismatch(void *addr, unsigned long access_info,
>                         unsigned long ret_ip)
>  {
>         kasan_report(addr, 1 << (access_info & 0xf), access_info & 0x10,
> --
> 2.39.2
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 1/2] clk: imx8mp: fix sai4 clock
From: Marco Felsch @ 2023-04-21  9:16 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: Anson.Huang, abelvesa, festevam, krzysztof.kozlowski+dt,
	mturquette, robh+dt, shawnguo, linux-clk, linux-arm-kernel,
	devicetree, kernel
In-Reply-To: <7687837da16c41ffca3cda747483f2d1.sboyd@kernel.org>

Hi,

On 23-01-12, Stephen Boyd wrote:
> Quoting Marco Felsch (2022-12-19 09:10:57)
> > The reference manual don't mention a SAI4 hardware block. This would be
> > clock slice 78 which is skipped (TRM, page 237). Remove any reference to
> > this clock to align the driver with the reality.
> > 
> > Fixes: 9c140d992676 ("clk: imx: Add support for i.MX8MP clock driver")
> > Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
> > ---
> 
> Acked-by: Stephen Boyd <sboyd@kernel.org>

I noticed that this isn't part of v6.3. @Abel can you add your rb or
comments please?

Regards,
  Marco

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2] PCI: cadence: Fix Gen2 Link Retraining process
From: Lorenzo Pieralisi @ 2023-04-21  9:09 UTC (permalink / raw)
  To: tjoseph, robh, kw, bhelgaas, nadeem, Siddharth Vadapalli
  Cc: Lorenzo Pieralisi, linux-pci, linux-kernel, linux-arm-kernel,
	vigneshr, srk, nm
In-Reply-To: <20230315070800.1615527-1-s-vadapalli@ti.com>

On Wed, 15 Mar 2023 12:38:00 +0530, Siddharth Vadapalli wrote:
> The Link Retraining process is initiated to account for the Gen2 defect in
> the Cadence PCIe controller in J721E SoC. The errata corresponding to this
> is i2085, documented at:
> https://www.ti.com/lit/er/sprz455c/sprz455c.pdf
> 
> The existing workaround implemented for the errata waits for the Data Link
> initialization to complete and assumes that the link retraining process
> at the Physical Layer has completed. However, it is possible that the
> Physical Layer training might be ongoing as indicated by the
> PCI_EXP_LNKSTA_LT bit in the PCI_EXP_LNKSTA register.
> 
> [...]

Applied to controller/cadence, thanks!

[1/1] PCI: cadence: Fix Gen2 Link Retraining process
      https://git.kernel.org/pci/pci/c/eac223e85208

Thanks,
Lorenzo

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH] crypto: ixp4xx - silence uninitialized variable warning
From: Linus Walleij @ 2023-04-21  8:58 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: Arnd Bergmann, Linus Walleij, Imre Kaloz, Krzysztof Halasa,
	Herbert Xu, David S. Miller, linux-crypto, linux-arm-kernel,
	kernel-janitors
In-Reply-To: <7de7d932-d01b-4ada-ae07-827c32438e00@kili.mountain>

On Wed, Apr 19, 2023 at 4:26 PM Dan Carpenter <dan.carpenter@linaro.org> wrote:

> Smatch complains that "dma" is uninitialized if dma_pool_alloc() fails.
> This is true, but also harmless.  Anyway, move the assignment after the
> error checking to silence this warning.
>
> Fixes: 586d492f2856 ("crypto: ixp4xx - fix building wiht 64-bit dma_addr_t")
> Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>

Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2] PCI: cadence: Fix Gen2 Link Retraining process
From: Lorenzo Pieralisi @ 2023-04-21  8:57 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Siddharth Vadapalli, tjoseph, robh, kw, bhelgaas, nadeem,
	Raghavendra, Vignesh, linux-pci, linux-kernel, linux-arm-kernel,
	srk, nm
In-Reply-To: <20230330170218.GA3155390@bhelgaas>

On Thu, Mar 30, 2023 at 12:02:18PM -0500, Bjorn Helgaas wrote:
> On Thu, Mar 30, 2023 at 09:52:06AM +0530, Siddharth Vadapalli wrote:
> > Hello Bjorn,
> > 
> > On 29/03/23 22:38, Bjorn Helgaas wrote:
> > > On Wed, Mar 29, 2023 at 08:11:25PM +0530, Raghavendra, Vignesh wrote:
> > >> Hi Lorenzo, Bjorn,
> > >>
> > >> On 3/15/2023 12:38 PM, Siddharth Vadapalli wrote:
> > >>> The Link Retraining process is initiated to account for the Gen2 defect in
> > >>> the Cadence PCIe controller in J721E SoC. The errata corresponding to this
> > >>> is i2085, documented at:
> > >>> https://www.ti.com/lit/er/sprz455c/sprz455c.pdf
> > >>>
> > >>> The existing workaround implemented for the errata waits for the Data Link
> > >>> initialization to complete and assumes that the link retraining process
> > >>> at the Physical Layer has completed. However, it is possible that the
> > >>> Physical Layer training might be ongoing as indicated by the
> > >>> PCI_EXP_LNKSTA_LT bit in the PCI_EXP_LNKSTA register.
> > >>>
> > >>> Fix the existing workaround, to ensure that the Physical Layer training
> > >>> has also completed, in addition to the Data Link initialization.
> > >>>
> > >>> Fixes: 4740b969aaf5 ("PCI: cadence: Retrain Link to work around Gen2 training defect")
> > >>> Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
> > >>> Reviewed-by: Vignesh Raghavendra <vigneshr@ti.com>
> > >>> ---
> > >>> Changes from v1:
> > >>> 1. Collect Reviewed-by tag from Vignesh Raghavendra.
> > >>> 2. Rebase on next-20230315.
> > >>>
> > >>> v1:
> > >>> https://lore.kernel.org/r/20230102075656.260333-1-s-vadapalli@ti.com
> > >>>
> > >>>  .../controller/cadence/pcie-cadence-host.c    | 27 +++++++++++++++++++
> > >>>  1 file changed, 27 insertions(+)
> > >>
> > >> Wondering do one of you be pulling this patch in? This patch was never
> > >> picked for 6.3-rc1 merge cycle... Just want to make sure
> > >> pcie-cadence*.c and pci-j721e.c patches have a path to reach pci tree.
> > > 
> > > Yes, Lorenzo or Krzysztof will likely pick this up.  I think Lorenzo
> > > is out of the office this week.
> > > 
> > > Drive-by comment: the current patch doesn't seem to give any
> > > indication to the user when cdns_pcie_host_training_complete() times
> > > out.  Is that timeout potentially of interest to a user?  Should there
> > > be a log message there?
> > 
> > Thank you for reviewing the patch. The return value of -ETIMEDOUT from the
> > function cdns_pcie_host_training_complete() added by this patch will be handled
> > similar to the -ETIMEDOUT from the cdns_pcie_host_wait_for_link() function that
> > is already present.
> > 
> > If cdns_pcie_host_training_complete() returns -ETIMEDOUT, it is returned to
> > cdns_pcie_host_start_link() function which is called within
> > cdns_pcie_host_setup() function. In the cdns_pcie_host_setup() function, there
> > is already a dev_dbg() print for handling the case where
> > cdns_pcie_host_wait_for_link() times out. For this reason, I felt that for both
> > cases, the dev_dbg() print can be used to debug without the need for an extra
> > log message. Please let me know if that's fine.
> 
> Sounds good.
> 
> dev_dbg() wouldn't be the right thing if we *expect* the link to come
> up, but ISTR that maybe you can't detect device presence directly.  If
> that's the case, all you can do is try to bring the link up and assume
> the slot is empty if it doesn't come up.  If the usual reason for the
> timeout is that the slot is empty, dev_dbg() should be fine.
> 
> Another drive-by comment, no action needed, seems slightly strange to
> have two "start_link" functions called one after the other:
> 
>   cdns_pcie_host_setup
>     cdns_pcie_start_link
>     cdns_pcie_host_start_link
> 
> I assume both are for the same link, so it's weird to have two
> functions for it.

Side note: I would advise developers to reply to review comments
before nagging us to merge patches, it is not fine to leave
comments unanswered.

Yes, it is weird, the first call is for the platform driver specific
link HW setup and the second for the host *generic* link set-up and I
agree that's confusing, it is not related to this patch - that I am
merging - but should be addressed nonetheless.

Lorenzo

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH] perf cs-etm: Add support for coresight trace for any range of CPUs
From: Suzuki K Poulose @ 2023-04-21  8:55 UTC (permalink / raw)
  To: James Clark, Ganapatrao Kulkarni
  Cc: mathieu.poirier, acme, darren, scott, scclevenger, linux-kernel,
	coresight, linux-arm-kernel, mike.leach
In-Reply-To: <53132776-c998-a24f-a811-d8fb2e5e6535@arm.com>

On 20/04/2023 16:44, James Clark wrote:
> 
> 
> On 20/04/2023 14:03, Suzuki K Poulose wrote:
>> On 20/04/2023 13:37, Ganapatrao Kulkarni wrote:
>>>
>>>
>>> On 20-04-2023 06:00 pm, James Clark wrote:
>>>>
>>>>
>>>> On 20/04/2023 12:47, Ganapatrao Kulkarni wrote:
>>>>>
>>
>> ...
>>
>>>>> My patch is rebased on 6.3-RC7 codebase with Mike's 3 perf patches
>>>>> related to dynamic id [1] support(queued for 6.4).
>>>>>
>>>>> "perf report -D" works for me.
>>>>
>>>> I was referring to sparse CPU lists, which I think you mentioned above
>>>> doesn't work even with this patch.
>>>>
>>>>>
>>>>> [1] https://www.spinics.net/lists/linux-perf-users/msg27452.html
>>>>>
>>>>
>>>> It should be based on the next branch here:
>>>> git://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux.git
>>>
>>> OK.
>>
>> It need not be. Since this patch is purely perf tools patch and has
>> nothing to do with the kernel drivers, it should be beased on whatever
>> the tip of the perf tool tree is. Otherwise we risk rebasing to that
>> eventually.
>>
>> Cheers
>> Suzuki
>>
> 
> Good point, sorry for the confusion!
> 
> I wonder if we could have some kind of new staging branch that has both
> up to date perf and coresight changes at the same time? Either that
> would make things like this easier, or more complicated. I'm not sure.

I agree that it is complicated. :-(

We could do something about this if a situation arises in the future,
where the kernel and perf patches are out of sync w.r.t merging.
As, such the dependency on Anshuman's series is for ACPI support
which Ampere system needs. I would let this one pass, given the merge
window is too close.


Thanks
Suzuki


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH] firmware: arm_scmi: Fix incorrect alloc_workqueue() invocation
From: Cristian Marussi @ 2023-04-21  8:46 UTC (permalink / raw)
  To: Tejun Heo; +Cc: Sudeep Holla, linux-arm-kernel, linux-kernel, kernel-team
In-Reply-To: <ZEGTnajiQm7mkkZS@slm.duckdns.org>

On Thu, Apr 20, 2023 at 09:33:49AM -1000, Tejun Heo wrote:
> scmi_xfer_raw_worker_init() is specifying a flag, WQ_SYSFS, as @max_active.
> Fix it by or'ing WQ_SYSFS into @flags so that it actually enables sysfs
> interface and using 0 for @max_active for the default setting.
> 

Hi Tejun,

my bad I messed up the params in the call.

LGTM.

Thanks,
Cristian

> Signed-off-by: Tejun Heo <tj@kernel.org>
> ---
>  drivers/firmware/arm_scmi/raw_mode.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> --- a/drivers/firmware/arm_scmi/raw_mode.c
> +++ b/drivers/firmware/arm_scmi/raw_mode.c
> @@ -1066,7 +1066,7 @@ static int scmi_xfer_raw_worker_init(str
>  
>  	raw->wait_wq = alloc_workqueue("scmi-raw-wait-wq-%d",
>  				       WQ_UNBOUND | WQ_FREEZABLE |
> -				       WQ_HIGHPRI, WQ_SYSFS, raw->id);
> +				       WQ_HIGHPRI | WQ_SYSFS, 0, raw->id);
>  	if (!raw->wait_wq)
>  		return -ENOMEM;
>  

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH V2 3/3] ARM: dts: BCM5301X: Specify WAN port MAC address for Luxul XWR-3150
From: Rafał Miłecki @ 2023-04-21  8:43 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Srinivas Kandagatla
  Cc: Florian Fainelli, Hauke Mehrtens, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, linux-kernel, Rafał Miłecki
In-Reply-To: <20230421084312.27932-1-zajec5@gmail.com>

From: Rafał Miłecki <rafal@milecki.pl>

It needs to be calculated based on the base Ethernet interface one.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
This PATCH is a proof of concept that can go separately through the ARM
DT tree. I'd actually suggest that. There are more .dts files I'll want
to update.
Srini: can you just take the first 2 patches from this series?
---
 arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
index 60a2c441d5bd..2dd05f4dce92 100644
--- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
@@ -27,6 +27,7 @@ nvram@1eff0000 {
 		reg = <0x1eff0000 0x10000>;
 
 		et0macaddr: et0macaddr {
+			#nvmem-cell-cells = <1>;
 		};
 	};
 
@@ -76,7 +77,7 @@ button-restart {
 };
 
 &gmac0 {
-	nvmem-cells = <&et0macaddr>;
+	nvmem-cells = <&et0macaddr 0>;
 	nvmem-cell-names = "mac-address";
 };
 
@@ -119,6 +120,8 @@ port@3 {
 		port@4 {
 			reg = <4>;
 			label = "wan";
+			nvmem-cells = <&et0macaddr 5>;
+			nvmem-cell-names = "mac-address";
 		};
 
 		port@5 {
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH V2 2/3] nvmem: brcm_nvram: add .read_post_process() for MACs
From: Rafał Miłecki @ 2023-04-21  8:43 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Srinivas Kandagatla
  Cc: Florian Fainelli, Hauke Mehrtens, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, linux-kernel, Rafał Miłecki
In-Reply-To: <20230421084312.27932-1-zajec5@gmail.com>

From: Rafał Miłecki <rafal@milecki.pl>

1. Parse ASCII MAC format into byte based
2. Calculate relative addresses based on index argument

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
 drivers/nvmem/Kconfig      |  1 +
 drivers/nvmem/brcm_nvram.c | 28 ++++++++++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index b291b27048c7..688b70ba4826 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -55,6 +55,7 @@ config NVMEM_BRCM_NVRAM
 	tristate "Broadcom's NVRAM support"
 	depends on ARCH_BCM_5301X || COMPILE_TEST
 	depends on HAS_IOMEM
+	select GENERIC_NET_UTILS
 	help
 	  This driver provides support for Broadcom's NVRAM that can be accessed
 	  using I/O mapping.
diff --git a/drivers/nvmem/brcm_nvram.c b/drivers/nvmem/brcm_nvram.c
index 39aa27942f28..4567c597c87f 100644
--- a/drivers/nvmem/brcm_nvram.c
+++ b/drivers/nvmem/brcm_nvram.c
@@ -4,6 +4,8 @@
  */
 
 #include <linux/bcm47xx_nvram.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
 #include <linux/io.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
@@ -42,6 +44,25 @@ static int brcm_nvram_read(void *context, unsigned int offset, void *val,
 	return 0;
 }
 
+static int brcm_nvram_read_post_process_macaddr(void *context, const char *id, int index,
+						unsigned int offset, void *buf, size_t bytes)
+{
+	u8 mac[ETH_ALEN];
+
+	if (bytes != 3 * ETH_ALEN - 1)
+		return -EINVAL;
+
+	if (!mac_pton(buf, mac))
+		return -EINVAL;
+
+	if (index)
+		eth_addr_add(mac, index);
+
+	ether_addr_copy(buf, mac);
+
+	return 0;
+}
+
 static int brcm_nvram_add_cells(struct brcm_nvram *priv, uint8_t *data,
 				size_t len)
 {
@@ -75,6 +96,13 @@ static int brcm_nvram_add_cells(struct brcm_nvram *priv, uint8_t *data,
 		priv->cells[idx].offset = value - (char *)data;
 		priv->cells[idx].bytes = strlen(value);
 		priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
+		if (!strcmp(var, "et0macaddr") ||
+		    !strcmp(var, "et1macaddr") ||
+		    !strcmp(var, "et2macaddr")) {
+			priv->cells[idx].raw_len = strlen(value);
+			priv->cells[idx].bytes = ETH_ALEN;
+			priv->cells[idx].read_post_process = brcm_nvram_read_post_process_macaddr;
+		}
 	}
 
 	return 0;
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH V2 1/3] dt-bindings: nvmem: brcm,nvram: add #nvmem-cell-cells for MACs
From: Rafał Miłecki @ 2023-04-21  8:43 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Srinivas Kandagatla
  Cc: Florian Fainelli, Hauke Mehrtens, devicetree, linux-arm-kernel,
	bcm-kernel-feedback-list, linux-kernel, Rafał Miłecki,
	Rob Herring

From: Rafał Miłecki <rafal@milecki.pl>

Broadcom's NVRAM contains MACs for Ethernet interfaces. Those MACs are
usually base addresses that are also used for calculating other MACs.

For example if a router vendor decided to use gmac0 it most likely
programmed NVRAM of each unit with a proper "et0macaddr" value. That is
a base.

Ethernet interface is usually connected to switch port. Switch usually
includes few LAN ports and a WAN port. MAC of WAN port gets calculated
as relative address to the interface one. Offset varies depending on
device model.

Wireless MACs may also need to be calculated using relevant offsets.

To support all those scenarios let MAC NVMEM cells be referenced with an
index specifying MAC offset. Disallow additionalProperties while at it.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Rob Herring <robh@kernel.org>
---
V2: Add additionalProperties: false
---
 .../devicetree/bindings/nvmem/brcm,nvram.yaml     | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml b/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
index 36def7128fca..13412af7f046 100644
--- a/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
+++ b/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
@@ -36,14 +36,29 @@ properties:
   et0macaddr:
     type: object
     description: First Ethernet interface's MAC address
+    properties:
+      "#nvmem-cell-cells":
+        description: The first argument is a MAC address offset.
+        const: 1
+    additionalProperties: false
 
   et1macaddr:
     type: object
     description: Second Ethernet interface's MAC address
+    properties:
+      "#nvmem-cell-cells":
+        description: The first argument is a MAC address offset.
+        const: 1
+    additionalProperties: false
 
   et2macaddr:
     type: object
     description: Third Ethernet interface's MAC address
+    properties:
+      "#nvmem-cell-cells":
+        description: The first argument is a MAC address offset.
+        const: 1
+    additionalProperties: false
 
 unevaluatedProperties: false
 
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [RFC v1 1/2] scmi: Introduce pinctrl SCMI protocol driver
From: Oleksii Moisieiev @ 2023-04-21  8:40 UTC (permalink / raw)
  To: Peng Fan, Cristian Marussi
  Cc: sudeep.holla@arm.com, Linus Walleij, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org,
	michal.simek@amd.com, vincent.guittot@linaro.org,
	souvik.chakravarty@arm.com
In-Reply-To: <6dc456ff-7fc6-3b73-3727-dd048e9a9629@oss.nxp.com>

Hi Peng Fan,

On 17.04.23 05:55, Peng Fan wrote:
>
>
> On 4/13/2023 6:04 AM, Cristian Marussi wrote:
>> On Fri, Apr 07, 2023 at 10:18:27AM +0000, Oleksii Moisieiev wrote:
>>> Implementation of the SCMI client driver, which implements
>>> PINCTRL_PROTOCOL. This protocol has ID 19 and is described
>>> in the latest DEN0056 document.
>>
>> Hi,
>>
>>> This protocol is part of the feature that was designed to
>>> separate the pinctrl subsystem from the SCP firmware.
>>> The idea is to separate communication of the pin control
>>> subsystem with the hardware to SCP firmware
>>> (or a similar system, such as ATF), which provides an interface
>>> to give the OS ability to control the hardware through SCMI protocol.
>>> This is a generic driver that implements SCMI protocol,
>>> independent of the platform type.
>>>
>>> DEN0056 document:
>>> https://urldefense.com/v3/__https://developer.arm.com/documentation/den0056/latest__;!!GF_29dbcQIUBPA!y2hR3PEGGxiPjVeXBcgGyV03DPDhzgUKR0uHvsTpiafKgBar8Egc6oOOs-IkFIquhSf-qBzltqEMyzRZHq8eC4g$ 
>>> [developer[.]arm[.]com]
>>>
>>
>> No need to specify all of this in the commit message, just a note that
>> you are adding a new SCMIv3.2 Pincontrol protocol, highlighting anything
>> that has been left out in this patch (if any) will be enough.
>
> Is it possible to extend the spec to support multilple uint32_t for PIN
> CONFIG SET?
>
> With only one uint32_t could not satisfy i.MX requirement.
>
> Thanks,
> Peng.
>
IIUC you are expecting to have an ability to set some kind of array of 
uint32_t config values to some specific ConfigType?

I'm not sure if it's supported by pintctrl subsystem right now. I was 
unable to find an example in the existing device-tree pinctrl bindings. 
This makes me think that this kind of binding is OEM specific.

Maybe it can be implemented by adding new IDs to OEM specific range 
(192-255) which is reserved for OEM specific units (See Table 23 of 
DEN0056E).

Best regards,

Oleksii


>> You can look at the very first commit logs of existing protos as an
>> example like: drivers/firmware/arm_scmi/powercap.c
>>
>> Some more comments down below, I'll mostly skip anything related to the
>> SCMI API change I mentioned before...
>>
>> I'll also wont comment on more trivial stuff related to style, BUT there
>> are lots of them: you should run
>>
>> ./scripts/checkpatch.pl --strict <your-git-format-patch-file>
>>
>> for each patch in the series. (and fix accordingly..spacing, 
>> brackets...etc)
>>
>>> Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@epam.com>
>>> ---
>>>   MAINTAINERS                         |   6 +
>>>   drivers/firmware/arm_scmi/Makefile  |   2 +-
>>>   drivers/firmware/arm_scmi/common.h  |   1 +
>>>   drivers/firmware/arm_scmi/driver.c  |   3 +
>>>   drivers/firmware/arm_scmi/pinctrl.c | 905 
>>> ++++++++++++++++++++++++++++
>>>   drivers/pinctrl/Kconfig             |   9 +
>>>   include/linux/scmi_protocol.h       |  58 +-
>>>   7 files changed, 982 insertions(+), 2 deletions(-)
>>>   create mode 100644 drivers/firmware/arm_scmi/pinctrl.c
>>>
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index 281de213ef47..abc543fd7544 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -16961,6 +16961,12 @@ F:    drivers/reset/reset-scmi.c
>>>   F:    include/linux/sc[mp]i_protocol.h
>>>   F:    include/trace/events/scmi.h
>>>   +PINCTRL DRIVER FOR SYSTEM CONTROL & POWER/MANAGEMENT INTERFACE 
>>> (SCPI/SCMI)
>>> +M:    Oleksii Moisieiev <oleksii_moisieiev@epam.com>
>>> +L:    linux-arm-kernel@lists.infradead.org
>>> +S:    Maintained
>>> +F:    drivers/firmware/arm_scmi/pinctrl.c
>>> +
>>>   SYSTEM RESET/SHUTDOWN DRIVERS
>>>   M:    Sebastian Reichel <sre@kernel.org>
>>>   L:    linux-pm@vger.kernel.org
>>> diff --git a/drivers/firmware/arm_scmi/Makefile 
>>> b/drivers/firmware/arm_scmi/Makefile
>>> index bc0d54f8e861..5cec357fbfa8 100644
>>> --- a/drivers/firmware/arm_scmi/Makefile
>>> +++ b/drivers/firmware/arm_scmi/Makefile
>>> @@ -4,7 +4,7 @@ scmi-driver-y = driver.o notify.o
>>>   scmi-transport-y = shmem.o
>>>   scmi-transport-$(CONFIG_MAILBOX) += mailbox.o
>>>   scmi-transport-$(CONFIG_HAVE_ARM_SMCCC_DISCOVERY) += smc.o
>>> -scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o 
>>> system.o
>>> +scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o 
>>> system.o pinctrl.o
>>>   scmi-module-objs := $(scmi-bus-y) $(scmi-driver-y) 
>>> $(scmi-protocols-y) \
>>>               $(scmi-transport-y)
>>>   obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-module.o
>>> diff --git a/drivers/firmware/arm_scmi/common.h 
>>> b/drivers/firmware/arm_scmi/common.h
>>> index 65063fa948d4..8bbb404abe8d 100644
>>> --- a/drivers/firmware/arm_scmi/common.h
>>> +++ b/drivers/firmware/arm_scmi/common.h
>>> @@ -170,6 +170,7 @@ DECLARE_SCMI_REGISTER_UNREGISTER(power);
>>>   DECLARE_SCMI_REGISTER_UNREGISTER(reset);
>>>   DECLARE_SCMI_REGISTER_UNREGISTER(sensors);
>>>   DECLARE_SCMI_REGISTER_UNREGISTER(system);
>>> +DECLARE_SCMI_REGISTER_UNREGISTER(pinctrl);
>>>     #define DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(id, name) \
>>>   int __init scmi_##name##_register(void) \
>>> diff --git a/drivers/firmware/arm_scmi/driver.c 
>>> b/drivers/firmware/arm_scmi/driver.c
>>> index 3dfd8b6a0ebf..fb9525fb3c24 100644
>>> --- a/drivers/firmware/arm_scmi/driver.c
>>> +++ b/drivers/firmware/arm_scmi/driver.c
>>> @@ -743,6 +743,7 @@ static struct scmi_prot_devnames devnames[] = {
>>>       { SCMI_PROTOCOL_CLOCK,  { "clocks" },},
>>>       { SCMI_PROTOCOL_SENSOR, { "hwmon" },},
>>>       { SCMI_PROTOCOL_RESET,  { "reset" },},
>>> +    { SCMI_PROTOCOL_PINCTRL,  { "pinctrl" },},
>>>   };
>>>     static inline void
>>> @@ -947,6 +948,7 @@ static int __init scmi_driver_init(void)
>>>       scmi_reset_register();
>>>       scmi_sensors_register();
>>>       scmi_system_register();
>>> +    scmi_pinctrl_register();
>>>         return platform_driver_register(&scmi_driver);
>>>   }
>>> @@ -962,6 +964,7 @@ static void __exit scmi_driver_exit(void)
>>>       scmi_reset_unregister();
>>>       scmi_sensors_unregister();
>>>       scmi_system_unregister();
>>> +    scmi_pinctrl_unregister();
>>>         platform_driver_unregister(&scmi_driver);
>>>   }
>>> diff --git a/drivers/firmware/arm_scmi/pinctrl.c 
>>> b/drivers/firmware/arm_scmi/pinctrl.c
>>> new file mode 100644
>>> index 000000000000..037270d7f39b
>>> --- /dev/null
>>> +++ b/drivers/firmware/arm_scmi/pinctrl.c
>>> @@ -0,0 +1,905 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * System Control and Management Interface (SCMI) Pinctrl Protocol
>>> + *
>>> + * Copyright (C) 2021 EPAM.
>>
>> nitpick: update (C) years
>>
>>> + */
>>> +
>>> +#define pr_fmt(fmt) "SCMI Notifications PINCTRL - " fmt
>>> +
>>
>> This is not needed, no notifs in this proto.
>>
>>> +#include <linux/scmi_protocol.h>
>>> +#include <linux/slab.h>
>>> +
>>> +#include "common.h"
>>> +#include "notify.h"
>>
>> Notifs not needed, and in the new API world you'll just need a:
>>
>>   #include "protocols.h"
>>
>>> +
>>> +#define SET_TYPE(x) ((x) & 0x3)
>>> +
>>
>> Even if trivial better to use std bitfield.h macros like
>> FIELD_GET() BIT() ... etc
>>
>>> +enum scmi_pinctrl_protocol_cmd {
>>> +    PINCTRL_ATTRIBUTES = 0x3,
>>> +    PINCTRL_LIST_ASSOCIATIONS = 0x4,
>>> +    PINCTRL_CONFIG_GET = 0x5,
>>> +    PINCTRL_CONFIG_SET = 0x6,
>>> +    PINCTRL_FUNCTION_SELECT = 0x7,
>>> +    PINCTRL_REQUEST = 0x8,
>>> +    PINCTRL_RELEASE = 0x9,
>>> +    PINCTRL_NAME_GET = 0xa,
>>> +    PINCTRL_SET_PERMISSIONS = 0xb
>>> +};
>>> +
>>> +enum scmi_pinctrl_selector_type {
>>> +    PIN_TYPE = 0,
>>> +    GROUP_TYPE,
>>> +    FUNCTION_TYPE
>>> +};
>>> +
>>> +struct scmi_group_info {
>>> +    bool present;
>>> +    char *name;
>>> +    unsigned int *group_pins;
>>> +    unsigned int nr_pins;
>>> +};
>>> +
>>> +struct scmi_function_info {
>>> +    bool present;
>>> +    char *name;
>>> +    unsigned int *groups;
>>> +    unsigned int nr_groups;
>>> +};
>>> +
>>> +struct scmi_pin_info {
>>> +    bool present;
>>> +    char *name;
>>> +};
>>> +
>>> +struct scmi_pinctrl_info {
>>> +    u32 version;
>>> +    u16 nr_groups;
>>> +    u16 nr_functions;
>>> +    u16 nr_pins;
>>
>> Since these vars are not related to stricly spaced message fields 
>> (even though
>> derived from such messages) do not use sized types, you can just 
>> stick with
>> unsigned int. (it is also better not to mix sized and unsized types 
>> in the same
>> struct). This also could come handy if these will be exposed to the user
>> in scmi_protocol.h in the future (more on this down below)
>>
>>> +    struct scmi_group_info *groups;
>>> +    struct scmi_function_info *functions;
>>> +    struct scmi_pin_info *pins;
>>> +};
>>> +
>>> +struct scmi_conf_tx {
>>> +    __le32 identifier;
>>> +#define SET_TYPE_BITS(attr, x) (((attr) & 0xFFFFFCFF) | (x & 0x3) 
>>> << 8)
>>> +#define SET_CONFIG(attr, x) (((attr) & 0xFF) | (x & 0xFF))
>>
>> Use bitfield.h like FIELD_SET / GENMASK etc
>>
>>> +    __le32 attributes;
>>> +};
>>> +
>>> +static int scmi_pinctrl_attributes_get(const struct scmi_handle 
>>> *handle,
>>> +                       struct scmi_pinctrl_info *pi)
>>> +{
>>> +    int ret;
>>> +    struct scmi_xfer *t;
>>> +    struct scmi_msg_pinctrl_protocol_attributes {
>>> +#define GROUPS_NR(x) ((x) >> 16)
>>> +#define PINS_NR(x) ((x) & 0xffff)
>>> +        __le32 attributes_low;
>>> +#define FUNCTIONS_NR(x) ((x) & 0xffff)
>>> +        __le32 attributes_high;
>>> +    } *attr;
>>
>> For consistency with the rest of the stack (mostly :D), please move 
>> this struct
>> definition and related macros outside in the global scope right after 
>> command
>> enum. (and use bitfield macros ...)
>>
>>> +
>>> +    if (!pi)
>>> +        return -EINVAL;
>>> +
>>> +    ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
>>> +                 SCMI_PROTOCOL_PINCTRL, 0, sizeof(*attr), &t);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    attr = t->rx.buf;
>>> +
>>> +    ret = scmi_do_xfer(handle, t);
>>> +    if (!ret) {
>>> +        pi->nr_functions =
>>> + le16_to_cpu(FUNCTIONS_NR(attr->attributes_high));
>>> +        pi->nr_groups = le16_to_cpu(GROUPS_NR(attr->attributes_low));
>>> +        pi->nr_pins = le16_to_cpu(PINS_NR(attr->attributes_low));
>>> +    }
>>> +
>>> +    scmi_xfer_put(handle, t);
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_get_groups_count(const struct scmi_handle 
>>> *handle)
>>> +{
>>> +    struct scmi_pinctrl_info *pi;
>>> +
>>> +    if (!handle || !handle->pinctrl_priv)
>>> +        return -ENODEV;
>>> +
>>> +    pi = handle->pinctrl_priv;
>>> +
>>> +    return pi->nr_groups;
>>> +}
>>> +
>>> +static int scmi_pinctrl_get_pins_count(const struct scmi_handle 
>>> *handle)
>>> +{
>>> +    struct scmi_pinctrl_info *pi;
>>> +
>>> +    if (!handle || !handle->pinctrl_priv)
>>> +        return -ENODEV;
>>> +
>>> +    pi = handle->pinctrl_priv;
>>> +
>>> +    return pi->nr_pins;
>>> +}
>>> +
>>> +static int scmi_pinctrl_get_functions_count(const struct 
>>> scmi_handle *handle)
>>> +{
>>> +    struct scmi_pinctrl_info *pi;
>>> +
>>> +    if (!handle || !handle->pinctrl_priv)
>>> +        return -ENODEV;
>>> +
>>> +    pi = handle->pinctrl_priv;
>>> +
>>> +    return pi->nr_functions;
>>> +}
>>> +
>>> +static int scmi_pinctrl_validate_id(const struct scmi_handle *handle,
>>> +                    u32 identifier,
>>> +                    enum scmi_pinctrl_selector_type type)
>>> +{
>>> +    struct scmi_pinctrl_info *pi;
>>> +
>>> +    if (!handle || !handle->pinctrl_priv)
>>> +        return -ENODEV;
>>> +
>>> +    switch (type) {
>>> +    case PIN_TYPE:
>>> +        pi = handle->pinctrl_priv;
>>> +
>>> +        return (identifier < pi->nr_pins) ? 0 : -EINVAL;
>>> +    case GROUP_TYPE:
>>> +        return (identifier <
>>> +            scmi_pinctrl_get_groups_count(handle)) ?
>>> +            0 : -EINVAL;
>>> +    case FUNCTION_TYPE:
>>> +        return (identifier <
>>> +            scmi_pinctrl_get_functions_count(handle)) ?
>>> +            0 : -EINVAL;
>>> +    default:
>>> +        return -EINVAL;
>>> +    }
>>
>> Here I would just pick the right value to compare, break and then
>> compare and exit, something aroundf the lines of:
>>
>>     case PIN_TYPE:
>>         ...
>>             val = pi->nr_pins;
>>         break;
>>         ...
>>     case GROUP_TYPE:
>>         val = scmi_pinctrl_get_groups_count());
>>         break;
>>
>>     ....
>>     ....
>>         default:
>>         return -EINVAL;
>>     }
>>
>>     if (identifier >= val)
>>         return -EINVAL;
>>
>>     return 0;
>> }
>>
>> ... it's easier to read. What do you think ?
>>
>>
>>> +}
>>> +
>>> +static int scmi_pinctrl_get_name(const struct scmi_handle *handle,
>>> +                 u32 identifier,
>>> +                 enum scmi_pinctrl_selector_type type,
>>> +                 char **name)
>>> +{
>>
>> As said, there is common helper for this, but it will need some small
>> adaptation in the SCMI core to work here so keep it as it is, and 
>> I'll take
>> care of this later, if it sounds fine for you.
>>
>>> +    struct scmi_xfer *t;
>>> +    int ret = 0;
>>> +    struct scmi_name_tx {
>>> +        __le32 identifier;
>>> +        __le32 flags;
>>> +    } *tx;
>>> +    struct scmi_name_rx {
>>> +        __le32 flags;
>>> +        u8 name[64];
>>> +    } *rx;
>>> +
>>> +    if (!handle || !name)
>>> +        return -EINVAL;
>>> +
>>> +    ret = scmi_pinctrl_validate_id(handle, identifier, type);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    ret = scmi_xfer_get_init(handle, PINCTRL_NAME_GET,
>>> +                 SCMI_PROTOCOL_PINCTRL,
>>> +                 sizeof(*tx), sizeof(*rx), &t);
>>> +
>>> +    tx = t->tx.buf;
>>> +    rx = t->rx.buf;
>>> +    tx->identifier = identifier;
>>> +    tx->flags = SET_TYPE(cpu_to_le32(type));
>>> +
>>> +    ret = scmi_do_xfer(handle, t);
>>> +    if (ret)
>>> +        goto out;
>>> +
>>> +    if (rx->flags) {
>>> +        ret = -EINVAL;
>>> +        goto out;
>>> +    }
>>> +
>>> +    *name = kasprintf(GFP_KERNEL, "%s", rx->name);
>>> +    if (!*name)
>>> +        ret = -ENOMEM;
>>> + out:
>>> +    scmi_xfer_put(handle, t);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_attributes(const struct scmi_handle *handle,
>>> +                   enum scmi_pinctrl_selector_type type,
>>> +                   u32 selector, char **name,
>>> +                   unsigned int *n_elems)
>>> +{
>>> +    int ret = 0;
>>> +    struct scmi_xfer *t;
>>> +    struct scmi_pinctrl_attributes_tx {
>>> +        __le32 identifier;
>>> +        __le32 flags;
>>> +    } *tx;
>>> +    struct scmi_pinctrl_attributes_rx {
>>> +#define EXT_NAME_FLAG(x) ((x) & BIT(31))
>>> +#define NUM_ELEMS(x) ((x) & 0xffff)
>>> +        __le32 attributes;
>>> +        u8 name[16];
>>> +    } *rx;
>>
>> Ditto. Move these defs outside, bitfield.h for macros and try to use the
>> same naming style for message structs as in other protos, i.e.
>>
>>     for commands:     struct scmi_msg_pinctrl_attributes
>>     for replies:     struct scmi_resp_pinctrl_attributes
>>
>> (or some variations around that...
>>     scmi_msg_cmd_*  scmi_msg_resp_*
>>
>>    we have not been fully consistent really, so I dont want to be
>>    pedantic here, but we never used tx/rx in message context since it is
>>    already (mis)-used in SCMI channel context...)
>>
>>> +
>>> +    if (!handle || !name)
>>> +        return -EINVAL;
>>> +
>>> +    ret = scmi_pinctrl_validate_id(handle, selector, type);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    ret = scmi_xfer_get_init(handle, PINCTRL_ATTRIBUTES,
>>> +             SCMI_PROTOCOL_PINCTRL, sizeof(*tx), sizeof(*rx), &t);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    tx = t->tx.buf;
>>> +    rx = t->rx.buf;
>>> +    tx->identifier = selector;
>>> +    tx->flags = SET_TYPE(cpu_to_le32(type));
>>> +
>>> +    ret = scmi_do_xfer(handle, t);
>>> +    if (ret)
>>> +        goto out;
>>> +
>>> +    *n_elems = NUM_ELEMS(rx->attributes);
>>> +
>>> +    if (!EXT_NAME_FLAG(rx->attributes)) {
>>> +        *name = kasprintf(GFP_KERNEL, "%s", rx->name);
>>> +        if (!*name)
>>> +            ret = -ENOMEM;
>>> +    } else
>>> +        ret = scmi_pinctrl_get_name(handle, selector, type, name);
>>> + out:
>>> +    scmi_xfer_put(handle, t);
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_list_associations(const struct scmi_handle 
>>> *handle,
>>> +                      u32 selector,
>>> +                      enum scmi_pinctrl_selector_type type,
>>> +                      uint16_t size, unsigned int *array)
>>> +{
>>
>> This is the other functionalities you could implement straight away 
>> using
>> ph->hops helpers (iterators) but just leave it this way, and I'll 
>> port it later
>> (once we retested all of this as working with the new API but without 
>> any
>> ph->hops usage..I think it is safer to change one bit at time... :P)
>>
>>> +    struct scmi_xfer *t;
>>> +    struct scmi_pinctrl_list_assoc_tx {
>>> +        __le32 identifier;
>>> +        __le32 flags;
>>> +        __le32 index;
>>> +    } *tx;
>>> +    struct scmi_pinctrl_list_assoc_rx {
>>> +#define RETURNED(x) ((x) & 0xFFF)
>>> +#define REMAINING(x) ((x) >> 16)
>>> +        __le32 flags;
>>> +        __le16 array[];
>>> +    } *rx;
>>
>> Ditto, about struct naming and macros.
>>
>>> +    u16 tot_num_ret = 0, loop_num_ret;
>>> +    u16 remaining_num_ret;
>>> +    int ret, loop;
>>> +
>>> +    if (!handle || !array || !size)
>>> +        return -EINVAL;
>>> +
>>> +    if (type == PIN_TYPE)
>>> +        return -EINVAL;
>>> +
>>> +    ret = scmi_pinctrl_validate_id(handle, selector, type);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    ret = scmi_xfer_get_init(handle, PINCTRL_LIST_ASSOCIATIONS,
>>> +                 SCMI_PROTOCOL_PINCTRL, sizeof(*tx),
>>> +                 0, &t);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    tx = t->tx.buf;
>>> +    rx = t->rx.buf;
>>> +
>>> +    do {
>>> +        tx->identifier = cpu_to_le32(selector);
>>> +        tx->flags = SET_TYPE(cpu_to_le32(type));
>>> +        tx->index = cpu_to_le32(tot_num_ret);
>>> +
>>> +        ret = scmi_do_xfer(handle, t);
>>> +        if (ret)
>>> +            break;
>>> +
>>> +        loop_num_ret = le32_to_cpu(RETURNED(rx->flags));
>>> +        remaining_num_ret = le32_to_cpu(REMAINING(rx->flags));
>>> +
>>> +        for (loop = 0; loop < loop_num_ret; loop++) {
>>> +            if (tot_num_ret + loop >= size) {
>>> +                ret = -EMSGSIZE;
>>> +                goto out;
>>> +            }
>>> +
>>> +            array[tot_num_ret + loop] =
>>> +                le16_to_cpu(rx->array[loop]);
>>> +        }
>>> +
>>> +        tot_num_ret += loop_num_ret;
>>> +
>>> +        scmi_reset_rx_to_maxsz(handle, t);
>>> +    } while (remaining_num_ret > 0);
>>> +out:
>>> +    scmi_xfer_put(handle, t);
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_request_config(const struct scmi_handle 
>>> *handle,
>>> +                       u32 selector,
>>> +                       enum scmi_pinctrl_selector_type type,
>>> +                       u32 *config)
>>> +{
>>> +    struct scmi_xfer *t;
>>> +    struct scmi_conf_tx *tx;
>>> +    __le32 *packed_config;
>>> +    u32 attributes = 0;
>>> +    int ret;
>>> +
>>> +    if (!handle || !config || type == FUNCTION_TYPE)
>>> +        return -EINVAL;
>>> +
>>> +    ret = scmi_pinctrl_validate_id(handle, selector, type);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    ret = scmi_xfer_get_init(handle, PINCTRL_CONFIG_GET,
>>> +                 SCMI_PROTOCOL_PINCTRL,
>>> +                 sizeof(*tx), sizeof(*packed_config), &t);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    tx = t->tx.buf;
>>> +    packed_config = t->rx.buf;
>>> +    tx->identifier = cpu_to_le32(selector);
>>> +    attributes = SET_TYPE_BITS(attributes, type);
>>> +    attributes = SET_CONFIG(attributes, *config);
>>> +
>>> +    tx->attributes = cpu_to_le32(attributes);
>>> +
>>> +    ret = scmi_do_xfer(handle, t);
>>> +
>>> +    if (!ret)
>>> +        *config = le32_to_cpu(*packed_config);
>>> +
>>> +    scmi_xfer_put(handle, t);
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_get_config(const struct scmi_handle 
>>> *handle, u32 pin,
>>> +                   u32 *config)
>>> +{
>>> +    return scmi_pinctrl_request_config(handle, pin, PIN_TYPE, config);
>>> +}
>>> +
>>> +static int scmi_pinctrl_apply_config(const struct scmi_handle *handle,
>>> +                     u32 selector,
>>> +                     enum scmi_pinctrl_selector_type type,
>>> +                     u32 config)
>>> +{
>>> +    struct scmi_xfer *t;
>>> +    struct scmi_conf_tx *tx;
>>> +    u32 attributes = 0;
>>> +    int ret;
>>> +
>>> +    if (!handle || type == FUNCTION_TYPE)
>>> +        return -EINVAL;
>>> +
>>> +    ret = scmi_pinctrl_validate_id(handle, selector, type);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    ret = scmi_xfer_get_init(handle, PINCTRL_CONFIG_SET,
>>> +                 SCMI_PROTOCOL_PINCTRL,
>>> +                 sizeof(*tx), 0, &t);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    tx = t->tx.buf;
>>> +    tx->identifier = cpu_to_le32(selector);
>>> +    attributes = SET_TYPE_BITS(attributes, type);
>>> +    attributes = SET_CONFIG(attributes, config);
>>> +    tx->attributes = cpu_to_le32(attributes);
>>> +
>>> +    ret = scmi_do_xfer(handle, t);
>>> +
>>> +    scmi_xfer_put(handle, t);
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_set_config(const struct scmi_handle 
>>> *handle, u32 pin,
>>> +                   u32 config)
>>> +{
>>> +    return scmi_pinctrl_apply_config(handle, pin, PIN_TYPE, config);
>>> +}
>>> +
>>> +static int scmi_pinctrl_get_config_group(const struct scmi_handle 
>>> *handle,
>>> +                     u32 group, u32 *config)
>>> +{
>>> +    return scmi_pinctrl_request_config(handle, group, GROUP_TYPE, 
>>> config);
>>> +}
>>> +
>>> +static int scmi_pinctrl_set_config_group(const struct scmi_handle 
>>> *handle,
>>> +                     u32 group, u32 config)
>>> +{
>>> +    return scmi_pinctrl_apply_config(handle, group, GROUP_TYPE, 
>>> config);
>>> +}
>>> +
>>> +static int scmi_pinctrl_function_select(const struct scmi_handle 
>>> *handle,
>>> +                    u32 identifier,
>>> +                    enum scmi_pinctrl_selector_type type,
>>> +                    u32 function_id)
>>> +{
>>> +    struct scmi_xfer *t;
>>> +    struct scmi_func_set_tx {
>>> +        __le32 identifier;
>>> +        __le32 function_id;
>>> +        __le32 flags;
>>> +    } *tx;
>>
>> Ditto.
>>
>>> +    int ret;
>>> +
>>> +    if (!handle || type == FUNCTION_TYPE)
>>> +        return -EINVAL;
>>> +
>>> +    ret = scmi_pinctrl_validate_id(handle, identifier, type);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    ret = scmi_xfer_get_init(handle, PINCTRL_FUNCTION_SELECT,
>>> +                 SCMI_PROTOCOL_PINCTRL,
>>> +                 sizeof(*tx), 0, &t);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    tx = t->tx.buf;
>>> +    tx->identifier = cpu_to_le32(identifier);
>>> +    tx->function_id = cpu_to_le32(function_id);
>>> +    tx->flags = SET_TYPE(cpu_to_le32(type));
>>> +
>>> +    ret = scmi_do_xfer(handle, t);
>>> +    scmi_xfer_put(handle, t);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_request(const struct scmi_handle *handle,
>>> +                u32 identifier,
>>> +                enum scmi_pinctrl_selector_type type)
>>> +{
>>> +    struct scmi_xfer *t;
>>> +    int ret;
>>> +    struct scmi_request_tx {
>>> +        __le32 identifier;
>>> +        __le32 flags;
>>> +    } *tx;
>>> +
>>
>> Ditto.
>>
>>> +    if (!handle || type == FUNCTION_TYPE)
>>> +        return -EINVAL;
>>> +
>>> +    ret = scmi_pinctrl_validate_id(handle, identifier, type);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    ret = scmi_xfer_get_init(handle, PINCTRL_REQUEST, 
>>> SCMI_PROTOCOL_PINCTRL,
>>> +                 sizeof(*tx), 0, &t);
>>> +
>>> +    tx = t->tx.buf;
>>> +    tx->identifier = identifier;
>>> +    tx->flags = SET_TYPE(cpu_to_le32(type));
>>> +
>>> +    ret = scmi_do_xfer(handle, t);
>>> +    scmi_xfer_put(handle, t);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_request_pin(const struct scmi_handle 
>>> *handle, u32 pin)
>>> +{
>>> +    return scmi_pinctrl_request(handle, pin, PIN_TYPE);
>>> +}
>>> +
>>> +static int scmi_pinctrl_free(const struct scmi_handle *handle, u32 
>>> identifier,
>>> +                 enum scmi_pinctrl_selector_type type)
>>> +{
>>> +    struct scmi_xfer *t;
>>> +    int ret;
>>> +    struct scmi_request_tx {
>>> +        __le32 identifier;
>>> +        __le32 flags;
>>> +    } *tx;
>>> +
>> Ditto.
>>
>>> +    if (!handle || type == FUNCTION_TYPE)
>>> +        return -EINVAL;
>>> +
>>> +    ret = scmi_pinctrl_validate_id(handle, identifier, type);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    ret = scmi_xfer_get_init(handle, PINCTRL_RELEASE, 
>>> SCMI_PROTOCOL_PINCTRL,
>>> +                 sizeof(*tx), 0, &t);
>>> +
>>> +    tx = t->tx.buf;
>>> +    tx->identifier = identifier;
>>> +    tx->flags = SET_TYPE(cpu_to_le32(type));
>>> +
>>> +    ret = scmi_do_xfer(handle, t);
>>> +    scmi_xfer_put(handle, t);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_free_pin(const struct scmi_handle *handle, 
>>> u32 pin)
>>> +{
>>> +    return scmi_pinctrl_free(handle, pin, PIN_TYPE);
>>> +}
>>> +
>>> +
>>> +static int scmi_pinctrl_get_group_info(const struct scmi_handle 
>>> *handle,
>>> +                       u32 selector,
>>> +                       struct scmi_group_info *group)
>>> +{
>>> +    int ret = 0;
>>> +    struct scmi_pinctrl_info *pi;
>>> +
>>> +    if (!handle || !handle->pinctrl_priv || !group)
>>> +        return -EINVAL;
>>> +
>>> +    pi = handle->pinctrl_priv;
>>> +
>>> +    ret = scmi_pinctrl_attributes(handle, GROUP_TYPE, selector,
>>> +                      &group->name,
>>> +                      &group->nr_pins);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    if (!group->nr_pins) {
>>> +        dev_err(handle->dev, "Group %d has 0 elements", selector);
>>> +        return -ENODATA;
>>> +    }
>>> +
>>> +    group->group_pins = devm_kmalloc_array(handle->dev, 
>>> group->nr_pins,
>>> +                           sizeof(*group->group_pins),
>>> +                           GFP_KERNEL);
>>
>> I think you can just use for the array allocation
>>
>>     devm_kcalloc(dev, n, size, flags)
>>
>> and it will add also __GFP_ZERO internally to clear it.
>> (indeed it calls in turn devm_kmalloc_array)
>>
>> ...BUT I think there is a further tricky issue here related to memory 
>> allocation...
>>
>> You call this and others function of this kind from some 
>> scmi_pinctrl_ops,
>> like in scmi_pinctrl_get_group_pins (scmi_pinctrl_ops->get_group_pins),
>> and then this is in turn called by the SCMI Pinctrl driver via
>> pinctrl_ops->get_group_pins AND you set a present flag so that you 
>> issue a
>> PINCTRL_LIST_ASSOCIATIONS and allocate here a new group_pins array just
>> the first time: but these are never released anywhere, since, even 
>> though
>> lazily dynamically allocated when asked for, these are static data that
>> you pass to the caller/user of this protocol and so you cannot release
>> them anytime soon, indeed.
>>
>> The core SCMI stack usually takes care to track and release all the 
>> devm_
>> resources allocated by the protocol ONLY if they were allocated with 
>> devres
>> while inside scmi_pinctrl_protocol_init() function.
>> (see 
>> drivers/firmware/arm-scmi/driver.c:scmi_alloc_init_protocol_instance()
>>   and scmi_protocol_release)
>>
>> BUT you do not allocate these arrays inside the protocol-init function,
>> you allocate them the first time these ops are called at runtime.
>>
>> If you unbind/unload all the drivers using this protocol and then reload
>> them, all the devm_ allocations in protocol_init will be freed and
>> reallocated BUT these arrays will never be freed (they are boudn to 
>> handle->dev)
>> and instead they will be reallocated multiple times (present flag 
>> will be cleared
>> on unload), remained unused and freed finally only when the whole 
>> SCMI stack is
>> unbind/unloaded.
>>
>> You use a present flag to avoid reissuing the same query and
>> reallocating all the arrays each time a driver calls these
>> protocol_ops one, but really all these data is available early on at
>> protocol init time and they are not supposed to change at runtime, 
>> dont they ?
>>
>> Even in a virtualized environment, you boot an agent and the SCMI
>> platform server provides to the agent the list of associations when
>> queried but then this does not change until the next reboot right ?
>> (indeed you do not query more than once...)
>>
>> The agent can only change the PIN status with CONFIG_SET or
>> FUNCTION_SELECT or REQUEST the exclusive use of a pin/group, but it is
>> not that the platform can change the pin/groups associaion for the same
>> agent at run time, this are static data for the whole life of the agent.
>>
>> Am I right ?
>>
>> IOW I think there is some potential memory leak on unbind/bind and it 
>> would
>> be better to query and allocate all of these resources at init time 
>> and keep
>> them ready to be retrieved by subsequent operations, since the lifetime
>> of these resources is pretty long and they are basically representing
>> static data that does not change after the init/probe phases.
>>
>> Indeed, all the other protocols usually allocate all the needed
>> resources and query all the available SCMI resources once for all during
>> the protocol_init, storing all the retrieved info in some struct *_info
>> exposed in scmi_protocol.h and then provide some related protocol_ops to
>> get the number of resources and to retrieve specific domain info 
>> descriptors.
>> (voltage.c is an example and more on this down below...)
>>
>> This way, any dynamic allocation is done during protocol_init, so
>> it can be automatically freed by the SCMI core once there are no more
>> users of that protocol, and all of this static info data is queried
>> and retrieved once for all at protocol initialization time, avoiding
>> unneeded message exchanges to retrieve always the same data.
>> (which you avoid anyway with the present flag)
>>
>> If you have a good reason to instead perform this sort of lazy
>> allocation/query performed only at the last minute when someone ask for
>> that specific resource, you will  have to provide also a 
>> .instance_deinit
>> function to clean anything you allocated out of the .instance_init
>> routine; but this would seem strange to me since any resource that is
>> discovered at init will be eventually immediately queried by a driver
>> which uses this protocol...am I missing something ?
>>
>>> +    if (!group->group_pins) {
>>> +        ret = -ENOMEM;
>>> +        goto err;
>>> +    }
>>> +
>>> +    ret = scmi_pinctrl_list_associations(handle, selector, GROUP_TYPE,
>>> +                         group->nr_pins, group->group_pins);
>>> +    if (ret)
>>> +        goto err_groups;
>>> +
>>> +    group->present = true;
>>> +    return 0;
>>> +
>>> + err_groups:
>>> +    kfree(group->group_pins);
>>> + err:
>>> +    kfree(group->name);
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_get_group_name(const struct scmi_handle 
>>> *handle,
>>> +                       u32 selector, const char **name)
>>> +{
>>> +    int ret;
>>> +    struct scmi_pinctrl_info *pi;
>>> +
>>> +    if (!handle || !handle->pinctrl_priv || !name)
>>> +        return -EINVAL;
>>> +
>>> +    pi = handle->pinctrl_priv;
>>> +
>>> +    if (selector > pi->nr_groups)
>>> +        return -EINVAL;
>>> +
>>> +    if (!pi->groups[selector].present) {
>>> +        ret = scmi_pinctrl_get_group_info(handle, selector,
>>> +                          &pi->groups[selector]);
>>> +        if (ret)
>>> +            return ret;
>>> +    }
>>> +
>>> +    *name = pi->groups[selector].name;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int scmi_pinctrl_get_group_pins(const struct scmi_handle 
>>> *handle,
>>> +                       u32 selector, const unsigned int **pins,
>>> +                       unsigned int *nr_pins)
>>> +{
>>> +    int ret;
>>> +    struct scmi_pinctrl_info *pi;
>>> +
>>> +    if (!handle || !handle->pinctrl_priv || !pins || !nr_pins)
>>> +        return -EINVAL;
>>> +
>>> +    pi = handle->pinctrl_priv;
>>> +
>>> +    if (selector > pi->nr_groups)
>>> +        return -EINVAL;
>>> +
>>> +    if (!pi->groups[selector].present) {
>>> +        ret = scmi_pinctrl_get_group_info(handle, selector,
>>> +                          &pi->groups[selector]);
>>> +        if (ret)
>>> +            return ret;
>>> +    }
>>> +
>>> +    *pins = pi->groups[selector].group_pins;
>>> +    *nr_pins = pi->groups[selector].nr_pins;
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_get_function_info(const struct scmi_handle 
>>> *handle,
>>> +                      u32 selector,
>>> +                      struct scmi_function_info *func)
>>> +{
>>> +    int ret = 0;
>>> +    struct scmi_pinctrl_info *pi;
>>> +
>>> +    if (!handle || !handle->pinctrl_priv || !func)
>>> +        return -EINVAL;
>>> +
>>> +    pi = handle->pinctrl_priv;
>>> +
>>> +    ret = scmi_pinctrl_attributes(handle, FUNCTION_TYPE, selector,
>>> +                      &func->name,
>>> +                      &func->nr_groups);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    if (!func->nr_groups) {
>>> +        dev_err(handle->dev, "Function %d has 0 elements", selector);
>>> +        return -ENODATA;
>>> +    }
>>> +
>>> +    func->groups = devm_kmalloc_array(handle->dev, func->nr_groups,
>>> +                      sizeof(*func->groups),
>>> +                      GFP_KERNEL);
>>> +    if (!func->groups) {
>>> +        ret = -ENOMEM;
>>> +        goto err;
>>> +    }
>>> +
>>> +    ret = scmi_pinctrl_list_associations(handle, selector, 
>>> FUNCTION_TYPE,
>>> +                         func->nr_groups, func->groups);
>>> +    if (ret)
>>> +        goto err_funcs;
>>> +
>>> +    func->present = true;
>>> +    return 0;
>>> +
>>> + err_funcs:
>>> +    kfree(func->groups);
>>> + err:
>>> +    kfree(func->name);
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_get_function_name(const struct scmi_handle 
>>> *handle,
>>> +                      u32 selector, const char **name)
>>> +{
>>> +    int ret;
>>> +    struct scmi_pinctrl_info *pi;
>>> +
>>> +    if (!handle || !handle->pinctrl_priv || !name)
>>> +        return -EINVAL;
>>> +
>>> +    pi = handle->pinctrl_priv;
>>> +
>>> +    if (selector > pi->nr_functions)
>>> +        return -EINVAL;
>>> +
>>> +    if (!pi->functions[selector].present) {
>>> +        ret = scmi_pinctrl_get_function_info(handle, selector,
>>> + &pi->functions[selector]);
>>> +        if (ret)
>>> +            return ret;
>>> +    }
>>> +
>>> +    *name = pi->functions[selector].name;
>>> +    return 0;
>>> +}
>>> +
>>> +static int scmi_pinctrl_get_function_groups(const struct 
>>> scmi_handle *handle,
>>> +                        u32 selector,
>>> +                        unsigned int *nr_groups,
>>> +                        const unsigned int **groups)
>>> +{
>>> +    int ret;
>>> +    struct scmi_pinctrl_info *pi;
>>> +
>>> +    if (!handle || !handle->pinctrl_priv || !groups || !nr_groups)
>>> +        return -EINVAL;
>>> +
>>> +    pi = handle->pinctrl_priv;
>>> +
>>> +    if (selector > pi->nr_functions)
>>> +        return -EINVAL;
>>> +
>>> +    if (!pi->functions[selector].present) {
>>> +        ret = scmi_pinctrl_get_function_info(handle, selector,
>>> + &pi->functions[selector]);
>>> +        if (ret)
>>> +            return ret;
>>> +    }
>>> +
>>> +    *groups = pi->functions[selector].groups;
>>> +    *nr_groups = pi->functions[selector].nr_groups;
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_set_mux(const struct scmi_handle *handle, 
>>> u32 selector,
>>> +                u32 group)
>>> +{
>>> +    return scmi_pinctrl_function_select(handle, group, GROUP_TYPE,
>>> +                        selector);
>>> +}
>>> +
>>> +static int scmi_pinctrl_get_pin_info(const struct scmi_handle *handle,
>>> +                     u32 selector, struct scmi_pin_info *pin)
>>> +{
>>> +    int ret = 0;
>>> +    struct scmi_pinctrl_info *pi;
>>> +    unsigned int n_elems;
>>> +
>>> +    if (!handle || !handle->pinctrl_priv || !pin)
>>> +        return -EINVAL;
>>> +
>>> +    pi = handle->pinctrl_priv;
>>> +
>>> +    ret = scmi_pinctrl_attributes(handle, PIN_TYPE, selector,
>>> +                      &pin->name,
>>> +                      &n_elems);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>> +    if (n_elems != pi->nr_pins) {
>>> +        dev_err(handle->dev, "Wrong pin count expected %d has %d",
>>> +            pi->nr_pins, n_elems);
>>> +        return -ENODATA;
>>> +    }
>>> +
>>> +    if (*(pin->name) == 0) {
>>> +        dev_err(handle->dev, "Pin name is empty");
>>> +        goto err;
>>> +    }
>>> +
>>> +    pin->present = true;
>>> +    return 0;
>>> +
>>> + err:
>>> +    kfree(pin->name);
>>> +    return ret;
>>> +}
>>> +
>>> +static int scmi_pinctrl_get_pin_name(const struct scmi_handle 
>>> *handle, u32 selector,
>>> +                     const char **name)
>>> +{
>>> +
>>> +    int ret;
>>> +    struct scmi_pinctrl_info *pi;
>>> +
>>> +    if (!handle || !handle->pinctrl_priv || !name)
>>> +        return -EINVAL;
>>> +
>>> +    pi = handle->pinctrl_priv;
>>> +
>>> +    if (selector > pi->nr_pins)
>>> +        return -EINVAL;
>>> +
>>> +    if (!pi->pins[selector].present) {
>>> +        ret = scmi_pinctrl_get_pin_info(handle, selector,
>>> +                        &pi->pins[selector]);
>>> +        if (ret)
>>> +            return ret;
>>> +    }
>>> +
>>> +    *name = pi->pins[selector].name;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +
>>> +static const struct scmi_pinctrl_ops pinctrl_ops = {
>>> +    .get_groups_count = scmi_pinctrl_get_groups_count,
>>> +    .get_group_name = scmi_pinctrl_get_group_name,
>>> +    .get_group_pins = scmi_pinctrl_get_group_pins,
>>> +    .get_functions_count = scmi_pinctrl_get_functions_count,
>>> +    .get_function_name = scmi_pinctrl_get_function_name,
>>> +    .get_function_groups = scmi_pinctrl_get_function_groups,
>>> +    .set_mux = scmi_pinctrl_set_mux,
>>> +    .get_pin_name = scmi_pinctrl_get_pin_name,
>>> +    .get_pins_count = scmi_pinctrl_get_pins_count,
>>> +    .get_config = scmi_pinctrl_get_config,
>>> +    .set_config = scmi_pinctrl_set_config,
>>> +    .get_config_group = scmi_pinctrl_get_config_group,
>>> +    .set_config_group = scmi_pinctrl_set_config_group,
>>> +    .request_pin = scmi_pinctrl_request_pin,
>>> +    .free_pin = scmi_pinctrl_free_pin
>>> +};
>>> +
>>> +static int scmi_pinctrl_protocol_init(struct scmi_handle *handle)
>>> +{
>>> +    u32 version;
>>> +    struct scmi_pinctrl_info *pinfo;
>>> +    int ret;
>>> +
>>> +    if (!handle)
>>> +        return -EINVAL;
>>> +
>>> +    scmi_version_get(handle, SCMI_PROTOCOL_PINCTRL, &version);
>>> +
>>> +    dev_dbg(handle->dev, "Pinctrl Version %d.%d\n",
>>> +        PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
>>> +
>>> +    pinfo = devm_kzalloc(handle->dev, sizeof(*pinfo), GFP_KERNEL);
>>> +    if (!pinfo)
>>> +        return -ENOMEM;
>>> +
>>> +    ret = scmi_pinctrl_attributes_get(handle, pinfo);
>>> +    if (ret)
>>> +        goto free;
>>> +
>>> +    pinfo->pins = devm_kmalloc_array(handle->dev, pinfo->nr_pins,
>>> +                     sizeof(*pinfo->pins),
>>> +                     GFP_KERNEL | __GFP_ZERO);
>>
>>   devm_kcalloc() zeroes on its own
>>
>>> +    if (!pinfo->pins) {
>>> +        ret = -ENOMEM;
>>> +        goto free;
>>> +    }
>>> +
>>> +    pinfo->groups = devm_kmalloc_array(handle->dev, pinfo->nr_groups,
>>> +                       sizeof(*pinfo->groups),
>>> +                       GFP_KERNEL | __GFP_ZERO);
>>
>> Ditto.
>>> +    if (!pinfo->groups) {
>>> +        ret = -ENOMEM;
>>> +        goto free;
>>> +    }
>>> +
>>> +    pinfo->functions = devm_kmalloc_array(handle->dev, 
>>> pinfo->nr_functions,
>>> +                          sizeof(*pinfo->functions),
>>> +                          GFP_KERNEL | __GFP_ZERO);
>>> +    if (!pinfo->functions) {
>>> +        ret = -ENOMEM;
>>> +        goto free;
>>> +    }
>>> +
>>> +    pinfo->version = version;
>>> +    handle->pinctrl_ops = &pinctrl_ops;
>>> +    handle->pinctrl_priv = pinfo;
>>> +
>>> +    return 0;
>>> +free:
>>> +    if (pinfo) {
>>> +        devm_kfree(handle->dev, pinfo->pins);
>>> +        devm_kfree(handle->dev, pinfo->functions);
>>> +        devm_kfree(handle->dev, pinfo->groups);
>>> +    }
>>
>> These frees are really not needed...if this function return failure any
>> devres allocated in it is freed by the SCMI core. (as said above...in a
>> recent kernel with the new API of course)
>>
>>> +
>>> +    devm_kfree(handle->dev, pinfo);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(SCMI_PROTOCOL_PINCTRL, 
>>> pinctrl)
>>> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
>>> index 815095326e2d..68add4d06e8c 100644
>>> --- a/drivers/pinctrl/Kconfig
>>> +++ b/drivers/pinctrl/Kconfig
>>> @@ -431,4 +431,13 @@ config PINCTRL_EQUILIBRIUM
>>>         pin functions, configure GPIO attributes for LGM SoC pins. 
>>> Pinmux and
>>>         pinconf settings are retrieved from device tree.
>>>   +config PINCTRL_SCMI
>>> +    bool "Pinctrl driver controlled via SCMI interface"
>>> +    depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
>>> +    help
>>> +      This driver provides support for pinctrl which is controlled
>>> +      by firmware that implements the SCMI interface.
>>> +      It uses SCMI Message Protocol to interact with the
>>> +      firmware providing all the pinctrl controls.
>>> +
>>
>> This does NOT belong to this patch, but to the next right ?
>>
>>>   endif
>>> diff --git a/include/linux/scmi_protocol.h 
>>> b/include/linux/scmi_protocol.h
>>> index 9cd312a1ff92..6a909ef3bf51 100644
>>> --- a/include/linux/scmi_protocol.h
>>> +++ b/include/linux/scmi_protocol.h
>>> @@ -12,7 +12,8 @@
>>>   #include <linux/notifier.h>
>>>   #include <linux/types.h>
>>>   -#define SCMI_MAX_STR_SIZE    16
>>> +#define SCMI_MAX_STR_SIZE 16
>>> +#define SCMI_MAX_STR_EXT_SIZE 64
>>
>> This is handled as part of how the extended names are handled with 
>> ph->hops
>> in a common way, as I was saying, so please move this if you need it in
>> the protocol code, then I'll port to the ph->hops interface and clean
>> up.
>>
>>>   #define SCMI_MAX_NUM_RATES    16
>>>     /**
>>> @@ -252,6 +253,55 @@ struct scmi_notify_ops {
>>>                        struct notifier_block *nb);
>>>   };
>>>   +/**
>>> + * struct scmi_pinctrl_ops - represents the various operations 
>>> provided
>>> + * by SCMI Pinctrl Protocol
>>> + *
>>> + * @get_groups_count: returns count of the registered groups
>>> + * @get_group_name: returns group name by index
>>> + * @get_group_pins: returns the set of pins, assigned to the 
>>> specified group
>>> + * @get_functions_count: returns count of the registered fucntions
>>> + * @get_function_name: returns function name by indes
>>> + * @get_function_groups: returns the set of groups, assigned to the 
>>> specified
>>> + *    function
>>> + * @set_mux: set muxing function for groups of pins
>>> + * @get_pins: returns the set of pins, registered in driver
>>> + * @get_config: returns configuration parameter for pin
>>> + * @set_config: sets the configuration parameter for pin
>>> + * @get_config_group: returns the configuration parameter for a 
>>> group of pins
>>> + * @set_config_group: sets the configuration parameter for a groups 
>>> of pins
>>> + * @request_pin: aquire pin before selecting mux setting
>>> + * @free_pin: frees pin, acquired by request_pin call
>>> + */
>>> +struct scmi_pinctrl_ops {
>>> +    int (*get_groups_count)(const struct scmi_handle *handle);
>>> +    int (*get_group_name)(const struct scmi_handle *handles, u32 
>>> selector,
>>> +                  const char **name);
>>> +    int (*get_group_pins)(const struct scmi_handle *handle, u32 
>>> selector,
>>> +                  const unsigned int **pins, unsigned int *nr_pins);
>>> +    int (*get_functions_count)(const struct scmi_handle *handle);
>>> +    int (*get_function_name)(const struct scmi_handle *handle, u32 
>>> selector,
>>> +                 const char **name);
>>> +    int (*get_function_groups)(const struct scmi_handle *handle,
>>> +                   u32 selector, unsigned int *nr_groups,
>>> +                   const unsigned int **groups);
>>> +    int (*set_mux)(const struct scmi_handle *handle, u32 selector,
>>> +               u32 group);
>>> +    int (*get_pin_name)(const struct scmi_handle *handle, u32 
>>> selector,
>>> +                const char **name);
>>> +    int (*get_pins_count)(const struct scmi_handle *handle);
>>> +    int (*get_config)(const struct scmi_handle *handle, u32 pin,
>>> +              u32 *config);
>>> +    int (*set_config)(const struct scmi_handle *handle, u32 pin,
>>> +              u32 config);
>>> +    int (*get_config_group)(const struct scmi_handle *handle, u32 pin,
>>> +              u32 *config);
>>> +    int (*set_config_group)(const struct scmi_handle *handle, u32 pin,
>>> +              u32 config);
>>> +    int (*request_pin)(const struct scmi_handle *handle, u32 pin);
>>> +    int (*free_pin)(const struct scmi_handle *handle, u32 pin);
>>> +};
>>> +
>>
>> As mentioned above, here you could drop a lot of this 
>> get_X_count/name/pins
>> and instead expose a few of the internal proocol struct scmi__X_info 
>> and then
>> provide just a mean to query how many resource are there and then get 
>> the info
>> descriptor you want for the specific domain_id, i.e.:
>>
>>      int (*num_domains_get)(ph, type)
>>      void *(*info_get)(ph, type, domain_id);
>>
>> Thanks,
>> Cristian
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> https://urldefense.com/v3/__http://lists.infradead.org/mailman/listinfo/linux-arm-kernel__;!!GF_29dbcQIUBPA!y2hR3PEGGxiPjVeXBcgGyV03DPDhzgUKR0uHvsTpiafKgBar8Egc6oOOs-IkFIquhSf-qBzltqEMyzRZrZi7qlk$ 
>> [lists[.]infradead[.]org]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 1/6] drm: bridge: samsung-dsim: Support multi-lane calculations
From: Lucas Stach @ 2023-04-21  8:40 UTC (permalink / raw)
  To: Adam Ford
  Cc: dri-devel, Krzysztof Kozlowski, aford, Laurent Pinchart,
	Andrzej Hajda, Fabio Estevam, m.szyprowski, marex, Robert Foss,
	David Airlie, Jernej Skrabec, Jagan Teki, NXP Linux Team,
	devicetree, Daniel Vetter, Jonas Karlman, Sascha Hauer, Inki Dae,
	Rob Herring, linux-arm-kernel, Neil Armstrong, linux-kernel,
	Pengutronix Kernel Team, Shawn Guo
In-Reply-To: <CAHCN7x+HYmGoxZ107OdY1aJYtjNWB4p3fqJ1tGjOAK2eO356yA@mail.gmail.com>

Am Donnerstag, dem 20.04.2023 um 16:51 -0500 schrieb Adam Ford:
> On Thu, Apr 20, 2023 at 8:43 AM Lucas Stach <l.stach@pengutronix.de> wrote:
> > 
> > Am Donnerstag, dem 20.04.2023 um 08:24 -0500 schrieb Adam Ford:
> > > On Thu, Apr 20, 2023 at 8:06 AM Lucas Stach <l.stach@pengutronix.de> wrote:
> > > > 
> > > > Hi Adam,
> > > > 
> > > > Am Mittwoch, dem 19.04.2023 um 05:47 -0500 schrieb Adam Ford:
> > > > > On Mon, Apr 17, 2023 at 6:55 AM Adam Ford <aford173@gmail.com> wrote:
> > > > > > 
> > > > > > On Mon, Apr 17, 2023 at 3:43 AM Lucas Stach <l.stach@pengutronix.de> wrote:
> > > > > > > 
> > > > > > > Hi Adam,
> > > > > > > 
> > > > > > > Am Samstag, dem 15.04.2023 um 05:40 -0500 schrieb Adam Ford:
> > > > > > > > If there is more than one lane, the HFP, HBP, and HSA is calculated in
> > > > > > > > bytes/pixel, then they are divided amongst the different lanes with some
> > > > > > > > additional overhead. This is necessary to achieve higher resolutions while
> > > > > > > > keeping the pixel clocks lower as the number of lanes increase.
> > > > > > > > 
> > > > > > > 
> > > > > > > In the testing I did to come up with my patch "drm: bridge: samsung-
> > > > > > > dsim: fix blanking packet size calculation" the number of lanes didn't
> > > > > > > make any difference. My testing might be flawed, as I could only
> > > > > > > measure the blanking after translation from MIPI DSI to DPI, so I'm
> > > > > > > interested to know what others did here. How did you validate the
> > > > > > > blanking with your patch? Would you have a chance to test my patch and
> > > > > > > see if it works or breaks in your setup?
> > > > > 
> > > > > Lucas,
> > > > > 
> > > > > I tried your patch instead of mine.  Yours is dependent on the
> > > > > hs_clock being always set to the burst clock which is configured by
> > > > > the device tree.  I unrolled a bit of my stuff and replaced it with
> > > > > yours.  It worked at 1080p, but when I tried a few other resolutions,
> > > > > they did not work.  I assume it's because the DSI clock is fixed and
> > > > > not changing based on the pixel clock.  In the version I did, I only
> > > > > did that math when the lanes were > 1. In your patch, you divide by 8,
> > > > > and in mine, I fetch the bits-per-pixel (which is 8) and I divide by
> > > > > that just in case the bpp ever changes from 8.  Overall,  I think our
> > > > > patches basically do the same thing.
> > > > 
> > > > The calculations in your and my patch are quite different. I'm not
> > > > taking into account the number of lanes or the MIPI format. I'm basing
> 
> I was taking the number of lanes into account in order to calculate
> the clock rate, since 4-lanes can run slower.
> 
Ah that makes sense if you aren't running at full clock burst clock
rate.

> > > 
> > > I was looking more at the division by 8 and the overhead correction of 6.
> > > This number 6 also appears in the NXP downstream kernel [1].  I know
> > > Marek V had some concerns about that.
> > > 
> > Yea, I don't fully remember the details about the overhead. Need to
> > page that back in. The division by 8 in my patch is just to get from
> > the bit to a byte clock, nothing to do with the MIPI format bits per
> > channel or something like that.
> > 
> > > > the blanking size purely on the ratio between MIPI DSI byte clock and
> > > > the DPI interface clock. It's quite counter-intuitive that the host
> > > > would scale the blanking to the number of lanes automatically, but
> > > > still require the MIPI packet offset removed, but that's what my
> > > > measurements showed to produce the correct blanking after translation
> > > > to DPI by the TC358767 bridge chip.
> > > 
> > > How many lanes is your DSI interface using?
> > > 
> > When I did the measurements to come up with the patch, I varied the
> > number of lanes between 1 and 4. Different number of lanes didn't make
> > a difference. In fact trying to compensate for the number of lanes when
> > calculating the blanking size to program into the controller lead to
> > wildly wrong blanking on the DPI side of the external bridge.
> > 
> > > > 
> > > > If you dynamically scale the HS clock, then you would need to input the
> > > > real used HS clock to the calculation in my patch, instead of the fixed
> > > > burst mode rate.
> > > 
> > > I think what you're saying makes sense.
> > > 
> > > The code I originally modeled this from was from the NXP downstream
> > > kernel where they define the calculation as being in words [2]. I am
> > > not saying the NXP code is perfect, but the NXP code works.  With this
> > > series, my monitors are able to sync a bunch of different resolutions
> > > from 1080p down to 640x480 and a bunch in between with various refresh
> > > rates too. That was the goal of this series.
> > > 
> > > Instead of just using your patch as-is, I will adapt yours to use the
> > > scaled clock to see how it behaves and get back to you.
> > > 
> > 
> > Thanks, that would be very much appreciated.
> 
> Lucas,
> 
> I took your patch and added a dsi state variable named "hs_clock"  to
> keep track of the output of samsung_dsim_set_pll which should be the
> active high-speed clock.
> 
> I then replaced one line in your code to reference the hs_clock
> instead of the burst clock:
> 
> @@ -960,7 +962,7 @@ static void samsung_dsim_set_display_mode(struct
> samsung_dsim *dsi)
>         u32 reg;
> 
>         if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
> -               int byte_clk_khz = dsi->burst_clk_rate / 1000 / 8;
> +               int byte_clk_khz = dsi->hs_clock / 1000 / 8;
>                 int hfp = (m->hsync_start - m->hdisplay) *
> byte_clk_khz / m->clock;
> 
> With that change, your patch works with the rest of my code, and I
> think it's easier to read, and it doesn't involve recalculating the
> clock speed each time since it's cached.  If you're OK with that, I'll
> incorporate your code into V2 of my series, and I'll apply my changes
> as a subsequent patch.  I hope to be able to send out V2 this weekend.
> 
That's good to hear! Seems we are converging here. Feel free to pick up
the patch, that's also easier for me as I don't have to resend with CC
fixed.

> I would be curious to know frm Marek Szyprowski what the impact is on
> the Samsung devices, if any.
> 
Since I messed up the list CC you also couldn't see his reply to my
patch:

| Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
| 
| Works fine on the Exynos based boards I have in my test farm.

Regards,
Lucas

> adam
> 
> > 
> > I also don't assert that my calculation is perfect, as I also don't
> > have any more information and needed to resort to observing the
> > blanking after translation by the external bridge, so I hope we could
> > get some better understanding of how things really work by checking
> > what works for both our systems.
> > 
> > >   I have
> > > finished reworking the dynamic DPHY settings, and I've fixed up making
> > > the PLL device tree optional. If your patch works, I'll drop my
> > > calculation and just build off what you have to use the scaled HS
> > > clock when I submit the V2 and I'll make sure I CC you.
> > > 
> > Thanks, I'm open to re-do my measurements with your new patches.
> > 
> > Regards,
> > Lucas
> > 
> > > adam
> > > 
> > > [1] - https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/drivers/gpu/drm/bridge/sec-dsim.c#L270
> > > [2] - https://github.com/nxp-imx/linux-imx/blob/lf-6.1.y/drivers/gpu/drm/bridge/sec-dsim.c#L914
> > > 
> > > > 
> > > > Regards,
> > > > Lucas
> > 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH -next] drm/stm: dsi: Use devm_platform_ioremap_resource()
From: Yang Li @ 2023-04-21  8:34 UTC (permalink / raw)
  To: yannick.fertre
  Cc: raphael.gallais-pou, philippe.cornu, airlied, daniel,
	mcoquelin.stm32, alexandre.torgue, dri-devel, linux-stm32,
	linux-arm-kernel, linux-kernel, Yang Li

Convert platform_get_resource(),devm_ioremap_resource() to a single call
to devm_platform_ioremap_resource(), as this is exactly what this function
does.

Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
---
 drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
index 89897d5f5c72..1750b6a25e87 100644
--- a/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
+++ b/drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
@@ -444,15 +444,13 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct dw_mipi_dsi_stm *dsi;
 	struct clk *pclk;
-	struct resource *res;
 	int ret;
 
 	dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
 	if (!dsi)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dsi->base = devm_ioremap_resource(dev, res);
+	dsi->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(dsi->base)) {
 		ret = PTR_ERR(dsi->base);
 		DRM_ERROR("Unable to get dsi registers %d\n", ret);
-- 
2.20.1.7.g153144c


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH 1/3] ARM: dts: sun5i: chip: Enable bluetooth
From: Jonathan McDowell @ 2023-04-21  8:28 UTC (permalink / raw)
  To: Saravana Kannan
  Cc: Andre Przywara, Greg Kroah-Hartman, Rob Herring,
	Krzysztof Kozlowski, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland,
	devicetree, linux-arm-kernel, linux-sunxi, linux-kernel
In-Reply-To: <CAGETcx-UnEK3CPC38Ef3gmHcq46nXSJbA9QAwEsF+Xt2bDKEWA@mail.gmail.com>

On Thu, Apr 20, 2023 at 06:43:06PM -0700, Saravana Kannan wrote:
> On Thu, Apr 20, 2023 at 12:12 PM Jonathan McDowell <noodles@earth.li> wrote:
> > On Sun, Apr 16, 2023 at 01:24:21AM +0100, Andre Przywara wrote:
> > > On Sat, 15 Apr 2023 18:46:03 +0100
> > > Jonathan McDowell <noodles@earth.li> wrote:
> > >
> > > > The C.H.I.P has an rtl8723bs device with the bluetooth interface hooked
> > > > up on UART3. Support for this didn't exist in mainline when the DTS was
> > > > initially added, but it does now, so enable it.
> > > >
> > > > Signed-off-by: Jonathan McDowell <noodles@earth.li>
> > > > ---
> > > >  arch/arm/boot/dts/sun5i-r8-chip.dts | 4 ++++
> > > >  1 file changed, 4 insertions(+)
> > > >
> > > > diff --git a/arch/arm/boot/dts/sun5i-r8-chip.dts b/arch/arm/boot/dts/sun5i-r8-chip.dts
> > > > index fd37bd1f3920..4d72a181d8aa 100644
> > > > --- a/arch/arm/boot/dts/sun5i-r8-chip.dts
> > > > +++ b/arch/arm/boot/dts/sun5i-r8-chip.dts
> > > > @@ -255,6 +255,10 @@ &uart3 {
> > > >     pinctrl-0 = <&uart3_pg_pins>,
> > > >                 <&uart3_cts_rts_pg_pins>;
> > > >     status = "okay";
> > > > +
> > > > +   bluetooth {
> > > > +           compatible = "realtek,rtl8723bs-bt";
> > > > +   }
> > >
> > > As the kernel test robot already pointed out, there is a semicolon
> > > missing here.
> > > Otherwise looks good (dt-validate passes), but don't know if there are
> > > any wakeup GPIOs connected (can't seem to find a schematic?).
> >
> > So there are wakeups, but if I add:
> >
> >         device-wake-gpios = <&axp_gpio 3 GPIO_ACTIVE_LOW>;
> >         host-wake-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
> >
> > then some odd sort of dependency issue happens where the serial port
> > load is deferred waiting for the GPIO to appear, and then the device
> > doesn't work.
> 
> When you say your device doesn't work, are you saying it never probes?

The bluetooth device (realtek,rtl8723bs-bt) never appears, apparently
because the UART it's attached to never loads - it doesn't even try to
load the firmware.

> <debugfs>/devices_deferred should tell you what devices have deferred and why.

root@chip:~# cat /sys/kernel/debug/devices_deferred
serial0-0

> > Error in dmesg is:
> >
> > serial serial0-0: deferred probe pending
> >
> > on 6.3-rc and on 6.1 I get:
> >
> > dw-apb-uart 1c28c00.serial: Failed to create device link (0x180) with axp20x-gpio
> 
> This error message doesn't block anything. So I don't think this is
> the cause of your blocking issue. But I still want to understand why
> this error message is showing up.
> 
> > I'm not clear why it's trying to link the serial port to the GPIO; it
> > seems that it should be the bluetooth device that depends on both the
> > UART and the GPIO,
> 
> A fix for the device link error message went in on v6.3-rc3. Is that
> the 6.3 version you tested this on?

I originally tried on 6.1.21, which is where I got the "Failed to create
device link" message. I then moved to 6.3-rc7 as I saw there had been
further changes recently. There I just get the:

serial serial0-0: deferred probe pending

message.

> Also, I tried looking into the UART driver
> (drivers/tty/serial/8250/8250_dw.c) but it wasn't clear how it ends up
> populating the bluetooth serial device. If you can point that out,
> that'd be helpful (assuming 6.3-rc3 still shows that error message).

I have the following in my device tree:

&uart3 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart3_pg_pins>,
                    <&uart3_cts_rts_pg_pins>;
        status = "okay";

        bluetooth {
                compatible = "realtek,rtl8723bs-bt";
                device-wake-gpios = <&axp_gpio 3 GPIO_ACTIVE_LOW>;
                host-wake-gpios = <&pio 1 3 GPIO_ACTIVE_HIGH>; /* PB3 */
        };
};

uart3 is a snps,dw-apb-uart, defined in arch/arm/boot/dts/sun5i.dtsi

The UART and AXP209 device drivers are compiled into the kernel:

CONFIG_PINCTRL_AXP209=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_DW=y

The bluetooth bits are modules (btrtl, hci_uart).

If I remove the device-wake-gpios line then the Bluetooth device works
fine, and /sys/kernel/debug/devices_deferred is empty.

Somehow it seems like the GPIO is being parsed as a dependency for the
serial port, even though the serial port + GPIO are both dependencies
for the bluetooth device. Even with that, given both are built-in I
don't understand why the serial port never completes setup.

> > and that the GPIO is actually optional so shouldn't
> > hold up loading, but I can't see how that should be represented.
> 
> Optional dependencies should get ignored after the default
> deferred_probe_timeout runs out and the supplier driver hasn't been
> loaded yet.

When I say it's optional I mean if it's not listed everything works
fine, but I don't believe there's anyway to express that in the DTS.
It's certainly not required for the serial port, just the bluetooth
device.

J.

-- 
Web [                     Don't be a stranger.                     ]
site: https:// [                                          ]      Made by
www.earth.li/~noodles/  [                      ]         HuggieTag 0.0.24

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH] kasan: use internal prototypes matching gcc-13 builtins
From: Arnd Bergmann @ 2023-04-21  8:19 UTC (permalink / raw)
  To: Andrey Ryabinin, Andrew Morton
  Cc: Arnd Bergmann, Catalin Marinas, Will Deacon, Alexander Potapenko,
	Andrey Konovalov, Dmitry Vyukov, Vincenzo Frascino, Mark Rutland,
	Kees Cook, Ard Biesheuvel, Marc Zyngier, Matthew Wilcox (Oracle),
	Marco Elver, Vlastimil Babka, Peter Zijlstra (Intel),
	linux-arm-kernel, linux-kernel, kasan-dev, linux-mm

From: Arnd Bergmann <arnd@arndb.de>

gcc-13 warns about function definitions for builtin interfaces
that have a different prototype, e.g.:

In file included from kasan_test.c:31:
kasan.h:574:6: error: conflicting types for built-in function '__asan_register_globals'; expected 'void(void *, long int)' [-Werror=builtin-declaration-mismatch]
  574 | void __asan_register_globals(struct kasan_global *globals, size_t size);
kasan.h:577:6: error: conflicting types for built-in function '__asan_alloca_poison'; expected 'void(void *, long int)' [-Werror=builtin-declaration-mismatch]
  577 | void __asan_alloca_poison(unsigned long addr, size_t size);
kasan.h:580:6: error: conflicting types for built-in function '__asan_load1'; expected 'void(void *)' [-Werror=builtin-declaration-mismatch]
  580 | void __asan_load1(unsigned long addr);
kasan.h:581:6: error: conflicting types for built-in function '__asan_store1'; expected 'void(void *)' [-Werror=builtin-declaration-mismatch]
  581 | void __asan_store1(unsigned long addr);
kasan.h:643:6: error: conflicting types for built-in function '__hwasan_tag_memory'; expected 'void(void *, unsigned char,  long int)' [-Werror=builtin-declaration-mismatch]
  643 | void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size);

The two problems are:

 - Addresses are passes as 'unsigned long' in the kernel, but gcc-13
   expects a 'void *'.

 - sizes are expected to be the built-in ssize_t type, not the one that
   is provided by the kernel. On 32-bit architectures, this is usually
   a signed 'int' rather than 'unsigned long.

Change all the prototypes to match these, using a custom 'kasan_size_t'
that is defined the way that gcc expects it regardless of the kernel's
size_t/ssize_t. Using 'void *' consistently for addresses gets rid of
a couple of type casts, so push that down to the leaf functions where
possible.

This now passes all randconfig builds on arm, arm64 and x86, but I have
not tested it on the other architectures that support kasan, since they
tend to fail randconfig builds in other ways. This might fail if any
of the 32-bit architectures expect a 'long' instead of 'int' for the size
argument.

The __asan_allocas_unpoison() function prototype is somewhat weird,
since it uses a pointer for 'stack_top' and an size_t for 'stack_bottom'.
This looks like it is meant to be 'addr' and 'size' like the others,
but the implementation clearly treats them as 'top' and 'bottom'.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
 arch/arm64/kernel/traps.c |   2 +-
 arch/arm64/mm/fault.c     |   2 +-
 include/linux/kasan.h     |   2 +-
 mm/kasan/common.c         |   2 +-
 mm/kasan/generic.c        |  72 ++++++++---------
 mm/kasan/kasan.h          | 166 ++++++++++++++++++++------------------
 mm/kasan/report.c         |  17 ++--
 mm/kasan/report_generic.c |  12 +--
 mm/kasan/report_hw_tags.c |   2 +-
 mm/kasan/report_sw_tags.c |   2 +-
 mm/kasan/shadow.c         |  36 ++++-----
 mm/kasan/sw_tags.c        |  20 ++---
 12 files changed, 170 insertions(+), 165 deletions(-)

diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 35a95b78b14f..3f5a21e5968e 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -1044,7 +1044,7 @@ static int kasan_handler(struct pt_regs *regs, unsigned long esr)
 	bool recover = esr & KASAN_ESR_RECOVER;
 	bool write = esr & KASAN_ESR_WRITE;
 	size_t size = KASAN_ESR_SIZE(esr);
-	u64 addr = regs->regs[0];
+	void *addr = (void *)regs->regs[0];
 	u64 pc = regs->pc;
 
 	kasan_report(addr, size, write, pc);
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index f4418382be98..940391ec5e1e 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -317,7 +317,7 @@ static void report_tag_fault(unsigned long addr, unsigned long esr,
 	 * find out access size.
 	 */
 	bool is_write = !!(esr & ESR_ELx_WNR);
-	kasan_report(addr, 0, is_write, regs->pc);
+	kasan_report((void *)addr, 0, is_write, regs->pc);
 }
 #else
 /* Tag faults aren't enabled without CONFIG_KASAN_HW_TAGS. */
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index f7ef70661ce2..819b6bc8ac08 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -343,7 +343,7 @@ static inline void *kasan_reset_tag(const void *addr)
  * @is_write: whether the bad access is a write or a read
  * @ip: instruction pointer for the accessibility check or the bad access itself
  */
-bool kasan_report(unsigned long addr, size_t size,
+bool kasan_report(const void *addr, size_t size,
 		bool is_write, unsigned long ip);
 
 #else /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */
diff --git a/mm/kasan/common.c b/mm/kasan/common.c
index b376a5d055e5..256930da578a 100644
--- a/mm/kasan/common.c
+++ b/mm/kasan/common.c
@@ -445,7 +445,7 @@ void * __must_check __kasan_krealloc(const void *object, size_t size, gfp_t flag
 bool __kasan_check_byte(const void *address, unsigned long ip)
 {
 	if (!kasan_byte_accessible(address)) {
-		kasan_report((unsigned long)address, 1, false, ip);
+		kasan_report(address, 1, false, ip);
 		return false;
 	}
 	return true;
diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c
index e5eef670735e..c0cab050fbf7 100644
--- a/mm/kasan/generic.c
+++ b/mm/kasan/generic.c
@@ -40,39 +40,39 @@
  * depending on memory access size X.
  */
 
-static __always_inline bool memory_is_poisoned_1(unsigned long addr)
+static __always_inline bool memory_is_poisoned_1(const void *addr)
 {
-	s8 shadow_value = *(s8 *)kasan_mem_to_shadow((void *)addr);
+	s8 shadow_value = *(s8 *)kasan_mem_to_shadow(addr);
 
 	if (unlikely(shadow_value)) {
-		s8 last_accessible_byte = addr & KASAN_GRANULE_MASK;
+		s8 last_accessible_byte = (unsigned long)addr & KASAN_GRANULE_MASK;
 		return unlikely(last_accessible_byte >= shadow_value);
 	}
 
 	return false;
 }
 
-static __always_inline bool memory_is_poisoned_2_4_8(unsigned long addr,
+static __always_inline bool memory_is_poisoned_2_4_8(const void *addr,
 						unsigned long size)
 {
-	u8 *shadow_addr = (u8 *)kasan_mem_to_shadow((void *)addr);
+	u8 *shadow_addr = (u8 *)kasan_mem_to_shadow(addr);
 
 	/*
 	 * Access crosses 8(shadow size)-byte boundary. Such access maps
 	 * into 2 shadow bytes, so we need to check them both.
 	 */
-	if (unlikely(((addr + size - 1) & KASAN_GRANULE_MASK) < size - 1))
+	if (unlikely((((unsigned long)addr + size - 1) & KASAN_GRANULE_MASK) < size - 1))
 		return *shadow_addr || memory_is_poisoned_1(addr + size - 1);
 
 	return memory_is_poisoned_1(addr + size - 1);
 }
 
-static __always_inline bool memory_is_poisoned_16(unsigned long addr)
+static __always_inline bool memory_is_poisoned_16(const void *addr)
 {
-	u16 *shadow_addr = (u16 *)kasan_mem_to_shadow((void *)addr);
+	u16 *shadow_addr = (u16 *)kasan_mem_to_shadow(addr);
 
 	/* Unaligned 16-bytes access maps into 3 shadow bytes. */
-	if (unlikely(!IS_ALIGNED(addr, KASAN_GRANULE_SIZE)))
+	if (unlikely(!IS_ALIGNED((unsigned long)addr, KASAN_GRANULE_SIZE)))
 		return *shadow_addr || memory_is_poisoned_1(addr + 15);
 
 	return *shadow_addr;
@@ -120,26 +120,25 @@ static __always_inline unsigned long memory_is_nonzero(const void *start,
 	return bytes_is_nonzero(start, (end - start) % 8);
 }
 
-static __always_inline bool memory_is_poisoned_n(unsigned long addr,
-						size_t size)
+static __always_inline bool memory_is_poisoned_n(const void *addr, size_t size)
 {
 	unsigned long ret;
 
-	ret = memory_is_nonzero(kasan_mem_to_shadow((void *)addr),
-			kasan_mem_to_shadow((void *)addr + size - 1) + 1);
+	ret = memory_is_nonzero(kasan_mem_to_shadow(addr),
+			kasan_mem_to_shadow(addr + size - 1) + 1);
 
 	if (unlikely(ret)) {
-		unsigned long last_byte = addr + size - 1;
-		s8 *last_shadow = (s8 *)kasan_mem_to_shadow((void *)last_byte);
+		const void *last_byte = addr + size - 1;
+		s8 *last_shadow = (s8 *)kasan_mem_to_shadow(last_byte);
 
 		if (unlikely(ret != (unsigned long)last_shadow ||
-			((long)(last_byte & KASAN_GRANULE_MASK) >= *last_shadow)))
+			(((long)last_byte & KASAN_GRANULE_MASK) >= *last_shadow)))
 			return true;
 	}
 	return false;
 }
 
-static __always_inline bool memory_is_poisoned(unsigned long addr, size_t size)
+static __always_inline bool memory_is_poisoned(const void *addr, size_t size)
 {
 	if (__builtin_constant_p(size)) {
 		switch (size) {
@@ -159,7 +158,7 @@ static __always_inline bool memory_is_poisoned(unsigned long addr, size_t size)
 	return memory_is_poisoned_n(addr, size);
 }
 
-static __always_inline bool check_region_inline(unsigned long addr,
+static __always_inline bool check_region_inline(const void *addr,
 						size_t size, bool write,
 						unsigned long ret_ip)
 {
@@ -172,7 +171,7 @@ static __always_inline bool check_region_inline(unsigned long addr,
 	if (unlikely(addr + size < addr))
 		return !kasan_report(addr, size, write, ret_ip);
 
-	if (unlikely(!addr_has_metadata((void *)addr)))
+	if (unlikely(!addr_has_metadata(addr)))
 		return !kasan_report(addr, size, write, ret_ip);
 
 	if (likely(!memory_is_poisoned(addr, size)))
@@ -181,7 +180,7 @@ static __always_inline bool check_region_inline(unsigned long addr,
 	return !kasan_report(addr, size, write, ret_ip);
 }
 
-bool kasan_check_range(unsigned long addr, size_t size, bool write,
+bool kasan_check_range(const void *addr, size_t size, bool write,
 					unsigned long ret_ip)
 {
 	return check_region_inline(addr, size, write, ret_ip);
@@ -221,36 +220,37 @@ static void register_global(struct kasan_global *global)
 		     KASAN_GLOBAL_REDZONE, false);
 }
 
-void __asan_register_globals(struct kasan_global *globals, size_t size)
+void __asan_register_globals(void *ptr, kasan_size_t size)
 {
 	int i;
+	struct kasan_global *globals = ptr;
 
 	for (i = 0; i < size; i++)
 		register_global(&globals[i]);
 }
 EXPORT_SYMBOL(__asan_register_globals);
 
-void __asan_unregister_globals(struct kasan_global *globals, size_t size)
+void __asan_unregister_globals(void *ptr, kasan_size_t size)
 {
 }
 EXPORT_SYMBOL(__asan_unregister_globals);
 
 #define DEFINE_ASAN_LOAD_STORE(size)					\
-	void __asan_load##size(unsigned long addr)			\
+	void __asan_load##size(void *addr)				\
 	{								\
 		check_region_inline(addr, size, false, _RET_IP_);	\
 	}								\
 	EXPORT_SYMBOL(__asan_load##size);				\
 	__alias(__asan_load##size)					\
-	void __asan_load##size##_noabort(unsigned long);		\
+	void __asan_load##size##_noabort(void *);			\
 	EXPORT_SYMBOL(__asan_load##size##_noabort);			\
-	void __asan_store##size(unsigned long addr)			\
+	void __asan_store##size(void *addr)				\
 	{								\
 		check_region_inline(addr, size, true, _RET_IP_);	\
 	}								\
 	EXPORT_SYMBOL(__asan_store##size);				\
 	__alias(__asan_store##size)					\
-	void __asan_store##size##_noabort(unsigned long);		\
+	void __asan_store##size##_noabort(void *);			\
 	EXPORT_SYMBOL(__asan_store##size##_noabort)
 
 DEFINE_ASAN_LOAD_STORE(1);
@@ -259,24 +259,24 @@ DEFINE_ASAN_LOAD_STORE(4);
 DEFINE_ASAN_LOAD_STORE(8);
 DEFINE_ASAN_LOAD_STORE(16);
 
-void __asan_loadN(unsigned long addr, size_t size)
+void __asan_loadN(void *addr, kasan_size_t size)
 {
 	kasan_check_range(addr, size, false, _RET_IP_);
 }
 EXPORT_SYMBOL(__asan_loadN);
 
 __alias(__asan_loadN)
-void __asan_loadN_noabort(unsigned long, size_t);
+void __asan_loadN_noabort(void *, kasan_size_t);
 EXPORT_SYMBOL(__asan_loadN_noabort);
 
-void __asan_storeN(unsigned long addr, size_t size)
+void __asan_storeN(void *addr, kasan_size_t size)
 {
 	kasan_check_range(addr, size, true, _RET_IP_);
 }
 EXPORT_SYMBOL(__asan_storeN);
 
 __alias(__asan_storeN)
-void __asan_storeN_noabort(unsigned long, size_t);
+void __asan_storeN_noabort(void *, kasan_size_t);
 EXPORT_SYMBOL(__asan_storeN_noabort);
 
 /* to shut up compiler complaints */
@@ -284,7 +284,7 @@ void __asan_handle_no_return(void) {}
 EXPORT_SYMBOL(__asan_handle_no_return);
 
 /* Emitted by compiler to poison alloca()ed objects. */
-void __asan_alloca_poison(unsigned long addr, size_t size)
+void __asan_alloca_poison(void *addr, kasan_size_t size)
 {
 	size_t rounded_up_size = round_up(size, KASAN_GRANULE_SIZE);
 	size_t padding_size = round_up(size, KASAN_ALLOCA_REDZONE_SIZE) -
@@ -295,7 +295,7 @@ void __asan_alloca_poison(unsigned long addr, size_t size)
 			KASAN_ALLOCA_REDZONE_SIZE);
 	const void *right_redzone = (const void *)(addr + rounded_up_size);
 
-	WARN_ON(!IS_ALIGNED(addr, KASAN_ALLOCA_REDZONE_SIZE));
+	WARN_ON(!IS_ALIGNED((unsigned long)addr, KASAN_ALLOCA_REDZONE_SIZE));
 
 	kasan_unpoison((const void *)(addr + rounded_down_size),
 			size - rounded_down_size, false);
@@ -307,18 +307,18 @@ void __asan_alloca_poison(unsigned long addr, size_t size)
 EXPORT_SYMBOL(__asan_alloca_poison);
 
 /* Emitted by compiler to unpoison alloca()ed areas when the stack unwinds. */
-void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom)
+void __asan_allocas_unpoison(void *stack_top, kasan_size_t stack_bottom)
 {
-	if (unlikely(!stack_top || stack_top > stack_bottom))
+	if (unlikely(!stack_top || stack_top > (void *)stack_bottom))
 		return;
 
-	kasan_unpoison(stack_top, stack_bottom - stack_top, false);
+	kasan_unpoison(stack_top, (void *)stack_bottom - stack_top, false);
 }
 EXPORT_SYMBOL(__asan_allocas_unpoison);
 
 /* Emitted by the compiler to [un]poison local variables. */
 #define DEFINE_ASAN_SET_SHADOW(byte) \
-	void __asan_set_shadow_##byte(const void *addr, size_t size)	\
+	void __asan_set_shadow_##byte(const void *addr, kasan_size_t size)	\
 	{								\
 		__memset((void *)addr, 0x##byte, size);			\
 	}								\
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index cd846ca34f44..cce8fd1b33fb 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -198,13 +198,13 @@ enum kasan_report_type {
 struct kasan_report_info {
 	/* Filled in by kasan_report_*(). */
 	enum kasan_report_type type;
-	void *access_addr;
+	const void *access_addr;
 	size_t access_size;
 	bool is_write;
 	unsigned long ip;
 
 	/* Filled in by the common reporting code. */
-	void *first_bad_addr;
+	const void *first_bad_addr;
 	struct kmem_cache *cache;
 	void *object;
 	size_t alloc_size;
@@ -289,6 +289,12 @@ struct kasan_stack_ring {
 
 #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS */
 
+#ifdef CONFIG_64BIT
+typedef ssize_t kasan_size_t;
+#else
+typedef int kasan_size_t;
+#endif
+
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
 
 static inline const void *kasan_shadow_to_mem(const void *shadow_addr)
@@ -311,7 +317,7 @@ static __always_inline bool addr_has_metadata(const void *addr)
  * @ret_ip: return address
  * @return: true if access was valid, false if invalid
  */
-bool kasan_check_range(unsigned long addr, size_t size, bool write,
+bool kasan_check_range(const void *addr, size_t size, bool write,
 				unsigned long ret_ip);
 
 #else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
@@ -323,7 +329,7 @@ static __always_inline bool addr_has_metadata(const void *addr)
 
 #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
 
-void *kasan_find_first_bad_addr(void *addr, size_t size);
+const void *kasan_find_first_bad_addr(const void *addr, size_t size);
 size_t kasan_get_alloc_size(void *object, struct kmem_cache *cache);
 void kasan_complete_mode_report_info(struct kasan_report_info *info);
 void kasan_metadata_fetch_row(char *buffer, void *row);
@@ -346,7 +352,7 @@ void kasan_print_aux_stacks(struct kmem_cache *cache, const void *object);
 static inline void kasan_print_aux_stacks(struct kmem_cache *cache, const void *object) { }
 #endif
 
-bool kasan_report(unsigned long addr, size_t size,
+bool kasan_report(const void *addr, size_t size,
 		bool is_write, unsigned long ip);
 void kasan_report_invalid_free(void *object, unsigned long ip, enum kasan_report_type type);
 
@@ -571,82 +577,82 @@ void kasan_restore_multi_shot(bool enabled);
  */
 
 asmlinkage void kasan_unpoison_task_stack_below(const void *watermark);
-void __asan_register_globals(struct kasan_global *globals, size_t size);
-void __asan_unregister_globals(struct kasan_global *globals, size_t size);
+void __asan_register_globals(void *globals, kasan_size_t size);
+void __asan_unregister_globals(void *globals, kasan_size_t size);
 void __asan_handle_no_return(void);
-void __asan_alloca_poison(unsigned long addr, size_t size);
-void __asan_allocas_unpoison(const void *stack_top, const void *stack_bottom);
-
-void __asan_load1(unsigned long addr);
-void __asan_store1(unsigned long addr);
-void __asan_load2(unsigned long addr);
-void __asan_store2(unsigned long addr);
-void __asan_load4(unsigned long addr);
-void __asan_store4(unsigned long addr);
-void __asan_load8(unsigned long addr);
-void __asan_store8(unsigned long addr);
-void __asan_load16(unsigned long addr);
-void __asan_store16(unsigned long addr);
-void __asan_loadN(unsigned long addr, size_t size);
-void __asan_storeN(unsigned long addr, size_t size);
-
-void __asan_load1_noabort(unsigned long addr);
-void __asan_store1_noabort(unsigned long addr);
-void __asan_load2_noabort(unsigned long addr);
-void __asan_store2_noabort(unsigned long addr);
-void __asan_load4_noabort(unsigned long addr);
-void __asan_store4_noabort(unsigned long addr);
-void __asan_load8_noabort(unsigned long addr);
-void __asan_store8_noabort(unsigned long addr);
-void __asan_load16_noabort(unsigned long addr);
-void __asan_store16_noabort(unsigned long addr);
-void __asan_loadN_noabort(unsigned long addr, size_t size);
-void __asan_storeN_noabort(unsigned long addr, size_t size);
-
-void __asan_report_load1_noabort(unsigned long addr);
-void __asan_report_store1_noabort(unsigned long addr);
-void __asan_report_load2_noabort(unsigned long addr);
-void __asan_report_store2_noabort(unsigned long addr);
-void __asan_report_load4_noabort(unsigned long addr);
-void __asan_report_store4_noabort(unsigned long addr);
-void __asan_report_load8_noabort(unsigned long addr);
-void __asan_report_store8_noabort(unsigned long addr);
-void __asan_report_load16_noabort(unsigned long addr);
-void __asan_report_store16_noabort(unsigned long addr);
-void __asan_report_load_n_noabort(unsigned long addr, size_t size);
-void __asan_report_store_n_noabort(unsigned long addr, size_t size);
-
-void __asan_set_shadow_00(const void *addr, size_t size);
-void __asan_set_shadow_f1(const void *addr, size_t size);
-void __asan_set_shadow_f2(const void *addr, size_t size);
-void __asan_set_shadow_f3(const void *addr, size_t size);
-void __asan_set_shadow_f5(const void *addr, size_t size);
-void __asan_set_shadow_f8(const void *addr, size_t size);
-
-void *__asan_memset(void *addr, int c, size_t len);
-void *__asan_memmove(void *dest, const void *src, size_t len);
-void *__asan_memcpy(void *dest, const void *src, size_t len);
-
-void __hwasan_load1_noabort(unsigned long addr);
-void __hwasan_store1_noabort(unsigned long addr);
-void __hwasan_load2_noabort(unsigned long addr);
-void __hwasan_store2_noabort(unsigned long addr);
-void __hwasan_load4_noabort(unsigned long addr);
-void __hwasan_store4_noabort(unsigned long addr);
-void __hwasan_load8_noabort(unsigned long addr);
-void __hwasan_store8_noabort(unsigned long addr);
-void __hwasan_load16_noabort(unsigned long addr);
-void __hwasan_store16_noabort(unsigned long addr);
-void __hwasan_loadN_noabort(unsigned long addr, size_t size);
-void __hwasan_storeN_noabort(unsigned long addr, size_t size);
-
-void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size);
-
-void *__hwasan_memset(void *addr, int c, size_t len);
-void *__hwasan_memmove(void *dest, const void *src, size_t len);
-void *__hwasan_memcpy(void *dest, const void *src, size_t len);
-
-void kasan_tag_mismatch(unsigned long addr, unsigned long access_info,
+void __asan_alloca_poison(void *, kasan_size_t size);
+void __asan_allocas_unpoison(void *stack_top, kasan_size_t stack_bottom);
+
+void __asan_load1(void *);
+void __asan_store1(void *);
+void __asan_load2(void *);
+void __asan_store2(void *);
+void __asan_load4(void *);
+void __asan_store4(void *);
+void __asan_load8(void *);
+void __asan_store8(void *);
+void __asan_load16(void *);
+void __asan_store16(void *);
+void __asan_loadN(void *, kasan_size_t size);
+void __asan_storeN(void *, kasan_size_t size);
+
+void __asan_load1_noabort(void *);
+void __asan_store1_noabort(void *);
+void __asan_load2_noabort(void *);
+void __asan_store2_noabort(void *);
+void __asan_load4_noabort(void *);
+void __asan_store4_noabort(void *);
+void __asan_load8_noabort(void *);
+void __asan_store8_noabort(void *);
+void __asan_load16_noabort(void *);
+void __asan_store16_noabort(void *);
+void __asan_loadN_noabort(void *, kasan_size_t size);
+void __asan_storeN_noabort(void *, kasan_size_t size);
+
+void __asan_report_load1_noabort(void *);
+void __asan_report_store1_noabort(void *);
+void __asan_report_load2_noabort(void *);
+void __asan_report_store2_noabort(void *);
+void __asan_report_load4_noabort(void *);
+void __asan_report_store4_noabort(void *);
+void __asan_report_load8_noabort(void *);
+void __asan_report_store8_noabort(void *);
+void __asan_report_load16_noabort(void *);
+void __asan_report_store16_noabort(void *);
+void __asan_report_load_n_noabort(void *, kasan_size_t size);
+void __asan_report_store_n_noabort(void *, kasan_size_t size);
+
+void __asan_set_shadow_00(const void *addr, kasan_size_t size);
+void __asan_set_shadow_f1(const void *addr, kasan_size_t size);
+void __asan_set_shadow_f2(const void *addr, kasan_size_t size);
+void __asan_set_shadow_f3(const void *addr, kasan_size_t size);
+void __asan_set_shadow_f5(const void *addr, kasan_size_t size);
+void __asan_set_shadow_f8(const void *addr, kasan_size_t size);
+
+void *__asan_memset(void *addr, int c, kasan_size_t len);
+void *__asan_memmove(void *dest, const void *src, kasan_size_t len);
+void *__asan_memcpy(void *dest, const void *src, kasan_size_t len);
+
+void __hwasan_load1_noabort(void *);
+void __hwasan_store1_noabort(void *);
+void __hwasan_load2_noabort(void *);
+void __hwasan_store2_noabort(void *);
+void __hwasan_load4_noabort(void *);
+void __hwasan_store4_noabort(void *);
+void __hwasan_load8_noabort(void *);
+void __hwasan_store8_noabort(void *);
+void __hwasan_load16_noabort(void *);
+void __hwasan_store16_noabort(void *);
+void __hwasan_loadN_noabort(void *, kasan_size_t size);
+void __hwasan_storeN_noabort(void *, kasan_size_t size);
+
+void __hwasan_tag_memory(void *, u8 tag, kasan_size_t size);
+
+void *__hwasan_memset(void *addr, int c, kasan_size_t len);
+void *__hwasan_memmove(void *dest, const void *src, kasan_size_t len);
+void *__hwasan_memcpy(void *dest, const void *src, kasan_size_t len);
+
+void kasan_tag_mismatch(void *addr, unsigned long access_info,
 			unsigned long ret_ip);
 
 #endif /* __MM_KASAN_KASAN_H */
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index 892a9dc9d4d3..84d9f3b37014 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -211,7 +211,7 @@ static void start_report(unsigned long *flags, bool sync)
 	pr_err("==================================================================\n");
 }
 
-static void end_report(unsigned long *flags, void *addr)
+static void end_report(unsigned long *flags, const void *addr)
 {
 	if (addr)
 		trace_error_report_end(ERROR_DETECTOR_KASAN,
@@ -450,8 +450,8 @@ static void print_memory_metadata(const void *addr)
 
 static void print_report(struct kasan_report_info *info)
 {
-	void *addr = kasan_reset_tag(info->access_addr);
-	u8 tag = get_tag(info->access_addr);
+	void *addr = kasan_reset_tag((void *)info->access_addr);
+	u8 tag = get_tag((void *)info->access_addr);
 
 	print_error_description(info);
 	if (addr_has_metadata(addr))
@@ -468,12 +468,12 @@ static void print_report(struct kasan_report_info *info)
 
 static void complete_report_info(struct kasan_report_info *info)
 {
-	void *addr = kasan_reset_tag(info->access_addr);
+	void *addr = kasan_reset_tag((void *)info->access_addr);
 	struct slab *slab;
 
 	if (info->type == KASAN_REPORT_ACCESS)
 		info->first_bad_addr = kasan_find_first_bad_addr(
-					info->access_addr, info->access_size);
+					(void *)info->access_addr, info->access_size);
 	else
 		info->first_bad_addr = addr;
 
@@ -544,11 +544,10 @@ void kasan_report_invalid_free(void *ptr, unsigned long ip, enum kasan_report_ty
  * user_access_save/restore(): kasan_report_invalid_free() cannot be called
  * from a UACCESS region, and kasan_report_async() is not used on x86.
  */
-bool kasan_report(unsigned long addr, size_t size, bool is_write,
+bool kasan_report(const void *addr, size_t size, bool is_write,
 			unsigned long ip)
 {
 	bool ret = true;
-	void *ptr = (void *)addr;
 	unsigned long ua_flags = user_access_save();
 	unsigned long irq_flags;
 	struct kasan_report_info info;
@@ -562,7 +561,7 @@ bool kasan_report(unsigned long addr, size_t size, bool is_write,
 
 	memset(&info, 0, sizeof(info));
 	info.type = KASAN_REPORT_ACCESS;
-	info.access_addr = ptr;
+	info.access_addr = addr;
 	info.access_size = size;
 	info.is_write = is_write;
 	info.ip = ip;
@@ -571,7 +570,7 @@ bool kasan_report(unsigned long addr, size_t size, bool is_write,
 
 	print_report(&info);
 
-	end_report(&irq_flags, ptr);
+	end_report(&irq_flags, (void *)addr);
 
 out:
 	user_access_restore(ua_flags);
diff --git a/mm/kasan/report_generic.c b/mm/kasan/report_generic.c
index 87d39bc0a673..080c73acbfcc 100644
--- a/mm/kasan/report_generic.c
+++ b/mm/kasan/report_generic.c
@@ -30,9 +30,9 @@
 #include "kasan.h"
 #include "../slab.h"
 
-void *kasan_find_first_bad_addr(void *addr, size_t size)
+const void *kasan_find_first_bad_addr(const void *addr, size_t size)
 {
-	void *p = addr;
+	const void *p = addr;
 
 	if (!addr_has_metadata(p))
 		return p;
@@ -362,14 +362,14 @@ void kasan_print_address_stack_frame(const void *addr)
 #endif /* CONFIG_KASAN_STACK */
 
 #define DEFINE_ASAN_REPORT_LOAD(size)                     \
-void __asan_report_load##size##_noabort(unsigned long addr) \
+void __asan_report_load##size##_noabort(void *addr) \
 {                                                         \
 	kasan_report(addr, size, false, _RET_IP_);	  \
 }                                                         \
 EXPORT_SYMBOL(__asan_report_load##size##_noabort)
 
 #define DEFINE_ASAN_REPORT_STORE(size)                     \
-void __asan_report_store##size##_noabort(unsigned long addr) \
+void __asan_report_store##size##_noabort(void *addr) \
 {                                                          \
 	kasan_report(addr, size, true, _RET_IP_);	   \
 }                                                          \
@@ -386,13 +386,13 @@ DEFINE_ASAN_REPORT_STORE(4);
 DEFINE_ASAN_REPORT_STORE(8);
 DEFINE_ASAN_REPORT_STORE(16);
 
-void __asan_report_load_n_noabort(unsigned long addr, size_t size)
+void __asan_report_load_n_noabort(void *addr, kasan_size_t size)
 {
 	kasan_report(addr, size, false, _RET_IP_);
 }
 EXPORT_SYMBOL(__asan_report_load_n_noabort);
 
-void __asan_report_store_n_noabort(unsigned long addr, size_t size)
+void __asan_report_store_n_noabort(void *addr, kasan_size_t size)
 {
 	kasan_report(addr, size, true, _RET_IP_);
 }
diff --git a/mm/kasan/report_hw_tags.c b/mm/kasan/report_hw_tags.c
index 32e80f78de7d..065e1b2fc484 100644
--- a/mm/kasan/report_hw_tags.c
+++ b/mm/kasan/report_hw_tags.c
@@ -15,7 +15,7 @@
 
 #include "kasan.h"
 
-void *kasan_find_first_bad_addr(void *addr, size_t size)
+const void *kasan_find_first_bad_addr(const void *addr, size_t size)
 {
 	/*
 	 * Hardware Tag-Based KASAN only calls this function for normal memory
diff --git a/mm/kasan/report_sw_tags.c b/mm/kasan/report_sw_tags.c
index 8b1f5a73ee6d..689e94f9fe3c 100644
--- a/mm/kasan/report_sw_tags.c
+++ b/mm/kasan/report_sw_tags.c
@@ -30,7 +30,7 @@
 #include "kasan.h"
 #include "../slab.h"
 
-void *kasan_find_first_bad_addr(void *addr, size_t size)
+const void *kasan_find_first_bad_addr(const void *addr, size_t size)
 {
 	u8 tag = get_tag(addr);
 	void *p = kasan_reset_tag(addr);
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index c8b86f3273b5..dccef3e9ad2d 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -28,13 +28,13 @@
 
 bool __kasan_check_read(const volatile void *p, unsigned int size)
 {
-	return kasan_check_range((unsigned long)p, size, false, _RET_IP_);
+	return kasan_check_range((void *)p, size, false, _RET_IP_);
 }
 EXPORT_SYMBOL(__kasan_check_read);
 
 bool __kasan_check_write(const volatile void *p, unsigned int size)
 {
-	return kasan_check_range((unsigned long)p, size, true, _RET_IP_);
+	return kasan_check_range((void *)p, size, true, _RET_IP_);
 }
 EXPORT_SYMBOL(__kasan_check_write);
 
@@ -50,7 +50,7 @@ EXPORT_SYMBOL(__kasan_check_write);
 #undef memset
 void *memset(void *addr, int c, size_t len)
 {
-	if (!kasan_check_range((unsigned long)addr, len, true, _RET_IP_))
+	if (!kasan_check_range(addr, len, true, _RET_IP_))
 		return NULL;
 
 	return __memset(addr, c, len);
@@ -60,8 +60,8 @@ void *memset(void *addr, int c, size_t len)
 #undef memmove
 void *memmove(void *dest, const void *src, size_t len)
 {
-	if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) ||
-	    !kasan_check_range((unsigned long)dest, len, true, _RET_IP_))
+	if (!kasan_check_range(src, len, false, _RET_IP_) ||
+	    !kasan_check_range(dest, len, true, _RET_IP_))
 		return NULL;
 
 	return __memmove(dest, src, len);
@@ -71,17 +71,17 @@ void *memmove(void *dest, const void *src, size_t len)
 #undef memcpy
 void *memcpy(void *dest, const void *src, size_t len)
 {
-	if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) ||
-	    !kasan_check_range((unsigned long)dest, len, true, _RET_IP_))
+	if (!kasan_check_range(src, len, false, _RET_IP_) ||
+	    !kasan_check_range(dest, len, true, _RET_IP_))
 		return NULL;
 
 	return __memcpy(dest, src, len);
 }
 #endif
 
-void *__asan_memset(void *addr, int c, size_t len)
+void *__asan_memset(void *addr, int c, kasan_size_t len)
 {
-	if (!kasan_check_range((unsigned long)addr, len, true, _RET_IP_))
+	if (!kasan_check_range(addr, len, true, _RET_IP_))
 		return NULL;
 
 	return __memset(addr, c, len);
@@ -89,10 +89,10 @@ void *__asan_memset(void *addr, int c, size_t len)
 EXPORT_SYMBOL(__asan_memset);
 
 #ifdef __HAVE_ARCH_MEMMOVE
-void *__asan_memmove(void *dest, const void *src, size_t len)
+void *__asan_memmove(void *dest, const void *src, kasan_size_t len)
 {
-	if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) ||
-	    !kasan_check_range((unsigned long)dest, len, true, _RET_IP_))
+	if (!kasan_check_range(src, len, false, _RET_IP_) ||
+	    !kasan_check_range(dest, len, true, _RET_IP_))
 		return NULL;
 
 	return __memmove(dest, src, len);
@@ -100,10 +100,10 @@ void *__asan_memmove(void *dest, const void *src, size_t len)
 EXPORT_SYMBOL(__asan_memmove);
 #endif
 
-void *__asan_memcpy(void *dest, const void *src, size_t len)
+void *__asan_memcpy(void *dest, const void *src, kasan_size_t len)
 {
-	if (!kasan_check_range((unsigned long)src, len, false, _RET_IP_) ||
-	    !kasan_check_range((unsigned long)dest, len, true, _RET_IP_))
+	if (!kasan_check_range(src, len, false, _RET_IP_) ||
+	    !kasan_check_range(dest, len, true, _RET_IP_))
 		return NULL;
 
 	return __memcpy(dest, src, len);
@@ -111,13 +111,13 @@ void *__asan_memcpy(void *dest, const void *src, size_t len)
 EXPORT_SYMBOL(__asan_memcpy);
 
 #ifdef CONFIG_KASAN_SW_TAGS
-void *__hwasan_memset(void *addr, int c, size_t len) __alias(__asan_memset);
+void *__hwasan_memset(void *addr, int c, kasan_size_t len) __alias(__asan_memset);
 EXPORT_SYMBOL(__hwasan_memset);
 #ifdef __HAVE_ARCH_MEMMOVE
-void *__hwasan_memmove(void *dest, const void *src, size_t len) __alias(__asan_memmove);
+void *__hwasan_memmove(void *dest, const void *src, kasan_size_t len) __alias(__asan_memmove);
 EXPORT_SYMBOL(__hwasan_memmove);
 #endif
-void *__hwasan_memcpy(void *dest, const void *src, size_t len) __alias(__asan_memcpy);
+void *__hwasan_memcpy(void *dest, const void *src, kasan_size_t len) __alias(__asan_memcpy);
 EXPORT_SYMBOL(__hwasan_memcpy);
 #endif
 
diff --git a/mm/kasan/sw_tags.c b/mm/kasan/sw_tags.c
index 30da65fa02a1..ae8d26beb3a4 100644
--- a/mm/kasan/sw_tags.c
+++ b/mm/kasan/sw_tags.c
@@ -70,8 +70,8 @@ u8 kasan_random_tag(void)
 	return (u8)(state % (KASAN_TAG_MAX + 1));
 }
 
-bool kasan_check_range(unsigned long addr, size_t size, bool write,
-				unsigned long ret_ip)
+bool kasan_check_range(const void *addr, size_t size, bool write,
+			unsigned long ret_ip)
 {
 	u8 tag;
 	u8 *shadow_first, *shadow_last, *shadow;
@@ -133,12 +133,12 @@ bool kasan_byte_accessible(const void *addr)
 }
 
 #define DEFINE_HWASAN_LOAD_STORE(size)					\
-	void __hwasan_load##size##_noabort(unsigned long addr)		\
+	void __hwasan_load##size##_noabort(void *addr)			\
 	{								\
-		kasan_check_range(addr, size, false, _RET_IP_);	\
+		kasan_check_range(addr, size, false, _RET_IP_);		\
 	}								\
 	EXPORT_SYMBOL(__hwasan_load##size##_noabort);			\
-	void __hwasan_store##size##_noabort(unsigned long addr)		\
+	void __hwasan_store##size##_noabort(void *addr)			\
 	{								\
 		kasan_check_range(addr, size, true, _RET_IP_);		\
 	}								\
@@ -150,25 +150,25 @@ DEFINE_HWASAN_LOAD_STORE(4);
 DEFINE_HWASAN_LOAD_STORE(8);
 DEFINE_HWASAN_LOAD_STORE(16);
 
-void __hwasan_loadN_noabort(unsigned long addr, unsigned long size)
+void __hwasan_loadN_noabort(void *addr, kasan_size_t size)
 {
 	kasan_check_range(addr, size, false, _RET_IP_);
 }
 EXPORT_SYMBOL(__hwasan_loadN_noabort);
 
-void __hwasan_storeN_noabort(unsigned long addr, unsigned long size)
+void __hwasan_storeN_noabort(void *addr, kasan_size_t size)
 {
 	kasan_check_range(addr, size, true, _RET_IP_);
 }
 EXPORT_SYMBOL(__hwasan_storeN_noabort);
 
-void __hwasan_tag_memory(unsigned long addr, u8 tag, unsigned long size)
+void __hwasan_tag_memory(void *addr, u8 tag, kasan_size_t size)
 {
-	kasan_poison((void *)addr, size, tag, false);
+	kasan_poison(addr, size, tag, false);
 }
 EXPORT_SYMBOL(__hwasan_tag_memory);
 
-void kasan_tag_mismatch(unsigned long addr, unsigned long access_info,
+void kasan_tag_mismatch(void *addr, unsigned long access_info,
 			unsigned long ret_ip)
 {
 	kasan_report(addr, 1 << (access_info & 0xf), access_info & 0x10,
-- 
2.39.2


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH -next] drm/rockchip: dsi: Use devm_platform_get_and_ioremap_resource()
From: Yang Li @ 2023-04-21  8:13 UTC (permalink / raw)
  To: hjc
  Cc: heiko, airlied, daniel, dri-devel, linux-arm-kernel, linux-kernel,
	Yang Li

Convert platform_get_resource(), devm_ioremap_resource() to a single
call to devm_platform_get_and_ioremap_resource(), as this is exactly
what this function does.

Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 917e79951aac..ab57df7c6eab 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -1351,8 +1351,7 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
 	if (!dsi)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	dsi->base = devm_ioremap_resource(dev, res);
+	dsi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 	if (IS_ERR(dsi->base)) {
 		DRM_DEV_ERROR(dev, "Unable to get dsi registers\n");
 		return PTR_ERR(dsi->base);
-- 
2.20.1.7.g153144c


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH v3 2/3] ARM: dts: Add nvmem node for BCM2711 bootloader public key
From: Tim Gover @ 2023-04-21  7:59 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Ivan T. Ivanov, Srinivas Kandagatla, Rob Herring,
	Krzysztof Kozlowski, Nicolas Saenz Julienne, Florian Fainelli,
	Stefan Wahren, linux-rpi-kernel, linux-arm-kernel, devicetree
In-Reply-To: <d3bbd951-67b0-95a3-8f26-a100d6ed12e6@linaro.org>

On Fri, 21 Apr 2023 at 08:55, Krzysztof Kozlowski
<krzysztof.kozlowski@linaro.org> wrote:
>
> On 20/04/2023 14:29, Ivan T. Ivanov wrote:
> > From: Tim Gover <tim.gover@raspberrypi.com>
> >
> > Make a copy of the bootloader secure-boot public key available to the OS
> > via an nvmem node. The placement information is populated by the
> > Raspberry Pi firmware[1] if a public key is present in the BCM2711
> > bootloader EEPROM.
> >
> > [1] https://www.raspberrypi.com/documentation/computers/configuration.html#nvmem-nodes
> >
> > Signed-off-by: Tim Gover <tim.gover@raspberrypi.com>
> > [iivanov] Added link to documentation.
> > Signed-off-by: Ivan T. Ivanov <iivanov@suse.de>
> > ---
> >  arch/arm/boot/dts/bcm2711-rpi.dtsi | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/bcm2711-rpi.dtsi b/arch/arm/boot/dts/bcm2711-rpi.dtsi
> > index 98817a6675b9..e30fbe84f9c3 100644
> > --- a/arch/arm/boot/dts/bcm2711-rpi.dtsi
> > +++ b/arch/arm/boot/dts/bcm2711-rpi.dtsi
> > @@ -15,6 +15,7 @@ aliases {
> >               ethernet0 = &genet;
> >               pcie0 = &pcie0;
> >               blconfig = &blconfig;
> > +             blpubkey = &blpubkey;
> >       };
> >  };
> >
> > @@ -67,6 +68,19 @@ blconfig: nvram@0 {
> >               no-map;
> >               status = "disabled";
> >       };
> > +
> > +     /*
> > +      * RPi4 will copy the binary public key blob (if present) from the bootloader
> > +      * into memory for use by the OS.
> > +      */
> > +     blpubkey: nvram@1 {
> > +             compatible = "raspberrypi,bootloader-public-key", "nvmem-rmem";
> > +             #address-cells = <1>;
> > +             #size-cells = <1>;
> > +             reg = <0x0 0x0 0x0>;
> > +             no-map;
> > +             status = "disabled";
>
> Why this is disabled? What external resources are missing?
>
> Best regards,
> Krzysztof

These nodes default to disabled because the firmware will not populate
them if the public-key or configuration file are not present.
e.g. There's no requirement to have a bootloader EEPROM on BCM2711.

Tim

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 5/5] arm64: dts: mediatek: cherry-tomato-r1: Enable NVMe PCI-Express port
From: Chen-Yu Tsai @ 2023-04-21  7:59 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: matthias.bgg, robh+dt, krzysztof.kozlowski+dt, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, kernel
In-Reply-To: <20230420094433.42794-6-angelogioacchino.delregno@collabora.com>

On Thu, Apr 20, 2023 at 5:45 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno@collabora.com> wrote:
>
> On Tomato rev1 the PCIe0 controller is used for NVMe storage.

This was slightly confusing for me. AFAIK rev1 is not an actual Tomato
device. It should be the prototype board, which is the original Cherry
reference design by Google [1].

There is an actual Cherry derived device that has NVMe, though it's under
another brand and another name.

ChenYu

[1] Much like Kukui & Jacuzzi (MT8183), and Asurada (MT8192) are the
    reference designs.  I don't think we ever upstream the reference
    boards because they don't really end up in the hands of people
    outside of the project, and the ones we do have tend to be quite
    beaten up or no longer working due to extensive testing.

> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
>  arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
> index 2d5e8f371b6d..11fc83ddf236 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
> @@ -20,6 +20,13 @@ &sound {
>         model = "mt8195_r1019_5682";
>  };
>
> +&pcie0 {
> +       status = "okay";
> +
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&pcie0_pins_default>;
> +};
> +
>  &ts_10 {
>         status = "okay";
>  };
> --
> 2.40.0
>
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH 1/1] ufs: core: fix &hwq->cq_lock deadlock issue
From: Alice Chao @ 2023-04-21  7:56 UTC (permalink / raw)
  To: alim.akhtar, avri.altman, bvanassche, jejb, martin.petersen,
	matthias.bgg, angelogioacchino.delregno, quic_asutoshd, quic_cang,
	mani, linux-scsi, linux-kernel, linux-arm-kernel, linux-mediatek
  Cc: stanley.chu, peter.wang, chun-hung.wu, alice.chao, powen.kao,
	naomi.chu, cc.chou, chaotian.jing, jiajie.hao, tun-yu.yu,
	eddie.huang, wsd_upstream

[name:lockdep&]WARNING: inconsistent lock state
[name:lockdep&]--------------------------------
[name:lockdep&]inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
[name:lockdep&]kworker/u16:4/260 [HC0[0]:SC0[0]:HE1:SE1] takes:
  ffffff8028444600 (&hwq->cq_lock){?.-.}-{2:2}, at:
ufshcd_mcq_poll_cqe_lock+0x30/0xe0
[name:lockdep&]{IN-HARDIRQ-W} state was registered at:
  lock_acquire+0x17c/0x33c
  _raw_spin_lock+0x5c/0x7c
  ufshcd_mcq_poll_cqe_lock+0x30/0xe0
  ufs_mtk_mcq_intr+0x60/0x1bc [ufs_mediatek_mod]
  __handle_irq_event_percpu+0x140/0x3ec
  handle_irq_event+0x50/0xd8
  handle_fasteoi_irq+0x148/0x2b0
  generic_handle_domain_irq+0x4c/0x6c
  gic_handle_irq+0x58/0x134
  call_on_irq_stack+0x40/0x74
  do_interrupt_handler+0x84/0xe4
  el1_interrupt+0x3c/0x78
<snip>

Possible unsafe locking scenario:
       CPU0
       ----
  lock(&hwq->cq_lock);
  <Interrupt>
    lock(&hwq->cq_lock);
  *** DEADLOCK ***
2 locks held by kworker/u16:4/260:

[name:lockdep&]
 stack backtrace:
CPU: 7 PID: 260 Comm: kworker/u16:4 Tainted: G S      W  OE
6.1.17-mainline-android14-2-g277223301adb #1
Workqueue: ufs_eh_wq_0 ufshcd_err_handler

 Call trace:
  dump_backtrace+0x10c/0x160
  show_stack+0x20/0x30
  dump_stack_lvl+0x98/0xd8
  dump_stack+0x20/0x60
  print_usage_bug+0x584/0x76c
  mark_lock_irq+0x488/0x510
  mark_lock+0x1ec/0x25c
  __lock_acquire+0x4d8/0xffc
  lock_acquire+0x17c/0x33c
  _raw_spin_lock+0x5c/0x7c
  ufshcd_mcq_poll_cqe_lock+0x30/0xe0
  ufshcd_poll+0x68/0x1b0
  ufshcd_transfer_req_compl+0x9c/0xc8
  ufshcd_err_handler+0x3bc/0xea0
  process_one_work+0x2f4/0x7e8
  worker_thread+0x234/0x450
  kthread+0x110/0x134
  ret_from_fork+0x10/0x20

ufs_mtk_mcq_intr() could refer to
https://lore.kernel.org/all/20230328103423.10970-3-powen.kao@mediatek.com/

When ufshcd_err_handler() is executed, CQ event interrupt can enter
waiting for the same lock. It could happened in upstream code path
ufshcd_handle_mcq_cq_events() and also in ufs_mtk_mcq_intr(). This
warning message will be generated when &hwq->cq_lock is used in IRQ
context with IRQ enabled. Use ufshcd_mcq_poll_cqe_lock() with
spin_lock_irqsave instead of spin_lock to resolve the deadlock issue.

Signed-off-by: Alice Chao <alice.chao@mediatek.com>
---
 drivers/ufs/core/ufs-mcq.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c
index 31df052fbc41..202ff71e1b58 100644
--- a/drivers/ufs/core/ufs-mcq.c
+++ b/drivers/ufs/core/ufs-mcq.c
@@ -299,11 +299,11 @@ EXPORT_SYMBOL_GPL(ufshcd_mcq_poll_cqe_nolock);
 unsigned long ufshcd_mcq_poll_cqe_lock(struct ufs_hba *hba,
 				       struct ufs_hw_queue *hwq)
 {
-	unsigned long completed_reqs;
+	unsigned long completed_reqs, flags;
 
-	spin_lock(&hwq->cq_lock);
+	spin_lock_irqsave(&hwq->cq_lock, flags);
 	completed_reqs = ufshcd_mcq_poll_cqe_nolock(hba, hwq);
-	spin_unlock(&hwq->cq_lock);
+	spin_unlock_irqrestore(&hwq->cq_lock, flags);
 
 	return completed_reqs;
 }
-- 
2.18.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH v3 1/3] dt-bindings: nvmem: rmem: Add raspberrypi,bootloader-public-key
From: Krzysztof Kozlowski @ 2023-04-21  7:56 UTC (permalink / raw)
  To: Ivan T. Ivanov, Srinivas Kandagatla, Rob Herring,
	Krzysztof Kozlowski
  Cc: Nicolas Saenz Julienne, Florian Fainelli, Stefan Wahren,
	linux-rpi-kernel, linux-arm-kernel, devicetree
In-Reply-To: <20230420122924.37997-2-iivanov@suse.de>

On 20/04/2023 14:29, Ivan T. Ivanov wrote:
> On RPi4 the bootloader[1] will copy the binary public key blob
> (if present) into memory location specified by this node, for
> use by the OS.
> 
> [1] https://www.raspberrypi.com/documentation/computers/configuration.html#nvmem-nodes
> 
> Signed-off-by: Ivan T. Ivanov <iivanov@suse.de>

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Best regards,
Krzysztof


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox