From 499147c9dbceee27c63bf8e6b604aca1737e9e0c Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Mon, 18 Mar 2013 22:31:52 +0100 Subject: pinctrl: samsung: Split pin bank description into two structures This patch splits pin bank description into two structures, one describing bank type (currently only bitfield widths), which can be shared across multiple banks and second containing bank-specific parameters including a pointer to a bank type struct. It is a prerequisite for further patch removing the statically hardcoded register offsets, making it impossible to support SoCs with different set and order of pin control registers. Signed-off-by: Tomasz Figa Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-samsung.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'drivers/pinctrl/pinctrl-samsung.c') diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index 0df613134072..97dd56024e33 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c @@ -300,10 +300,13 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, * pin function number in the config register. */ for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++) { + struct samsung_pin_bank_type *type; + pin_to_reg_bank(drvdata, pins[cnt] - drvdata->ctrl->base, ®, &pin_offset, &bank); - mask = (1 << bank->func_width) - 1; - shift = pin_offset * bank->func_width; + type = bank->type; + mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; + shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC]; spin_lock_irqsave(&bank->slock, flags); @@ -340,6 +343,7 @@ static void samsung_pinmux_disable(struct pinctrl_dev *pctldev, static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset, bool input) { + struct samsung_pin_bank_type *type; struct samsung_pin_bank *bank; struct samsung_pinctrl_drv_data *drvdata; void __iomem *reg; @@ -347,13 +351,14 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, unsigned long flags; bank = gc_to_pin_bank(range->gc); + type = bank->type; drvdata = pinctrl_dev_get_drvdata(pctldev); pin_offset = offset - bank->pin_base; reg = drvdata->virt_base + bank->pctl_offset; - mask = (1 << bank->func_width) - 1; - shift = pin_offset * bank->func_width; + mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; + shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC]; spin_lock_irqsave(&bank->slock, flags); @@ -383,6 +388,7 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, unsigned long *config, bool set) { struct samsung_pinctrl_drv_data *drvdata; + struct samsung_pin_bank_type *type; struct samsung_pin_bank *bank; void __iomem *reg_base; enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config); @@ -393,22 +399,19 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, drvdata = pinctrl_dev_get_drvdata(pctldev); pin_to_reg_bank(drvdata, pin - drvdata->ctrl->base, ®_base, &pin_offset, &bank); + type = bank->type; switch (cfg_type) { case PINCFG_TYPE_PUD: - width = bank->pud_width; cfg_reg = PUD_REG; break; case PINCFG_TYPE_DRV: - width = bank->drv_width; cfg_reg = DRV_REG; break; case PINCFG_TYPE_CON_PDN: - width = bank->conpdn_width; cfg_reg = CONPDN_REG; break; case PINCFG_TYPE_PUD_PDN: - width = bank->pudpdn_width; cfg_reg = PUDPDN_REG; break; default: @@ -416,9 +419,11 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, return -EINVAL; } - if (!width) + if (cfg_type >= PINCFG_TYPE_NUM || !type->fld_width[cfg_type]) return -EINVAL; + width = type->fld_width[cfg_type]; + spin_lock_irqsave(&bank->slock, flags); mask = (1 << width) - 1; @@ -497,6 +502,7 @@ static const struct pinconf_ops samsung_pinconf_ops = { static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) { struct samsung_pin_bank *bank = gc_to_pin_bank(gc); + struct samsung_pin_bank_type *type = bank->type; unsigned long flags; void __iomem *reg; u32 data; -- cgit v1.2.3