From patchwork Wed Nov 20 03:21:11 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Horman X-Patchwork-Id: 3211781 Return-Path: X-Original-To: patchwork-ltsi-dev@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 9AAEDC045B for ; Wed, 20 Nov 2013 08:10:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 356572065E for ; Wed, 20 Nov 2013 08:10:29 +0000 (UTC) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) by mail.kernel.org (Postfix) with ESMTP id 0687F206DC for ; Wed, 20 Nov 2013 08:10:27 +0000 (UTC) Received: from mail.linux-foundation.org (localhost [IPv6:::1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 86CA7E11; Wed, 20 Nov 2013 08:08:22 +0000 (UTC) X-Original-To: ltsi-dev@lists.linuxfoundation.org Delivered-To: ltsi-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTP id 4CF95F0F for ; Wed, 20 Nov 2013 08:07:13 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from kirsty.vergenet.net (kirsty.vergenet.net [202.4.237.240]) by smtp1.linuxfoundation.org (Postfix) with ESMTP id E697D210BD for ; Wed, 20 Nov 2013 08:07:09 +0000 (UTC) Received: from ayumi.isobedori.kobe.vergenet.net (p2020-ipbfp1604kobeminato.hyogo.ocn.ne.jp [114.154.85.20]) by kirsty.vergenet.net (Postfix) with ESMTP id 4615C2673AA; Wed, 20 Nov 2013 14:23:21 +1100 (EST) Received: by ayumi.isobedori.kobe.vergenet.net (Postfix, from userid 7100) id DA81F6CE6CE; Wed, 20 Nov 2013 12:23:19 +0900 (JST) From: Simon Horman To: ltsi-dev@lists.linuxfoundation.org Date: Wed, 20 Nov 2013 12:21:11 +0900 Message-Id: <1384917713-15962-554-git-send-email-horms+renesas@verge.net.au> X-Mailer: git-send-email 1.8.4 In-Reply-To: <1384917713-15962-1-git-send-email-horms+renesas@verge.net.au> References: <1384917713-15962-1-git-send-email-horms+renesas@verge.net.au> X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org Cc: Magnus Damm Subject: [LTSI-dev] [PATCH ltsi-3.10 553/595] sh-pfc: Compute pin ranges automatically X-BeenThere: ltsi-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: "A list to discuss patches, development, and other things related to the LTSI project" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ltsi-dev-bounces@lists.linuxfoundation.org Errors-To: ltsi-dev-bounces@lists.linuxfoundation.org X-Virus-Scanned: ClamAV using ClamSMTP From: Laurent Pinchart Remove the manually specified ranges from PFC SoC data and compute the ranges automatically. This prevents ranges from being out-of-sync with pins definitions. Signed-off-by: Laurent Pinchart Tested-by: Yusuke Goda (cherry picked from commit acac8ed5e2aa2c0d364d06f364fd9ed0dc27d28a) Signed-off-by: Simon Horman --- drivers/pinctrl/sh-pfc/core.c | 70 +++++++++++++++++++++++++++++++----- drivers/pinctrl/sh-pfc/core.h | 8 +++++ drivers/pinctrl/sh-pfc/gpio.c | 21 +++-------- drivers/pinctrl/sh-pfc/pfc-r8a73a4.c | 17 --------- drivers/pinctrl/sh-pfc/pfc-sh73a0.c | 9 ----- drivers/pinctrl/sh-pfc/pinctrl.c | 49 ++++++++----------------- drivers/pinctrl/sh-pfc/sh_pfc.h | 2 -- 7 files changed, 88 insertions(+), 88 deletions(-) diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 96b0224..cb47bce 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -82,17 +82,14 @@ int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin) unsigned int offset; unsigned int i; - if (pfc->info->ranges == NULL) - return pin; - - for (i = 0, offset = 0; i < pfc->info->nr_ranges; ++i) { - const struct pinmux_range *range = &pfc->info->ranges[i]; + for (i = 0, offset = 0; i < pfc->nr_ranges; ++i) { + const struct sh_pfc_pin_range *range = &pfc->ranges[i]; if (pin <= range->end) - return pin >= range->begin - ? offset + pin - range->begin : -1; + return pin >= range->start + ? offset + pin - range->start : -1; - offset += range->end - range->begin + 1; + offset += range->end - range->start + 1; } return -EINVAL; @@ -341,6 +338,59 @@ int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type) return 0; } +static int sh_pfc_init_ranges(struct sh_pfc *pfc) +{ + struct sh_pfc_pin_range *range; + unsigned int nr_ranges; + unsigned int i; + + if (pfc->info->pins[0].pin == (u16)-1) { + /* Pin number -1 denotes that the SoC doesn't report pin numbers + * in its pin arrays yet. Consider the pin numbers range as + * continuous and allocate a single range. + */ + pfc->nr_ranges = 1; + pfc->ranges = devm_kzalloc(pfc->dev, sizeof(*pfc->ranges), + GFP_KERNEL); + if (pfc->ranges == NULL) + return -ENOMEM; + + pfc->ranges->start = 0; + pfc->ranges->end = pfc->info->nr_pins - 1; + pfc->nr_gpio_pins = pfc->info->nr_pins; + + return 0; + } + + /* Count, allocate and fill the ranges. */ + for (i = 1, nr_ranges = 1; i < pfc->info->nr_pins; ++i) { + if (pfc->info->pins[i-1].pin != pfc->info->pins[i].pin - 1) + nr_ranges++; + } + + pfc->nr_ranges = nr_ranges; + pfc->ranges = devm_kzalloc(pfc->dev, sizeof(*pfc->ranges) * nr_ranges, + GFP_KERNEL); + if (pfc->ranges == NULL) + return -ENOMEM; + + range = pfc->ranges; + range->start = pfc->info->pins[0].pin; + + for (i = 1; i < pfc->info->nr_pins; ++i) { + if (pfc->info->pins[i-1].pin != pfc->info->pins[i].pin - 1) { + range->end = pfc->info->pins[i-1].pin; + range++; + range->start = pfc->info->pins[i].pin; + } + } + + range->end = pfc->info->pins[i-1].pin; + pfc->nr_gpio_pins = range->end + 1; + + return 0; +} + #ifdef CONFIG_OF static const struct of_device_id sh_pfc_of_table[] = { #ifdef CONFIG_PINCTRL_PFC_R8A73A4 @@ -431,6 +481,10 @@ static int sh_pfc_probe(struct platform_device *pdev) pinctrl_provide_dummies(); + ret = sh_pfc_init_ranges(pfc); + if (ret < 0) + return ret; + /* * Initialize pinctrl bindings first */ diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index 93963a1..a1b2376 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -25,6 +25,11 @@ struct sh_pfc_window { struct sh_pfc_chip; struct sh_pfc_pinctrl; +struct sh_pfc_pin_range { + u16 start; + u16 end; +}; + struct sh_pfc { struct device *dev; const struct sh_pfc_soc_info *info; @@ -34,6 +39,9 @@ struct sh_pfc { unsigned int num_windows; struct sh_pfc_window *window; + struct sh_pfc_pin_range *ranges; + unsigned int nr_ranges; + unsigned int nr_gpio_pins; struct sh_pfc_chip *gpio; diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 7661be5..78fcb80 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -334,10 +334,7 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *), int sh_pfc_register_gpiochip(struct sh_pfc *pfc) { - const struct pinmux_range *ranges; - struct pinmux_range def_range; struct sh_pfc_chip *chip; - unsigned int nr_ranges; unsigned int i; int ret; @@ -368,23 +365,13 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) pfc->gpio = chip; /* Register the GPIO to pin mappings. */ - if (pfc->info->ranges == NULL) { - def_range.begin = 0; - def_range.end = pfc->info->nr_pins - 1; - ranges = &def_range; - nr_ranges = 1; - } else { - ranges = pfc->info->ranges; - nr_ranges = pfc->info->nr_ranges; - } - - for (i = 0; i < nr_ranges; ++i) { - const struct pinmux_range *range = &ranges[i]; + for (i = 0; i < pfc->nr_ranges; ++i) { + const struct sh_pfc_pin_range *range = &pfc->ranges[i]; ret = gpiochip_add_pin_range(&chip->gpio_chip, dev_name(pfc->dev), - range->begin, range->begin, - range->end - range->begin + 1); + range->start, range->start, + range->end - range->start + 1); if (ret < 0) return ret; } diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c b/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c index 04ecb5e..05d96ae 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c @@ -1398,20 +1398,6 @@ static struct sh_pfc_pin pinmux_pins[] = { R8A73A4_PIN_IO_PU_PD(328), R8A73A4_PIN_IO_PU_PD(329), }; -static const struct pinmux_range pinmux_ranges[] = { - {.begin = 0, .end = 30,}, - {.begin = 32, .end = 40,}, - {.begin = 64, .end = 85,}, - {.begin = 96, .end = 126,}, - {.begin = 128, .end = 134,}, - {.begin = 160, .end = 178,}, - {.begin = 192, .end = 222,}, - {.begin = 224, .end = 250,}, - {.begin = 256, .end = 283,}, - {.begin = 288, .end = 308,}, - {.begin = 320, .end = 329,}, -}; - /* - IRQC ------------------------------------------------------------------- */ #define IRQC_PINS_MUX(pin, irq_mark) \ static const unsigned int irqc_irq##irq_mark##_pins[] = { \ @@ -2756,9 +2742,6 @@ const struct sh_pfc_soc_info r8a73a4_pinmux_info = { .pins = pinmux_pins, .nr_pins = ARRAY_SIZE(pinmux_pins), - .ranges = pinmux_ranges, - .nr_ranges = ARRAY_SIZE(pinmux_ranges), - .groups = pinmux_groups, .nr_groups = ARRAY_SIZE(pinmux_groups), .functions = pinmux_functions, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c index 918bad5..6a26946 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh73a0.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh73a0.c @@ -1446,13 +1446,6 @@ static struct sh_pfc_pin pinmux_pins[] = { SH73A0_PIN_O(309), }; -static const struct pinmux_range pinmux_ranges[] = { - {.begin = 0, .end = 118,}, - {.begin = 128, .end = 164,}, - {.begin = 192, .end = 282,}, - {.begin = 288, .end = 309,}, -}; - /* Pin numbers for pins without a corresponding GPIO port number are computed * from the row and column numbers with a 1000 offset to avoid collisions with * GPIO port numbers. @@ -3895,8 +3888,6 @@ const struct sh_pfc_soc_info sh73a0_pinmux_info = { .pins = pinmux_pins, .nr_pins = ARRAY_SIZE(pinmux_pins), - .ranges = pinmux_ranges, - .nr_ranges = ARRAY_SIZE(pinmux_ranges), .groups = pinmux_groups, .nr_groups = ARRAY_SIZE(pinmux_groups), .functions = pinmux_functions, diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index 314255d..8649ec3 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -587,22 +587,9 @@ static const struct pinconf_ops sh_pfc_pinconf_ops = { /* PFC ranges -> pinctrl pin descs */ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) { - const struct pinmux_range *ranges; - struct pinmux_range def_range; - unsigned int nr_ranges; - unsigned int nr_pins; unsigned int i; - if (pfc->info->ranges == NULL) { - def_range.begin = 0; - def_range.end = pfc->info->nr_pins - 1; - ranges = &def_range; - nr_ranges = 1; - } else { - ranges = pfc->info->ranges; - nr_ranges = pfc->info->nr_ranges; - } - + /* Allocate and initialize the pins and configs arrays. */ pmx->pins = devm_kzalloc(pfc->dev, sizeof(*pmx->pins) * pfc->info->nr_pins, GFP_KERNEL); @@ -615,32 +602,24 @@ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) 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 (i = 0; i < pfc->info->nr_pins; ++i) { + const struct sh_pfc_pin *info = &pfc->info->pins[i]; + struct sh_pfc_pin_config *cfg = &pmx->configs[i]; + struct pinctrl_pin_desc *pin = &pmx->pins[i]; - 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]; - const struct sh_pfc_pin *info = - &pfc->info->pins[nr_pins]; - - pin->number = number; - pin->name = info->name; - cfg->type = PINMUX_TYPE_NONE; - } + /* If the pin number is equal to -1 all pins are considered */ + pin->number = info->pin != (u16)-1 ? info->pin : i; + pin->name = info->name; + cfg->type = PINMUX_TYPE_NONE; } - pfc->nr_gpio_pins = ranges[nr_ranges-1].end + 1; - - return nr_ranges; + return 0; } int sh_pfc_register_pinctrl(struct sh_pfc *pfc) { struct sh_pfc_pinctrl *pmx; - int nr_ranges; + int ret; pmx = devm_kzalloc(pfc->dev, sizeof(*pmx), GFP_KERNEL); if (unlikely(!pmx)) @@ -649,9 +628,9 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) pmx->pfc = pfc; pfc->pinctrl = pmx; - nr_ranges = sh_pfc_map_pins(pfc, pmx); - if (unlikely(nr_ranges < 0)) - return nr_ranges; + ret = sh_pfc_map_pins(pfc, pmx); + if (ret < 0) + return ret; pmx->pctl_desc.name = DRV_NAME; pmx->pctl_desc.owner = THIS_MODULE; diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 839e695..2469b35 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -125,8 +125,6 @@ struct sh_pfc_soc_info { const struct sh_pfc_pin *pins; unsigned int nr_pins; - const struct pinmux_range *ranges; - unsigned int nr_ranges; const struct sh_pfc_pin_group *groups; unsigned int nr_groups; const struct sh_pfc_function *functions;