On 2017-06-21 04:59, Dong Aisheng wrote: > Various IMX platforms may have different imx_pmx_ops.gpio_set_direction > implementations, so let's make it platform specific callbacks instead of > the fixed common one. > > Currently only VF610 platform implements it. No function level changes. Adds an indirection, but I feel this is necessary since we have platform differences how GPIO directions are handled... So: Acked-by: Stefan Agner <stefan@xxxxxxxx> -- Stefan > > Cc: Stefan Agner <stefan@xxxxxxxx> > Cc: Linus Walleij <linus.walleij@xxxxxxxxxx> > Cc: Alexandre Courbot <gnurou@xxxxxxxxx> > Cc: Shawn Guo <shawnguo@xxxxxxxxxx> > Signed-off-by: Dong Aisheng <aisheng.dong@xxxxxxx> > > --- > ChangeLog: > * new patch. > --- > drivers/pinctrl/freescale/pinctrl-imx.c | 48 +++---------------------------- > drivers/pinctrl/freescale/pinctrl-imx.h | 20 +++++++++++++ > drivers/pinctrl/freescale/pinctrl-vf610.c | 25 ++++++++++++++++ > 3 files changed, 49 insertions(+), 44 deletions(-) > > diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c > b/drivers/pinctrl/freescale/pinctrl-imx.c > index 505fe79..ad23e39 100644 > --- a/drivers/pinctrl/freescale/pinctrl-imx.c > +++ b/drivers/pinctrl/freescale/pinctrl-imx.c > @@ -35,18 +35,6 @@ > #define IMX_NO_PAD_CTL 0x80000000 /* no pin config need */ > #define IMX_PAD_SION 0x40000000 /* set SION */ > > -/** > - * @dev: a pointer back to containing device > - * @base: the offset to the controller in virtual memory > - */ > -struct imx_pinctrl { > - struct device *dev; > - struct pinctrl_dev *pctl; > - void __iomem *base; > - void __iomem *input_sel_base; > - struct imx_pinctrl_soc_info *info; > -}; > - > static inline const struct group_desc *imx_pinctrl_find_group_by_name( > struct pinctrl_dev *pctldev, > const char *name) > @@ -255,42 +243,11 @@ static int imx_pmx_set(struct pinctrl_dev > *pctldev, unsigned selector, > return 0; > } > > -static int imx_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, > - struct pinctrl_gpio_range *range, unsigned offset, bool input) > -{ > - struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); > - struct imx_pinctrl_soc_info *info = ipctl->info; > - const struct imx_pin_reg *pin_reg; > - u32 reg; > - > - /* > - * Only Vybrid has the input/output buffer enable flags (IBE/OBE) > - * They are part of the shared mux/conf register. > - */ > - if (!(info->flags & SHARE_MUX_CONF_REG)) > - return 0; > - > - pin_reg = &info->pin_regs[offset]; > - if (pin_reg->mux_reg == -1) > - return -EINVAL; > - > - /* IBE always enabled allows us to read the value "on the wire" */ > - reg = readl(ipctl->base + pin_reg->mux_reg); > - if (input) > - reg &= ~0x2; > - else > - reg |= 0x2; > - writel(reg, ipctl->base + pin_reg->mux_reg); > - > - return 0; > -} > - > -static const struct pinmux_ops imx_pmx_ops = { > +struct pinmux_ops imx_pmx_ops = { > .get_functions_count = pinmux_generic_get_function_count, > .get_function_name = pinmux_generic_get_function_name, > .get_function_groups = pinmux_generic_get_function_groups, > .set_mux = imx_pmx_set, > - .gpio_set_direction = imx_pmx_gpio_set_direction, > }; > > /* decode generic config into raw register values */ > @@ -793,6 +750,9 @@ int imx_pinctrl_probe(struct platform_device *pdev, > imx_pinctrl_desc->custom_params = info->custom_params; > imx_pinctrl_desc->num_custom_params = info->num_custom_params; > > + /* platform specific callback */ > + imx_pmx_ops.gpio_set_direction = info->gpio_set_direction; > + > mutex_init(&info->mutex); > > ipctl->info = info; > diff --git a/drivers/pinctrl/freescale/pinctrl-imx.h > b/drivers/pinctrl/freescale/pinctrl-imx.h > index 880bba7..5aa22b5 100644 > --- a/drivers/pinctrl/freescale/pinctrl-imx.h > +++ b/drivers/pinctrl/freescale/pinctrl-imx.h > @@ -16,9 +16,12 @@ > #define __DRIVERS_PINCTRL_IMX_H > > #include <linux/pinctrl/pinconf-generic.h> > +#include <linux/pinctrl/pinmux.h> > > struct platform_device; > > +extern struct pinmux_ops imx_pmx_ops; > + > /** > * struct imx_pin - describes a single i.MX pin > * @pin: the pin_id of this pin > @@ -76,6 +79,23 @@ struct imx_pinctrl_soc_info { > unsigned int num_decodes; > void (*fixup)(unsigned long *configs, unsigned int num_configs, > u32 *raw_config); > + > + int (*gpio_set_direction)(struct pinctrl_dev *pctldev, > + struct pinctrl_gpio_range *range, > + unsigned offset, > + bool input); > +}; > + > +/** > + * @dev: a pointer back to containing device > + * @base: the offset to the controller in virtual memory > + */ > +struct imx_pinctrl { > + struct device *dev; > + struct pinctrl_dev *pctl; > + void __iomem *base; > + void __iomem *input_sel_base; > + struct imx_pinctrl_soc_info *info; > }; > > #define IMX_CFG_PARAMS_DECODE(p, m, o) \ > diff --git a/drivers/pinctrl/freescale/pinctrl-vf610.c > b/drivers/pinctrl/freescale/pinctrl-vf610.c > index 3bd8556..ac18bb6 100644 > --- a/drivers/pinctrl/freescale/pinctrl-vf610.c > +++ b/drivers/pinctrl/freescale/pinctrl-vf610.c > @@ -295,10 +295,35 @@ static const struct pinctrl_pin_desc > vf610_pinctrl_pads[] = { > IMX_PINCTRL_PIN(VF610_PAD_PTA7), > }; > > +static int vf610_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, > + struct pinctrl_gpio_range *range, > + unsigned offset, bool input) > +{ > + struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); > + struct imx_pinctrl_soc_info *info = ipctl->info; > + const struct imx_pin_reg *pin_reg; > + u32 reg; > + > + pin_reg = &info->pin_regs[offset]; > + if (pin_reg->mux_reg == -1) > + return -EINVAL; > + > + /* IBE always enabled allows us to read the value "on the wire" */ > + reg = readl(ipctl->base + pin_reg->mux_reg); > + if (input) > + reg &= ~0x2; > + else > + reg |= 0x2; > + writel(reg, ipctl->base + pin_reg->mux_reg); > + > + return 0; > +} > + > static struct imx_pinctrl_soc_info vf610_pinctrl_info = { > .pins = vf610_pinctrl_pads, > .npins = ARRAY_SIZE(vf610_pinctrl_pads), > .flags = SHARE_MUX_CONF_REG | ZERO_OFFSET_VALID, > + .gpio_set_direction = vf610_pmx_gpio_set_direction, > .mux_mask = 0x700000, > .mux_shift = 20, > }; -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html