mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-19 02:54:00 +08:00
pinctrl: aspeed: Fix spurious mux failures on the AST2500
Commit674fa8daa8
("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:7d29ed88ac
("pinctrl: aspeed: Read and write bits in LPC and GFX controllers") Fixes:674fa8daa8
("pinctrl: aspeed-g5: Delay acquisition of regmaps") Reported-by: John Wang <wangzqbj@inspur.com> Tested-by: John Wang <wangzqbj@inspur.com> Signed-off-by: Andrew Jeffery <andrew@aj.id.au> Link: https://lore.kernel.org/r/20190829071738.2523-1-andrew@aj.id.au Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
This commit is contained in:
parent
d45331b00d
commit
c1432423a1
@ -2552,7 +2552,7 @@ static struct regmap *aspeed_g5_acquire_regmap(struct aspeed_pinmux_data *ctx,
|
||||
if (IS_ERR(map))
|
||||
return map;
|
||||
} else
|
||||
map = ERR_PTR(-ENODEV);
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
ctx->maps[ASPEED_IP_LPC] = map;
|
||||
dev_dbg(ctx->dev, "Acquired LPC regmap");
|
||||
@ -2562,6 +2562,33 @@ static struct regmap *aspeed_g5_acquire_regmap(struct aspeed_pinmux_data *ctx,
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
static int aspeed_g5_sig_expr_eval(struct aspeed_pinmux_data *ctx,
|
||||
const struct aspeed_sig_expr *expr,
|
||||
bool enabled)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < expr->ndescs; i++) {
|
||||
const struct aspeed_sig_desc *desc = &expr->descs[i];
|
||||
struct regmap *map;
|
||||
|
||||
map = aspeed_g5_acquire_regmap(ctx, desc->ip);
|
||||
if (IS_ERR(map)) {
|
||||
dev_err(ctx->dev,
|
||||
"Failed to acquire regmap for IP block %d\n",
|
||||
desc->ip);
|
||||
return PTR_ERR(map);
|
||||
}
|
||||
|
||||
ret = aspeed_sig_desc_eval(desc, enabled, ctx->maps[desc->ip]);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a pin's signal by applying an expression's descriptor state for
|
||||
* all descriptors in the expression.
|
||||
@ -2647,6 +2674,7 @@ static int aspeed_g5_sig_expr_set(struct aspeed_pinmux_data *ctx,
|
||||
}
|
||||
|
||||
static const struct aspeed_pinmux_ops aspeed_g5_ops = {
|
||||
.eval = aspeed_g5_sig_expr_eval,
|
||||
.set = aspeed_g5_sig_expr_set,
|
||||
};
|
||||
|
||||
|
@ -78,11 +78,14 @@ int aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,
|
||||
* neither the enabled nor disabled state. Thus we must explicitly test for
|
||||
* either condition as required.
|
||||
*/
|
||||
int aspeed_sig_expr_eval(const struct aspeed_pinmux_data *ctx,
|
||||
int aspeed_sig_expr_eval(struct aspeed_pinmux_data *ctx,
|
||||
const struct aspeed_sig_expr *expr, bool enabled)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (ctx->ops->eval)
|
||||
return ctx->ops->eval(ctx, expr, enabled);
|
||||
|
||||
for (i = 0; i < expr->ndescs; i++) {
|
||||
const struct aspeed_sig_desc *desc = &expr->descs[i];
|
||||
|
@ -702,6 +702,8 @@ struct aspeed_pin_function {
|
||||
struct aspeed_pinmux_data;
|
||||
|
||||
struct aspeed_pinmux_ops {
|
||||
int (*eval)(struct aspeed_pinmux_data *ctx,
|
||||
const struct aspeed_sig_expr *expr, bool enabled);
|
||||
int (*set)(struct aspeed_pinmux_data *ctx,
|
||||
const struct aspeed_sig_expr *expr, bool enabled);
|
||||
};
|
||||
@ -722,9 +724,8 @@ struct aspeed_pinmux_data {
|
||||
int aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc, bool enabled,
|
||||
struct regmap *map);
|
||||
|
||||
int aspeed_sig_expr_eval(const struct aspeed_pinmux_data *ctx,
|
||||
const struct aspeed_sig_expr *expr,
|
||||
bool enabled);
|
||||
int aspeed_sig_expr_eval(struct aspeed_pinmux_data *ctx,
|
||||
const struct aspeed_sig_expr *expr, bool enabled);
|
||||
|
||||
static inline int aspeed_sig_expr_set(struct aspeed_pinmux_data *ctx,
|
||||
const struct aspeed_sig_expr *expr,
|
||||
|
Loading…
Reference in New Issue
Block a user