From patchwork Mon Mar 18 11:05:41 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 2291371 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id B54973FCF6 for ; Mon, 18 Mar 2013 13:07:06 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UHZj2-0006iO-3R; Mon, 18 Mar 2013 13:03:40 +0000 Received: from kirsty.vergenet.net ([202.4.237.240]) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UHYDJ-0002jA-Ah for linux-arm-kernel@lists.infradead.org; Mon, 18 Mar 2013 11:27:07 +0000 Received: from ayumi.akashicho.tokyo.vergenet.net (p8120-ipbfp1001kobeminato.hyogo.ocn.ne.jp [118.10.137.120]) by kirsty.vergenet.net (Postfix) with ESMTP id 42B0F267188; Mon, 18 Mar 2013 22:07:28 +1100 (EST) Received: by ayumi.akashicho.tokyo.vergenet.net (Postfix, from userid 7100) id 9036DEDE76B; Mon, 18 Mar 2013 20:07:26 +0900 (JST) From: Simon Horman To: Arnd Bergmann , Olof Johansson Subject: [PATCH 045/142] sh-pfc: Don't modify pinmux_data_reg SoC data Date: Mon, 18 Mar 2013 20:05:41 +0900 Message-Id: <1363604838-29359-46-git-send-email-horms+renesas@verge.net.au> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1363604838-29359-1-git-send-email-horms+renesas@verge.net.au> References: <1363604838-29359-1-git-send-email-horms+renesas@verge.net.au> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130318_072652_589594_EE357D7A X-CRM114-Status: GOOD ( 19.05 ) X-Spam-Score: -5.1 (-----) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-5.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [202.4.237.240 listed in list.dnswl.org] -2.5 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Laurent Pinchart , linux-sh@vger.kernel.org, Linus Walleij , Magnus Damm , arm@kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Laurent Pinchart The pinmux_data_reg structure supplied in SoC data contains information about data registers. It's abused to store per-device mapped iomem and shadow values. Move those fields out of the pinmux_data_reg structure into the per-device sh_pfc_chip structure. Signed-off-by: Laurent Pinchart Acked-by: Linus Walleij --- drivers/pinctrl/sh-pfc/gpio.c | 58 +++++++++++++++++++++++++++------------ drivers/pinctrl/sh-pfc/sh_pfc.h | 2 +- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index b370d28..55eaf75 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -21,11 +21,17 @@ #include "core.h" +struct sh_pfc_gpio_data_reg { + const struct pinmux_data_reg *info; + unsigned long shadow; +}; + struct sh_pfc_chip { struct sh_pfc *pfc; struct gpio_chip gpio_chip; struct sh_pfc_window *mem; + struct sh_pfc_gpio_data_reg *regs; }; static struct sh_pfc_chip *gpio_to_pfc_chip(struct gpio_chip *gc) @@ -38,13 +44,16 @@ static struct sh_pfc *gpio_to_pfc(struct gpio_chip *gc) return gpio_to_pfc_chip(gc)->pfc; } -static void gpio_get_data_reg(struct sh_pfc *pfc, unsigned int gpio, - struct pinmux_data_reg **dr, unsigned int *bit) +static void gpio_get_data_reg(struct sh_pfc_chip *chip, unsigned int gpio, + struct sh_pfc_gpio_data_reg **reg, + unsigned int *bit) { - struct sh_pfc_pin *gpiop = sh_pfc_get_pin(pfc, gpio); + struct sh_pfc_pin *gpiop = sh_pfc_get_pin(chip->pfc, gpio); + unsigned int reg_idx; - *dr = pfc->info->data_regs - + ((gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT); + reg_idx = (gpiop->flags & PINMUX_FLAG_DREG) >> PINMUX_FLAG_DREG_SHIFT; + + *reg = &chip->regs[reg_idx]; *bit = (gpiop->flags & PINMUX_FLAG_DBIT) >> PINMUX_FLAG_DBIT_SHIFT; } @@ -91,7 +100,7 @@ static int gpio_setup_data_regs(struct sh_pfc_chip *chip) { struct sh_pfc *pfc = chip->pfc; unsigned long addr = pfc->info->data_regs[0].reg; - struct pinmux_data_reg *dreg; + const struct pinmux_data_reg *dreg; unsigned int i; /* Find the window that contain the GPIO registers. */ @@ -108,8 +117,21 @@ static int gpio_setup_data_regs(struct sh_pfc_chip *chip) /* GPIO data registers must be in the first memory resource. */ chip->mem = &pfc->window[i]; - for (dreg = pfc->info->data_regs; dreg->reg; ++dreg) - dreg->reg_shadow = gpio_read_data_reg(chip, dreg); + /* Count the number of data registers, allocate memory and initialize + * them. + */ + for (i = 0; pfc->info->data_regs[i].reg_width; ++i) + ; + + chip->regs = devm_kzalloc(pfc->dev, i * sizeof(*chip->regs), + GFP_KERNEL); + if (chip->regs == NULL) + return -ENOMEM; + + for (i = 0, dreg = pfc->info->data_regs; dreg->reg_width; ++i, ++dreg) { + chip->regs[i].info = dreg; + chip->regs[i].shadow = gpio_read_data_reg(chip, dreg); + } for (i = 0; i < pfc->info->nr_pins; i++) { if (pfc->info->pins[i].enum_id == 0) @@ -144,20 +166,20 @@ static void gpio_pin_free(struct gpio_chip *gc, unsigned offset) static void gpio_pin_set_value(struct sh_pfc_chip *chip, unsigned offset, int value) { - struct pinmux_data_reg *dreg; + struct sh_pfc_gpio_data_reg *reg; unsigned long pos; unsigned int bit; - gpio_get_data_reg(chip->pfc, offset, &dreg, &bit); + gpio_get_data_reg(chip, offset, ®, &bit); - pos = dreg->reg_width - (bit + 1); + pos = reg->info->reg_width - (bit + 1); if (value) - set_bit(pos, &dreg->reg_shadow); + set_bit(pos, ®->shadow); else - clear_bit(pos, &dreg->reg_shadow); + clear_bit(pos, ®->shadow); - gpio_write_data_reg(chip, dreg, dreg->reg_shadow); + gpio_write_data_reg(chip, reg->info, reg->shadow); } static int gpio_pin_direction_input(struct gpio_chip *gc, unsigned offset) @@ -176,15 +198,15 @@ static int gpio_pin_direction_output(struct gpio_chip *gc, unsigned offset, static int gpio_pin_get(struct gpio_chip *gc, unsigned offset) { struct sh_pfc_chip *chip = gpio_to_pfc_chip(gc); - struct pinmux_data_reg *dreg; + struct sh_pfc_gpio_data_reg *reg; unsigned long pos; unsigned int bit; - gpio_get_data_reg(chip->pfc, offset, &dreg, &bit); + gpio_get_data_reg(chip, offset, ®, &bit); - pos = dreg->reg_width - (bit + 1); + pos = reg->info->reg_width - (bit + 1); - return (gpio_read_data_reg(chip, dreg) >> pos) & 1; + return (gpio_read_data_reg(chip, reg->info) >> pos) & 1; } static void gpio_pin_set(struct gpio_chip *gc, unsigned offset, int value) diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index ba3697d..e6a51a9 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -108,7 +108,7 @@ struct pinmux_cfg_reg { .enum_ids = (pinmux_enum_t []) struct pinmux_data_reg { - unsigned long reg, reg_width, reg_shadow; + unsigned long reg, reg_width; pinmux_enum_t *enum_ids; };