Skip to content

Commit 7aeb353

Browse files
amboarLinus Walleij
authored andcommitted
pinctrl: aspeed: Fix GPIO requests on pass-through banks
Commit 6726fbf ("pinctrl: aspeed: Fix GPI only function problem.") fixes access to GPIO banks T and U on the AST2600. Both banks contain input-only pins and the GPIO pin function is named GPITx and GPIUx respectively. Unfortunately the fix had a negative impact on GPIO banks D and E for the AST2400 and AST2500 where the GPIO pass-through functions take similar "GPI"-style names. The net effect on the older SoCs was that when the GPIO subsystem requested a pin in banks D or E be muxed for GPIO, they were instead muxed for pass-through mode. Mistakenly muxing pass-through mode e.g. breaks booting the host on IBM's Witherspoon (AC922) platform where GPIOE0 is used for FSI. Further exploit the names in the provided expression structure to differentiate pass-through from pin-specific GPIO modes. This follow-up fix gives the expected behaviour for the following tests: Witherspoon BMC (AST2500): 1. Power-on the Witherspoon host 2. Request GPIOD1 be muxed via /sys/class/gpio/export 3. Request GPIOE1 be muxed via /sys/class/gpio/export 4. Request the balls for GPIOs E2 and E3 be muxed as GPIO pass-through ("GPIE2" mode) via a pinctrl hog in the devicetree Rainier BMC (AST2600): 5. Request GPIT0 be muxed via /sys/class/gpio/export 6. Request GPIU0 be muxed via /sys/class/gpio/export Together the tests demonstrate that all three pieces of functionality (general GPIOs via 1, 2 and 3, input-only GPIOs via 5 and 6, pass-through mode via 4) operate as desired across old and new SoCs. Fixes: 9b92f5c ("pinctrl: aspeed: Fix GPI only function problem.") Signed-off-by: Andrew Jeffery <andrew@aj.id.au> Tested-by: Joel Stanley <joel@jms.id.au> Reviewed-by: Joel Stanley <joel@jms.id.au> Cc: Billy Tsai <billy_tsai@aspeedtech.com> Cc: Joel Stanley <joel@jms.id.au> Link: https://lore.kernel.org/r/20201126063337.489927-1-andrew@aj.id.au Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
1 parent 47a0001 commit 7aeb353

2 files changed

Lines changed: 72 additions & 9 deletions

File tree

drivers/pinctrl/aspeed/pinctrl-aspeed.c

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -286,14 +286,76 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function,
286286
static bool aspeed_expr_is_gpio(const struct aspeed_sig_expr *expr)
287287
{
288288
/*
289-
* The signal type is GPIO if the signal name has "GPI" as a prefix.
290-
* strncmp (rather than strcmp) is used to implement the prefix
291-
* requirement.
289+
* We need to differentiate between GPIO and non-GPIO signals to
290+
* implement the gpio_request_enable() interface. For better or worse
291+
* the ASPEED pinctrl driver uses the expression names to determine
292+
* whether an expression will mux a pin for GPIO.
292293
*
293-
* expr->signal might look like "GPIOB1" in the GPIO case.
294-
* expr->signal might look like "GPIT0" in the GPI case.
294+
* Generally we have the following - A GPIO such as B1 has:
295+
*
296+
* - expr->signal set to "GPIOB1"
297+
* - expr->function set to "GPIOB1"
298+
*
299+
* Using this fact we can determine whether the provided expression is
300+
* a GPIO expression by testing the signal name for the string prefix
301+
* "GPIO".
302+
*
303+
* However, some GPIOs are input-only, and the ASPEED datasheets name
304+
* them differently. An input-only GPIO such as T0 has:
305+
*
306+
* - expr->signal set to "GPIT0"
307+
* - expr->function set to "GPIT0"
308+
*
309+
* It's tempting to generalise the prefix test from "GPIO" to "GPI" to
310+
* account for both GPIOs and GPIs, but in doing so we run aground on
311+
* another feature:
312+
*
313+
* Some pins in the ASPEED BMC SoCs have a "pass-through" GPIO
314+
* function where the input state of one pin is replicated as the
315+
* output state of another (as if they were shorted together - a mux
316+
* configuration that is typically enabled by hardware strapping).
317+
* This feature allows the BMC to pass e.g. power button state through
318+
* to the host while the BMC is yet to boot, but take control of the
319+
* button state once the BMC has booted by muxing each pin as a
320+
* separate, pin-specific GPIO.
321+
*
322+
* Conceptually this pass-through mode is a form of GPIO and is named
323+
* as such in the datasheets, e.g. "GPID0". This naming similarity
324+
* trips us up with the simple GPI-prefixed-signal-name scheme
325+
* discussed above, as the pass-through configuration is not what we
326+
* want when muxing a pin as GPIO for the GPIO subsystem.
327+
*
328+
* On e.g. the AST2400, a pass-through function "GPID0" is grouped on
329+
* balls A18 and D16, where we have:
330+
*
331+
* For ball A18:
332+
* - expr->signal set to "GPID0IN"
333+
* - expr->function set to "GPID0"
334+
*
335+
* For ball D16:
336+
* - expr->signal set to "GPID0OUT"
337+
* - expr->function set to "GPID0"
338+
*
339+
* By contrast, the pin-specific GPIO expressions for the same pins are
340+
* as follows:
341+
*
342+
* For ball A18:
343+
* - expr->signal looks like "GPIOD0"
344+
* - expr->function looks like "GPIOD0"
345+
*
346+
* For ball D16:
347+
* - expr->signal looks like "GPIOD1"
348+
* - expr->function looks like "GPIOD1"
349+
*
350+
* Testing both the signal _and_ function names gives us the means
351+
* differentiate the pass-through GPIO pinmux configuration from the
352+
* pin-specific configuration that the GPIO subsystem is after: An
353+
* expression is a pin-specific (non-pass-through) GPIO configuration
354+
* if the signal prefix is "GPI" and the signal name matches the
355+
* function name.
295356
*/
296-
return strncmp(expr->signal, "GPI", 3) == 0;
357+
return !strncmp(expr->signal, "GPI", 3) &&
358+
!strcmp(expr->signal, expr->function);
297359
}
298360

299361
static bool aspeed_gpio_in_exprs(const struct aspeed_sig_expr **exprs)

drivers/pinctrl/aspeed/pinmux-aspeed.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -452,10 +452,11 @@ struct aspeed_sig_desc {
452452
* evaluation of the descriptors.
453453
*
454454
* @signal: The signal name for the priority level on the pin. If the signal
455-
* type is GPIO, then the signal name must begin with the string
456-
* "GPIO", e.g. GPIOA0, GPIOT4 etc.
455+
* type is GPIO, then the signal name must begin with the
456+
* prefix "GPI", e.g. GPIOA0, GPIT0 etc.
457457
* @function: The name of the function the signal participates in for the
458-
* associated expression
458+
* associated expression. For pin-specific GPIO, the function
459+
* name must match the signal name.
459460
* @ndescs: The number of signal descriptors in the expression
460461
* @descs: Pointer to an array of signal descriptors that comprise the
461462
* function expression

0 commit comments

Comments
 (0)