From 43fc9e7fab903ea3c525c693c5e9bf566d521380 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Mon, 18 Mar 2013 22:31:53 +0100 Subject: pinctrl: samsung: Remove hardcoded register offsets This patch replaces statically hardcoded register offsets of Exynos SoCs with an array of register offsets in samsung_pin_bank_type struct. Thanks to this change, support for SoCs with other set and order of registers can be added (e.g. S3C24xx and S3C64xx). Signed-off-by: Tomasz Figa Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-samsung.c | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) (limited to 'drivers/pinctrl/pinctrl-samsung.c') diff --git a/drivers/pinctrl/pinctrl-samsung.c b/drivers/pinctrl/pinctrl-samsung.c index 97dd56024e33..b917ed36fb65 100644 --- a/drivers/pinctrl/pinctrl-samsung.c +++ b/drivers/pinctrl/pinctrl-samsung.c @@ -275,10 +275,6 @@ static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata, *offset = pin - b->pin_base; if (bank) *bank = b; - - /* some banks have two config registers in a single bank */ - if (*offset * b->func_width > BITS_PER_LONG) - *reg += 4; } /* enable or disable a pinmux function */ @@ -310,11 +306,11 @@ static void samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector, spin_lock_irqsave(&bank->slock, flags); - data = readl(reg); + data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]); data &= ~(mask << shift); if (enable) data |= drvdata->pin_groups[group].func << shift; - writel(data, reg); + writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]); spin_unlock_irqrestore(&bank->slock, flags); } @@ -355,7 +351,8 @@ static int samsung_pinmux_gpio_set_direction(struct pinctrl_dev *pctldev, drvdata = pinctrl_dev_get_drvdata(pctldev); pin_offset = offset - bank->pin_base; - reg = drvdata->virt_base + bank->pctl_offset; + reg = drvdata->virt_base + bank->pctl_offset + + type->reg_offset[PINCFG_TYPE_FUNC]; mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1; shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC]; @@ -401,28 +398,11 @@ static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin, &pin_offset, &bank); type = bank->type; - switch (cfg_type) { - case PINCFG_TYPE_PUD: - cfg_reg = PUD_REG; - break; - case PINCFG_TYPE_DRV: - cfg_reg = DRV_REG; - break; - case PINCFG_TYPE_CON_PDN: - cfg_reg = CONPDN_REG; - break; - case PINCFG_TYPE_PUD_PDN: - cfg_reg = PUDPDN_REG; - break; - default: - WARN_ON(1); - return -EINVAL; - } - if (cfg_type >= PINCFG_TYPE_NUM || !type->fld_width[cfg_type]) return -EINVAL; width = type->fld_width[cfg_type]; + cfg_reg = type->reg_offset[cfg_type]; spin_lock_irqsave(&bank->slock, flags); @@ -511,11 +491,11 @@ static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value) spin_lock_irqsave(&bank->slock, flags); - data = readl(reg + DAT_REG); + data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); data &= ~(1 << offset); if (value) data |= 1 << offset; - writel(data, reg + DAT_REG); + writel(data, reg + type->reg_offset[PINCFG_TYPE_DAT]); spin_unlock_irqrestore(&bank->slock, flags); } @@ -526,10 +506,11 @@ static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset) void __iomem *reg; u32 data; struct samsung_pin_bank *bank = gc_to_pin_bank(gc); + struct samsung_pin_bank_type *type = bank->type; reg = bank->drvdata->virt_base + bank->pctl_offset; - data = readl(reg + DAT_REG); + data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]); data >>= offset; data &= 1; return data; -- cgit v1.2.3