Skip to content

Commit c143242

Browse files
amboarlinusw
authored andcommitted
pinctrl: aspeed: Fix spurious mux failures on the AST2500
Commit 674fa8d ("pinctrl: aspeed-g5: Delay acquisition of regmaps") was determined to be a partial fix to the problem of acquiring the LPC Host Controller and GFX regmaps: The AST2500 pin controller may need to fetch syscon regmaps during expression evaluation as well as when setting mux state. For example, this case is hit by attempting to export pins exposing the LPC Host Controller as GPIOs. An optional eval() hook is added to the Aspeed pinmux operation struct and called from aspeed_sig_expr_eval() if the pointer is set by the SoC-specific driver. This enables the AST2500 to perform the custom action of acquiring its regmap dependencies as required. John Wang tested the fix on an Inspur FP5280G2 machine (AST2500-based) where the issue was found, and I've booted the fix on Witherspoon (AST2500) and Palmetto (AST2400) machines, and poked at relevant pins under QEMU by forcing mux configurations via devmem before exporting GPIOs to exercise the driver. Fixes: 7d29ed8 ("pinctrl: aspeed: Read and write bits in LPC and GFX controllers") Fixes: 674fa8d ("pinctrl: aspeed-g5: Delay acquisition of regmaps") Reported-by: John Wang <[email protected]> Tested-by: John Wang <[email protected]> Signed-off-by: Andrew Jeffery <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Linus Walleij <[email protected]>
1 parent d45331b commit c143242

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2552,7 +2552,7 @@ static struct regmap *aspeed_g5_acquire_regmap(struct aspeed_pinmux_data *ctx,
25522552
if (IS_ERR(map))
25532553
return map;
25542554
} else
2555-
map = ERR_PTR(-ENODEV);
2555+
return ERR_PTR(-ENODEV);
25562556

25572557
ctx->maps[ASPEED_IP_LPC] = map;
25582558
dev_dbg(ctx->dev, "Acquired LPC regmap");
@@ -2562,6 +2562,33 @@ static struct regmap *aspeed_g5_acquire_regmap(struct aspeed_pinmux_data *ctx,
25622562
return ERR_PTR(-EINVAL);
25632563
}
25642564

2565+
static int aspeed_g5_sig_expr_eval(struct aspeed_pinmux_data *ctx,
2566+
const struct aspeed_sig_expr *expr,
2567+
bool enabled)
2568+
{
2569+
int ret;
2570+
int i;
2571+
2572+
for (i = 0; i < expr->ndescs; i++) {
2573+
const struct aspeed_sig_desc *desc = &expr->descs[i];
2574+
struct regmap *map;
2575+
2576+
map = aspeed_g5_acquire_regmap(ctx, desc->ip);
2577+
if (IS_ERR(map)) {
2578+
dev_err(ctx->dev,
2579+
"Failed to acquire regmap for IP block %d\n",
2580+
desc->ip);
2581+
return PTR_ERR(map);
2582+
}
2583+
2584+
ret = aspeed_sig_desc_eval(desc, enabled, ctx->maps[desc->ip]);
2585+
if (ret <= 0)
2586+
return ret;
2587+
}
2588+
2589+
return 1;
2590+
}
2591+
25652592
/**
25662593
* Configure a pin's signal by applying an expression's descriptor state for
25672594
* all descriptors in the expression.
@@ -2647,6 +2674,7 @@ static int aspeed_g5_sig_expr_set(struct aspeed_pinmux_data *ctx,
26472674
}
26482675

26492676
static const struct aspeed_pinmux_ops aspeed_g5_ops = {
2677+
.eval = aspeed_g5_sig_expr_eval,
26502678
.set = aspeed_g5_sig_expr_set,
26512679
};
26522680

drivers/pinctrl/aspeed/pinmux-aspeed.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,14 @@ int aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,
7878
* neither the enabled nor disabled state. Thus we must explicitly test for
7979
* either condition as required.
8080
*/
81-
int aspeed_sig_expr_eval(const struct aspeed_pinmux_data *ctx,
81+
int aspeed_sig_expr_eval(struct aspeed_pinmux_data *ctx,
8282
const struct aspeed_sig_expr *expr, bool enabled)
8383
{
84-
int i;
8584
int ret;
85+
int i;
86+
87+
if (ctx->ops->eval)
88+
return ctx->ops->eval(ctx, expr, enabled);
8689

8790
for (i = 0; i < expr->ndescs; i++) {
8891
const struct aspeed_sig_desc *desc = &expr->descs[i];

drivers/pinctrl/aspeed/pinmux-aspeed.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,8 @@ struct aspeed_pin_function {
702702
struct aspeed_pinmux_data;
703703

704704
struct aspeed_pinmux_ops {
705+
int (*eval)(struct aspeed_pinmux_data *ctx,
706+
const struct aspeed_sig_expr *expr, bool enabled);
705707
int (*set)(struct aspeed_pinmux_data *ctx,
706708
const struct aspeed_sig_expr *expr, bool enabled);
707709
};
@@ -722,9 +724,8 @@ struct aspeed_pinmux_data {
722724
int aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc, bool enabled,
723725
struct regmap *map);
724726

725-
int aspeed_sig_expr_eval(const struct aspeed_pinmux_data *ctx,
726-
const struct aspeed_sig_expr *expr,
727-
bool enabled);
727+
int aspeed_sig_expr_eval(struct aspeed_pinmux_data *ctx,
728+
const struct aspeed_sig_expr *expr, bool enabled);
728729

729730
static inline int aspeed_sig_expr_set(struct aspeed_pinmux_data *ctx,
730731
const struct aspeed_sig_expr *expr,

0 commit comments

Comments
 (0)