[PATCH] pinctrl: rockchip: Fix Data Abort exception in SPL

Kever Yang kever.yang at rock-chips.com
Thu Jun 29 12:39:15 CEST 2023


On 2023/6/8 18:59, Jonas Karlman wrote:
> Using CONFIG_ARMV8_SPL_EXCEPTION_VECTORS=y and CONFIG_OF_LIVE=y triggers
> a Data Abort exception from unaligned memory access when the pinctrl
> driver iterate node properties, e.g. for UART2 on RK3568.
>
>    setting mux of GPIO0-24 to 1
>    setting mux of GPIO0-24 to 1
>    "Synchronous Abort" handler, esr 0x96000021
>    elr: 000000000000e554 lr : 000000000000e54c
>    x 0: 0000000000000a5c x 1: 0000000000000a5c
>    x 2: 0000000000000007 x 3: 0000000000000065
>    x 4: 0000000000000007 x 5: 0000000000022d4e
>    x 6: 0000000000000a7c x 7: 00000000000227a4
>    x 8: 0000000000021cf0 x 9: 0000000000000a7c
>    x10: 0000000000021cf0 x11: 0000000000021cf0
>    x12: 00000000003fda1c x13: 0000000000000007
>    x14: 00000000003fd9ec x15: 000000000001c0ff
>    x16: 0000000007000000 x17: 00000000fdccd028
>    x18: 00000000003fde20 x19: 0000000000000018
>    x20: 0000000000020670 x21: 0000000000000000
>    x22: 00000000003fdb00 x23: 00000000003fef90
>    x24: 0000000000020688 x25: 0000000000000000
>    x26: 0000000000000001 x27: 00000000003ffc50
>    x28: 0000000000000000 x29: 00000000003fda60
>
>    Code: b94083e1 97ffd508 93407c01 37f81260 (f9401038)
>    Resetting CPU ...
>
> Fix this by replacing the loop to access node properties with use of
> ofnode_for_each_prop instead of the current ifdef.
>
> Also continue to next prop instead of aborting at first sign of an
> unknown property.
>
> This fixes the Data Abort exception and also pinconf of e.g. pull and
> drive in SPL, e.g. for UART2 on RK3568.
>
>    setting mux of GPIO0-24 to 1
>    setting mux of GPIO0-24 to 1
>    setting pull of GPIO0-24 to 5
>    setting mux of GPIO0-25 to 1
>    setting mux of GPIO0-25 to 1
>    setting pull of GPIO0-25 to 5
>
> Fixes: e7ae4cf27a6d ("pinctrl: rockchip: Add common rockchip pinctrl driver")
> Signed-off-by: Jonas Karlman <jonas at kwiboo.se>
Reviewed-by: Kever Yang <kever.yang at rock-chips.com>

Thanks,
- Kever
> ---
>   .../pinctrl/rockchip/pinctrl-rockchip-core.c  | 28 ++++---------------
>   1 file changed, 6 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> index d9d61fdb726a..8ef089994f46 100644
> --- a/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
> @@ -12,7 +12,6 @@
>   #include <fdtdec.h>
>   #include <linux/bitops.h>
>   #include <linux/libfdt.h>
> -#include <asm/global_data.h>
>   
>   #include "pinctrl-rockchip.h"
>   
> @@ -433,13 +432,7 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
>   	int prop_len, param;
>   	const u32 *data;
>   	ofnode node;
> -#ifdef CONFIG_OF_LIVE
> -	const struct device_node *np;
> -	struct property *pp;
> -#else
> -	int property_offset, pcfg_node;
> -	const void *blob = gd->fdt_blob;
> -#endif
> +	struct ofprop prop;
>   	data = dev_read_prop(config, "rockchip,pins", &count);
>   	if (count < 0) {
>   		debug("%s: bad array size %d\n", __func__, count);
> @@ -473,24 +466,15 @@ static int rockchip_pinctrl_set_state(struct udevice *dev,
>   		node = ofnode_get_by_phandle(conf);
>   		if (!ofnode_valid(node))
>   			return -ENODEV;
> -#ifdef CONFIG_OF_LIVE
> -		np = ofnode_to_np(node);
> -		for (pp = np->properties; pp; pp = pp->next) {
> -			prop_name = pp->name;
> -			prop_len = pp->length;
> -			value = pp->value;
> -#else
> -		pcfg_node = ofnode_to_offset(node);
> -		fdt_for_each_property_offset(property_offset, blob, pcfg_node) {
> -			value = fdt_getprop_by_offset(blob, property_offset,
> -						      &prop_name, &prop_len);
> +		ofnode_for_each_prop(prop, node) {
> +			value = ofprop_get_property(&prop, &prop_name, &prop_len);
>   			if (!value)
> -				return -ENOENT;
> -#endif
> +				continue;
> +
>   			param = rockchip_pinconf_prop_name_to_param(prop_name,
>   								    &default_val);
>   			if (param < 0)
> -				break;
> +				continue;
>   
>   			if (prop_len >= sizeof(fdt32_t))
>   				arg = fdt32_to_cpu(*(fdt32_t *)value);


More information about the U-Boot mailing list