diff options
author | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-03-08 17:43:54 +0100 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> | 2013-03-15 13:33:53 +0100 |
commit | 1a0039dce269317a843d4fc85c4a3430b484bc2d (patch) | |
tree | cb22db8e8b78b04c9ce13891a1685244b1c0cbac /drivers/pinctrl/sh-pfc/pinctrl.c | |
parent | 51cb226b359bc48fed4a92b9bbd9af34640b1be8 (diff) | |
download | blackbird-obmc-linux-1a0039dce269317a843d4fc85c4a3430b484bc2d.tar.gz blackbird-obmc-linux-1a0039dce269317a843d4fc85c4a3430b484bc2d.zip |
sh-pfc: Don't modify sh_pfc_pin SoC data
The sh_pfc_pin structure supplied in SoC data contains information about
pin configuration and name. It's abused to store GPIO data registers
information and pin config type. Move those fields out of the
pinmux_data_reg structure into the new sh_pfc_gpio_pin and
sh_pfc_pin_config structures.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/sh-pfc/pinctrl.c')
-rw-r--r-- | drivers/pinctrl/sh-pfc/pinctrl.c | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 3e49bf0eac25..ef5cf5d8298f 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -25,6 +25,10 @@ #include "core.h" +struct sh_pfc_pin_config { + u32 type; +}; + struct sh_pfc_pinctrl { struct pinctrl_dev *pctl; struct pinctrl_desc pctl_desc; @@ -32,6 +36,7 @@ struct sh_pfc_pinctrl { struct sh_pfc *pfc; struct pinctrl_pin_desc *pins; + struct sh_pfc_pin_config *configs; }; static int sh_pfc_get_groups_count(struct pinctrl_dev *pctldev) @@ -148,30 +153,30 @@ static void sh_pfc_func_disable(struct pinctrl_dev *pctldev, unsigned selector, spin_unlock_irqrestore(&pfc->lock, flags); } -static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, +static int sh_pfc_reconfig_pin(struct sh_pfc_pinctrl *pmx, unsigned offset, int new_type) { - struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset); + struct sh_pfc *pfc = pmx->pfc; + int idx = sh_pfc_get_pin_index(pfc, offset); + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + struct sh_pfc_pin *pin = &pfc->info->pins[idx]; unsigned int mark = pin->enum_id; unsigned long flags; - int pinmux_type; int ret = -EINVAL; spin_lock_irqsave(&pfc->lock, flags); - pinmux_type = pin->flags & PINMUX_FLAG_TYPE; - /* * See if the present config needs to first be de-configured. */ - switch (pinmux_type) { + switch (cfg->type) { case PINMUX_TYPE_GPIO: break; case PINMUX_TYPE_OUTPUT: case PINMUX_TYPE_INPUT: case PINMUX_TYPE_INPUT_PULLUP: case PINMUX_TYPE_INPUT_PULLDOWN: - sh_pfc_config_mux(pfc, mark, pinmux_type, GPIO_CFG_FREE); + sh_pfc_config_mux(pfc, mark, cfg->type, GPIO_CFG_FREE); break; default: goto err; @@ -189,8 +194,7 @@ static int sh_pfc_reconfig_pin(struct sh_pfc *pfc, unsigned offset, if (sh_pfc_config_mux(pfc, mark, new_type, GPIO_CFG_REQ) != 0) goto err; - pin->flags &= ~PINMUX_FLAG_TYPE; - pin->flags |= new_type; + cfg->type = new_type; ret = 0; @@ -206,22 +210,21 @@ static int sh_pfc_gpio_request_enable(struct pinctrl_dev *pctldev, { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; - struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset); + int idx = sh_pfc_get_pin_index(pfc, offset); + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; unsigned long flags; - int ret, pinmux_type; + int ret; spin_lock_irqsave(&pfc->lock, flags); - pinmux_type = pin->flags & PINMUX_FLAG_TYPE; - - switch (pinmux_type) { + switch (cfg->type) { case PINMUX_TYPE_GPIO: case PINMUX_TYPE_INPUT: case PINMUX_TYPE_OUTPUT: break; case PINMUX_TYPE_FUNCTION: default: - pr_err("Unsupported mux type (%d), bailing...\n", pinmux_type); + pr_err("Unsupported mux type (%d), bailing...\n", cfg->type); ret = -ENOTSUPP; goto err; } @@ -240,15 +243,14 @@ static void sh_pfc_gpio_disable_free(struct pinctrl_dev *pctldev, { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; - struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, offset); + int idx = sh_pfc_get_pin_index(pfc, offset); + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; + struct sh_pfc_pin *pin = &pfc->info->pins[idx]; unsigned long flags; - int pinmux_type; spin_lock_irqsave(&pfc->lock, flags); - pinmux_type = pin->flags & PINMUX_FLAG_TYPE; - - sh_pfc_config_mux(pfc, pin->enum_id, pinmux_type, GPIO_CFG_FREE); + sh_pfc_config_mux(pfc, pin->enum_id, cfg->type, GPIO_CFG_FREE); spin_unlock_irqrestore(&pfc->lock, flags); } @@ -260,7 +262,7 @@ static int sh_pfc_gpio_set_direction(struct pinctrl_dev *pctldev, struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); int type = input ? PINMUX_TYPE_INPUT : PINMUX_TYPE_OUTPUT; - return sh_pfc_reconfig_pin(pmx->pfc, offset, type); + return sh_pfc_reconfig_pin(pmx, offset, type); } static const struct pinmux_ops sh_pfc_pinmux_ops = { @@ -279,9 +281,10 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin, { struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); struct sh_pfc *pfc = pmx->pfc; - struct sh_pfc_pin *pin = sh_pfc_get_pin(pfc, _pin); + int idx = sh_pfc_get_pin_index(pfc, _pin); + struct sh_pfc_pin_config *cfg = &pmx->configs[idx]; - *config = pin->flags & PINMUX_FLAG_TYPE; + *config = cfg->type; return 0; } @@ -295,7 +298,7 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, if (config >= PINMUX_FLAG_TYPE) return -EINVAL; - return sh_pfc_reconfig_pin(pmx->pfc, pin, config); + return sh_pfc_reconfig_pin(pmx, pin, config); } static void sh_pfc_pinconf_dbg_show(struct pinctrl_dev *pctldev, @@ -351,17 +354,25 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) if (unlikely(!pmx->pins)) return -ENOMEM; + pmx->configs = devm_kzalloc(pfc->dev, + sizeof(*pmx->configs) * pfc->info->nr_pins, + GFP_KERNEL); + if (unlikely(!pmx->configs)) + return -ENOMEM; + for (i = 0, nr_pins = 0; i < nr_ranges; ++i) { const struct pinmux_range *range = &ranges[i]; unsigned int number; for (number = range->begin; number <= range->end; number++, nr_pins++) { + struct sh_pfc_pin_config *cfg = &pmx->configs[nr_pins]; struct pinctrl_pin_desc *pin = &pmx->pins[nr_pins]; struct sh_pfc_pin *info = &pfc->info->pins[nr_pins]; pin->number = number; pin->name = info->name; + cfg->type = PINMUX_TYPE_GPIO; } } |