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. 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, }; -- 2.7.4 -- 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