On Tue, Dec 6, 2016 at 1:41 PM, Andrew Jeffery <andrew@xxxxxxxx> wrote: > The System Control Unit IP block in the Aspeed SoCs is typically where > the pinmux configuration is found, but not always. A number of pins > depend on state in one of LPC Host Control (LHC) or SoC Display > Controller (GFX) IP blocks, so the Aspeed pinmux drivers should have the > means to adjust these as necessary. > > We use syscon to cast a regmap over the GFX and LPC blocks, which is > used as an arbitration layer between the relevant driver and the pinctrl > subsystem. The regmaps are then exposed to the SoC-specific pinctrl > drivers by phandles in the devicetree, and are selected during a mux > request by querying a new 'ip' member in struct aspeed_sig_desc. > > Signed-off-by: Andrew Jeffery <andrew@xxxxxxxx> Reviewed-by: Joel Stanley <joel@xxxxxxxxx> (I think I've reviewed these on the openbmc list; feel free to keep my reviewed-by tag when that's happened). We might need to split the bindings update and the code changes into separate patches so they can go via their respective trees. Cheers, Joel > --- > .../devicetree/bindings/pinctrl/pinctrl-aspeed.txt | 50 ++++++- > drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c | 18 +-- > drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c | 48 ++++-- > drivers/pinctrl/aspeed/pinctrl-aspeed.c | 161 +++++++++++++-------- > drivers/pinctrl/aspeed/pinctrl-aspeed.h | 32 ++-- > 5 files changed, 214 insertions(+), 95 deletions(-) > > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt > index 2ad18c4ea55c..115b0cce6c1c 100644 > --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt > +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-aspeed.txt > @@ -4,12 +4,19 @@ Aspeed Pin Controllers > The Aspeed SoCs vary in functionality inside a generation but have a common mux > device register layout. > > -Required properties: > -- compatible : Should be any one of the following: > - "aspeed,ast2400-pinctrl" > - "aspeed,g4-pinctrl" > - "aspeed,ast2500-pinctrl" > - "aspeed,g5-pinctrl" > +Required properties for g4: > +- compatible : Should be any one of the following: > + "aspeed,ast2400-pinctrl" > + "aspeed,g4-pinctrl" > + > +Required properties for g5: > +- compatible : Should be any one of the following: > + "aspeed,ast2500-pinctrl" > + "aspeed,g5-pinctrl" > + > +- aspeed,external-nodes: A cell of phandles to external controller nodes: > + 0: compatible with "aspeed,ast2500-gfx", "syscon" > + 1: compatible with "aspeed,ast2500-lpchc", "syscon" > > The pin controller node should be a child of a syscon node with the required > property: > @@ -47,7 +54,7 @@ RGMII1 RGMII2 RMII1 RMII2 SD1 SPI1 SPI1DEBUG SPI1PASSTHRU TIMER4 TIMER5 TIMER6 > TIMER7 TIMER8 VGABIOSROM > > > -Examples: > +g4 Example: > > syscon: scu@1e6e2000 { > compatible = "syscon", "simple-mfd"; > @@ -63,5 +70,34 @@ syscon: scu@1e6e2000 { > }; > }; > > +g5 Example: > + > +apb { > + gfx: display@1e6e6000 { > + compatible = "aspeed,ast2500-gfx", "syscon"; > + reg = <0x1e6e6000 0x1000>; > + }; > + > + lpchc: lpchc@1e7890a0 { > + compatible = "aspeed,ast2500-lpchc", "syscon"; > + reg = <0x1e7890a0 0xc4>; > + }; > + > + syscon: scu@1e6e2000 { > + compatible = "syscon", "simple-mfd"; > + reg = <0x1e6e2000 0x1a8>; > + > + pinctrl: pinctrl { > + compatible = "aspeed,g5-pinctrl"; > + aspeed,external-nodes = <&gfx, &lpchc>; > + > + pinctrl_i2c3_default: i2c3_default { > + function = "I2C3"; > + groups = "I2C3"; > + }; > + }; > + }; > +}; > + > Please refer to pinctrl-bindings.txt in this directory for details of the > common pinctrl bindings used by client devices. > diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c > index a21b071ff290..558bd102416c 100644 > --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c > +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c > @@ -292,7 +292,7 @@ SSSF_PIN_DECL(U18, GPIOG7, FLWP, SIG_DESC_SET(SCU84, 7)); > #define UART6_DESC SIG_DESC_SET(SCU90, 7) > #define ROM16_DESC SIG_DESC_SET(SCU90, 6) > #define FLASH_WIDE SIG_DESC_SET(HW_STRAP1, 4) > -#define BOOT_SRC_NOR { HW_STRAP1, GENMASK(1, 0), 0, 0 } > +#define BOOT_SRC_NOR { ASPEED_IP_SCU, HW_STRAP1, GENMASK(1, 0), 0, 0 } > > #define A8 56 > SIG_EXPR_DECL(ROMD8, ROM16, ROM16_DESC); > @@ -418,9 +418,9 @@ FUNC_GROUP_DECL(I2C8, G5, F3); > #define U1 88 > SSSF_PIN_DECL(U1, GPIOL0, NCTS1, SIG_DESC_SET(SCU84, 16)); > > -#define VPI18_DESC { SCU90, GENMASK(5, 4), 1, 0 } > -#define VPI24_DESC { SCU90, GENMASK(5, 4), 2, 0 } > -#define VPI30_DESC { SCU90, GENMASK(5, 4), 3, 0 } > +#define VPI18_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 1, 0 } > +#define VPI24_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 2, 0 } > +#define VPI30_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 3, 0 } > > #define T5 89 > #define T5_DESC SIG_DESC_SET(SCU84, 17) > @@ -641,11 +641,11 @@ SSSF_PIN_DECL(Y22, GPIOR2, ROMCS3, SIG_DESC_SET(SCU88, 26)); > #define U19 139 > SSSF_PIN_DECL(U19, GPIOR3, ROMCS4, SIG_DESC_SET(SCU88, 27)); > > -#define VPOOFF0_DESC { SCU94, GENMASK(1, 0), 0, 0 } > -#define VPO12_DESC { SCU94, GENMASK(1, 0), 1, 0 } > -#define VPO24_DESC { SCU94, GENMASK(1, 0), 2, 0 } > -#define VPOOFF1_DESC { SCU94, GENMASK(1, 0), 3, 0 } > -#define VPO_OFF_12 { SCU94, 0x2, 0, 0 } > +#define VPOOFF0_DESC { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 0, 0 } > +#define VPO12_DESC { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 1, 0 } > +#define VPO24_DESC { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 2, 0 } > +#define VPOOFF1_DESC { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 3, 0 } > +#define VPO_OFF_12 { ASPEED_IP_SCU, SCU94, 0x2, 0, 0 } > #define VPO_24_OFF SIG_DESC_SET(SCU94, 1) > > #define V21 140 > diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c > index 87b46390b695..c5c9a1b6fa1c 100644 > --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c > +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c > @@ -10,6 +10,7 @@ > #include <linux/init.h> > #include <linux/io.h> > #include <linux/kernel.h> > +#include <linux/mfd/syscon.h> > #include <linux/mutex.h> > #include <linux/of.h> > #include <linux/platform_device.h> > @@ -26,8 +27,8 @@ > > #define ASPEED_G5_NR_PINS 228 > > -#define COND1 { SCU90, BIT(6), 0, 0 } > -#define COND2 { SCU94, GENMASK(1, 0), 0, 0 } > +#define COND1 { ASPEED_IP_SCU, SCU90, BIT(6), 0, 0 } > +#define COND2 { ASPEED_IP_SCU, SCU94, GENMASK(1, 0), 0, 0 } > > #define B14 0 > SSSF_PIN_DECL(B14, GPIOA0, MAC1LINK, SIG_DESC_SET(SCU80, 0)); > @@ -186,9 +187,12 @@ MS_PIN_DECL(C20, GPIOE1, NDCD3, GPIE0OUT); > > FUNC_GROUP_DECL(GPIE0, B20, C20); > > -#define SPI1_DESC { HW_STRAP1, GENMASK(13, 12), 1, 0 } > -#define SPI1DEBUG_DESC { HW_STRAP1, GENMASK(13, 12), 2, 0 } > -#define SPI1PASSTHRU_DESC { HW_STRAP1, GENMASK(13, 12), 3, 0 } > +#define SPI1_DESC \ > + { ASPEED_IP_SCU, HW_STRAP1, GENMASK(13, 12), 1, 0 } > +#define SPI1DEBUG_DESC \ > + { ASPEED_IP_SCU, HW_STRAP1, GENMASK(13, 12), 2, 0 } > +#define SPI1PASSTHRU_DESC \ > + { ASPEED_IP_SCU, HW_STRAP1, GENMASK(13, 12), 3, 0 } > > #define C18 64 > SIG_EXPR_DECL(SYSCS, SPI1DEBUG, COND1, SPI1DEBUG_DESC); > @@ -325,10 +329,11 @@ SS_PIN_DECL(R1, GPIOK7, SDA8); > > FUNC_GROUP_DECL(I2C8, P2, R1); > > -#define VPIOFF0_DESC { SCU90, GENMASK(5, 4), 0, 0 } > -#define VPIOFF1_DESC { SCU90, GENMASK(5, 4), 1, 0 } > -#define VPI24_DESC { SCU90, GENMASK(5, 4), 2, 0 } > -#define VPIRSVD_DESC { SCU90, GENMASK(5, 4), 3, 0 } > +#define VPIOFF0_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 0, 0 } > +#define VPIOFF1_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 1, 0 } > +#define VPI24_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 2, 0 } > +#define VPIRSVD_DESC { ASPEED_IP_SCU, SCU90, GENMASK(5, 4), 3, 0 } > + > > #define V2 104 > #define V2_DESC SIG_DESC_SET(SCU88, 0) > @@ -848,10 +853,35 @@ static struct pinctrl_desc aspeed_g5_pinctrl_desc = { > static int aspeed_g5_pinctrl_probe(struct platform_device *pdev) > { > int i; > + struct regmap *map; > + struct device_node *node; > > for (i = 0; i < ARRAY_SIZE(aspeed_g5_pins); i++) > aspeed_g5_pins[i].number = i; > > + node = of_parse_phandle(pdev->dev.of_node, "aspeed,external-nodes", 0); > + map = syscon_node_to_regmap(node); > + of_node_put(node); > + if (IS_ERR(map)) { > + dev_warn(&pdev->dev, "No GFX phandle found, some mux configurations may fail\n"); > + map = NULL; > + } > + aspeed_g5_pinctrl_data.maps[ASPEED_IP_GFX] = map; > + > + node = of_parse_phandle(pdev->dev.of_node, "aspeed,external-nodes", 1); > + if (node) { > + map = syscon_node_to_regmap(node->parent); > + if (IS_ERR(map)) { > + dev_warn(&pdev->dev, "LHC parent is not a syscon, some mux configurations may fail\n"); > + map = NULL; > + } > + } else { > + dev_warn(&pdev->dev, "No LHC phandle found, some mux configurations may fail\n"); > + map = NULL; > + } > + of_node_put(node); > + aspeed_g5_pinctrl_data.maps[ASPEED_IP_LPC] = map; > + > return aspeed_pinctrl_probe(pdev, &aspeed_g5_pinctrl_desc, > &aspeed_g5_pinctrl_data); > } > diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c b/drivers/pinctrl/aspeed/pinctrl-aspeed.c > index 49aeba912531..782c5c97f853 100644 > --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.c > +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c > @@ -14,6 +14,12 @@ > #include "../core.h" > #include "pinctrl-aspeed.h" > > +static const char *const aspeed_pinmux_ips[] = { > + [ASPEED_IP_SCU] = "SCU", > + [ASPEED_IP_GFX] = "GFX", > + [ASPEED_IP_LPC] = "LPC", > +}; > + > int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) > { > struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); > @@ -78,7 +84,8 @@ int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev, > static inline void aspeed_sig_desc_print_val( > const struct aspeed_sig_desc *desc, bool enable, u32 rv) > { > - pr_debug("SCU%x[0x%08x]=0x%x, got 0x%x from 0x%08x\n", desc->reg, > + pr_debug("Want %s%X[0x%08X]=0x%X, got 0x%X from 0x%08X\n", > + aspeed_pinmux_ips[desc->ip], desc->reg, > desc->mask, enable ? desc->enable : desc->disable, > (rv & desc->mask) >> __ffs(desc->mask), rv); > } > @@ -88,10 +95,11 @@ static inline void aspeed_sig_desc_print_val( > * > * @desc: The signal descriptor of interest > * @enabled: True to query the enabled state, false to query disabled state > - * @regmap: The SCU regmap instance > + * @regmap: The IP block's regmap instance > * > - * @return True if the descriptor's bitfield is configured to the state > - * selected by @enabled, false otherwise > + * @return 1 if the descriptor's bitfield is configured to the state > + * selected by @enabled, 0 if not, and less than zero if an unrecoverable > + * failure occurred > * > * Evaluation of descriptor state is non-trivial in that it is not a binary > * outcome: The bitfields can be greater than one bit in size and thus can take > @@ -99,14 +107,19 @@ static inline void aspeed_sig_desc_print_val( > * descriptor (typically this means a different function to the one of interest > * is enabled). Thus we must explicitly test for either condition as required. > */ > -static bool aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc, > +static int aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc, > bool enabled, struct regmap *map) > { > + int ret; > unsigned int raw; > u32 want; > > - if (regmap_read(map, desc->reg, &raw) < 0) > - return false; > + if (!map) > + return -ENODEV; > + > + ret = regmap_read(map, desc->reg, &raw); > + if (ret) > + return ret; > > aspeed_sig_desc_print_val(desc, enabled, raw); > want = enabled ? desc->enable : desc->disable; > @@ -119,10 +132,10 @@ static bool aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc, > * > * @expr: An expression controlling the signal for a mux function on a pin > * @enabled: True to query the enabled state, false to query disabled state > - * @regmap: The SCU regmap instance > + * @maps: The list of regmap instances > * > - * @return True if the expression composed by @enabled evaluates true, false > - * otherwise > + * @return 1 if the expression composed by @enabled evaluates true, 0 if not, > + * and less than zero if an unrecoverable failure occurred. > * > * A mux function is enabled or disabled if the function's signal expression > * for each pin in the function's pin group evaluates true for the desired > @@ -135,19 +148,21 @@ static bool 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. > */ > -static bool aspeed_sig_expr_eval(const struct aspeed_sig_expr *expr, > - bool enabled, struct regmap *map) > +static int aspeed_sig_expr_eval(const struct aspeed_sig_expr *expr, > + bool enabled, struct regmap * const *maps) > { > int i; > + int ret; > > for (i = 0; i < expr->ndescs; i++) { > const struct aspeed_sig_desc *desc = &expr->descs[i]; > > - if (!aspeed_sig_desc_eval(desc, enabled, map)) > - return false; > + ret = aspeed_sig_desc_eval(desc, enabled, maps[desc->ip]); > + if (ret <= 0) > + return ret; > } > > - return true; > + return 1; > } > > /** > @@ -158,19 +173,24 @@ static bool aspeed_sig_expr_eval(const struct aspeed_sig_expr *expr, > * configured > * @enable: true to enable an function's signal through a pin's signal > * expression, false to disable the function's signal > - * @map: The SCU's regmap instance for pinmux register access. > + * @maps: The list of regmap instances for pinmux register access. > * > - * @return true if the expression is configured as requested, false otherwise > + * @return 0 if the expression is configured as requested and a negative error > + * code otherwise > */ > -static bool aspeed_sig_expr_set(const struct aspeed_sig_expr *expr, > - bool enable, struct regmap *map) > +static int aspeed_sig_expr_set(const struct aspeed_sig_expr *expr, > + bool enable, struct regmap * const *maps) > { > + int ret; > int i; > > for (i = 0; i < expr->ndescs; i++) { > - bool ret; > const struct aspeed_sig_desc *desc = &expr->descs[i]; > u32 pattern = enable ? desc->enable : desc->disable; > + u32 val = (pattern << __ffs(desc->mask)); > + > + if (!maps[desc->ip]) > + return -ENODEV; > > /* > * Strap registers are configured in hardware or by early-boot > @@ -179,64 +199,79 @@ static bool aspeed_sig_expr_set(const struct aspeed_sig_expr *expr, > * deconfigured and is the reason we re-evaluate after writing > * all descriptor bits. > */ > - if (desc->reg == HW_STRAP1 || desc->reg == HW_STRAP2) > + if ((desc->reg == HW_STRAP1 || desc->reg == HW_STRAP2) && > + desc->ip == ASPEED_IP_SCU) > continue; > > - ret = regmap_update_bits(map, desc->reg, desc->mask, > - pattern << __ffs(desc->mask)) == 0; > + ret = regmap_update_bits(maps[desc->ip], desc->reg, > + desc->mask, val); > > - if (!ret) > + if (ret) > return ret; > } > > - return aspeed_sig_expr_eval(expr, enable, map); > + ret = aspeed_sig_expr_eval(expr, enable, maps); > + if (ret < 0) > + return ret; > + > + if (!ret) > + return -EPERM; > + > + return 0; > } > > -static bool aspeed_sig_expr_enable(const struct aspeed_sig_expr *expr, > - struct regmap *map) > +static int aspeed_sig_expr_enable(const struct aspeed_sig_expr *expr, > + struct regmap * const *maps) > { > - if (aspeed_sig_expr_eval(expr, true, map)) > - return true; > + int ret; > + > + ret = aspeed_sig_expr_eval(expr, true, maps); > + if (ret < 0) > + return ret; > > - return aspeed_sig_expr_set(expr, true, map); > + if (!ret) > + return aspeed_sig_expr_set(expr, true, maps); > + > + return 0; > } > > -static bool aspeed_sig_expr_disable(const struct aspeed_sig_expr *expr, > - struct regmap *map) > +static int aspeed_sig_expr_disable(const struct aspeed_sig_expr *expr, > + struct regmap * const *maps) > { > - if (!aspeed_sig_expr_eval(expr, true, map)) > - return true; > + int ret; > + > + ret = aspeed_sig_expr_eval(expr, true, maps); > + if (ret < 0) > + return ret; > + > + if (ret) > + return aspeed_sig_expr_set(expr, false, maps); > > - return aspeed_sig_expr_set(expr, false, map); > + return 0; > } > > /** > * Disable a signal on a pin by disabling all provided signal expressions. > * > * @exprs: The list of signal expressions (from a priority level on a pin) > - * @map: The SCU's regmap instance for pinmux register access. > + * @maps: The list of regmap instances for pinmux register access. > * > - * @return true if all expressions in the list are successfully disabled, false > - * otherwise > + * @return 0 if all expressions are disabled, otherwise a negative error code > */ > -static bool aspeed_disable_sig(const struct aspeed_sig_expr **exprs, > - struct regmap *map) > +static int aspeed_disable_sig(const struct aspeed_sig_expr **exprs, > + struct regmap * const *maps) > { > - bool disabled = true; > + int ret = 0; > > if (!exprs) > return true; > > - while (*exprs) { > - bool ret; > - > - ret = aspeed_sig_expr_disable(*exprs, map); > - disabled = disabled && ret; > - > + while (*exprs && !ret) { > + ret = aspeed_sig_expr_disable(*exprs, maps); > exprs++; > } > > - return disabled; > + return ret; > } > > /** > @@ -330,6 +365,7 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, > unsigned int group) > { > int i; > + int ret; > const struct aspeed_pinctrl_data *pdata = > pinctrl_dev_get_drvdata(pctldev); > const struct aspeed_pin_group *pgroup = &pdata->groups[group]; > @@ -343,6 +379,8 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, > const struct aspeed_sig_expr **funcs; > const struct aspeed_sig_expr ***prios; > > + pr_debug("Muxing pin %d for %s\n", pin, pfunc->name); > + > if (!pdesc) > return -EINVAL; > > @@ -358,8 +396,9 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, > if (expr) > break; > > - if (!aspeed_disable_sig(funcs, pdata->map)) > - return -EPERM; > + ret = aspeed_disable_sig(funcs, pdata->maps); > + if (ret) > + return ret; > > prios++; > } > @@ -377,8 +416,9 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, > return -ENXIO; > } > > - if (!aspeed_sig_expr_enable(expr, pdata->map)) > - return -EPERM; > + ret = aspeed_sig_expr_enable(expr, pdata->maps); > + if (ret) > + return ret; > } > > return 0; > @@ -414,6 +454,7 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev, > struct pinctrl_gpio_range *range, > unsigned int offset) > { > + int ret; > const struct aspeed_pinctrl_data *pdata = > pinctrl_dev_get_drvdata(pctldev); > const struct aspeed_pin_desc *pdesc = pdata->pins[offset].drv_data; > @@ -432,8 +473,9 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev, > if (aspeed_gpio_in_exprs(funcs)) > break; > > - if (!aspeed_disable_sig(funcs, pdata->map)) > - return -EPERM; > + ret = aspeed_disable_sig(funcs, pdata->maps); > + if (ret) > + return ret; > > prios++; > } > @@ -462,10 +504,7 @@ int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev, > * If GPIO is not the lowest priority signal type, assume there is only > * one expression defined to enable the GPIO function > */ > - if (!aspeed_sig_expr_enable(expr, pdata->map)) > - return -EPERM; > - > - return 0; > + return aspeed_sig_expr_enable(expr, pdata->maps); > } > > int aspeed_pinctrl_probe(struct platform_device *pdev, > @@ -481,10 +520,10 @@ int aspeed_pinctrl_probe(struct platform_device *pdev, > return -ENODEV; > } > > - pdata->map = syscon_node_to_regmap(parent->of_node); > - if (IS_ERR(pdata->map)) { > + pdata->maps[ASPEED_IP_SCU] = syscon_node_to_regmap(parent->of_node); > + if (IS_ERR(pdata->maps[ASPEED_IP_SCU])) { > dev_err(&pdev->dev, "No regmap for syscon pincontroller parent\n"); > - return PTR_ERR(pdata->map); > + return PTR_ERR(pdata->maps[ASPEED_IP_SCU]); > } > > pctl = pinctrl_register(pdesc, &pdev->dev, pdata); > diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.h b/drivers/pinctrl/aspeed/pinctrl-aspeed.h > index 3e72ef8c54bf..0e93cbf2ff33 100644 > --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.h > +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.h > @@ -232,6 +232,11 @@ > * group. > */ > > +#define ASPEED_IP_SCU 0 > +#define ASPEED_IP_GFX 1 > +#define ASPEED_IP_LPC 2 > +#define ASPEED_NR_PINMUX_IPS 3 > + > /* > * The "Multi-function Pins Mapping and Control" table in the SoC datasheet > * references registers by the device/offset mnemonic. The register macros > @@ -261,7 +266,9 @@ > * A signal descriptor, which describes the register, bits and the > * enable/disable values that should be compared or written. > * > - * @reg: The register offset from base in bytes > + * @ip: The IP block identifier, used as an index into the regmap array in > + * struct aspeed_pinctrl_data > + * @reg: The register offset with respect to the base address of the IP block > * @mask: The mask to apply to the register. The lowest set bit of the mask is > * used to derive the shift value. > * @enable: The value that enables the function. Value should be in the LSBs, > @@ -270,6 +277,7 @@ > * LSBs, not at the position of the mask. > */ > struct aspeed_sig_desc { > + unsigned int ip; > unsigned int reg; > u32 mask; > u32 enable; > @@ -313,24 +321,30 @@ struct aspeed_pin_desc { > > /* Macro hell */ > > +#define SIG_DESC_IP_BIT(ip, reg, idx, val) \ > + { ip, reg, BIT_MASK(idx), val, (((val) + 1) & 1) } > + > /** > - * Short-hand macro for describing a configuration enabled by the state of one > - * bit. The disable value is derived. > + * Short-hand macro for describing an SCU descriptor enabled by the state of > + * one bit. The disable value is derived. > * > * @reg: The signal's associated register, offset from base > * @idx: The signal's bit index in the register > * @val: The value (0 or 1) that enables the function > */ > #define SIG_DESC_BIT(reg, idx, val) \ > - { reg, BIT_MASK(idx), val, (((val) + 1) & 1) } > + SIG_DESC_IP_BIT(ASPEED_IP_SCU, reg, idx, val) > + > +#define SIG_DESC_IP_SET(ip, reg, idx) SIG_DESC_IP_BIT(ip, reg, idx, 1) > > /** > - * A further short-hand macro describing a configuration enabled with a set bit. > + * A further short-hand macro expanding to an SCU descriptor enabled by a set > + * bit. > * > - * @reg: The configuration's associated register, offset from base > - * @idx: The configuration's bit index in the register > + * @reg: The register, offset from base > + * @idx: The bit index in the register > */ > -#define SIG_DESC_SET(reg, idx) SIG_DESC_BIT(reg, idx, 1) > +#define SIG_DESC_SET(reg, idx) SIG_DESC_IP_BIT(ASPEED_IP_SCU, reg, idx, 1) > > #define SIG_DESC_LIST_SYM(sig, func) sig_descs_ ## sig ## _ ## func > #define SIG_DESC_LIST_DECL(sig, func, ...) \ > @@ -500,7 +514,7 @@ struct aspeed_pin_desc { > MS_PIN_DECL_(pin, SIG_EXPR_LIST_PTR(gpio)) > > struct aspeed_pinctrl_data { > - struct regmap *map; > + struct regmap *maps[ASPEED_NR_PINMUX_IPS]; > > const struct pinctrl_pin_desc *pins; > const unsigned int npins; > -- > 2.9.3 > -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html