From patchwork Fri Feb 27 23:39:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergei Shtylyov X-Patchwork-Id: 5904091 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 52F3EBF440 for ; Fri, 27 Feb 2015 23:39:28 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 57B4020340 for ; Fri, 27 Feb 2015 23:39:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 432EA20306 for ; Fri, 27 Feb 2015 23:39:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932197AbbB0XjZ (ORCPT ); Fri, 27 Feb 2015 18:39:25 -0500 Received: from mail-la0-f53.google.com ([209.85.215.53]:41149 "EHLO mail-la0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755341AbbB0XjX (ORCPT ); Fri, 27 Feb 2015 18:39:23 -0500 Received: by labgd6 with SMTP id gd6so20557334lab.8 for ; Fri, 27 Feb 2015 15:39:22 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:organization :user-agent:mime-version:content-transfer-encoding:content-type; bh=W3fWlilojTDYae3IHb+aX+yXKjY99EKq9K0GjhgzCnk=; b=SqnBzKfB/SQQe51K0QUKfq4ePYBr222SlETrjngZH6I4jLEtQwLjQYn0PleE5bzUT0 nH7AUzOuD0114NoTO91FRlh+GXmBoit74NvDxQYvFy61TeJpgN/6a7n3iuW9OSFXlEvo J6try3k0KYkyphrdMTheBRY5nFAICG0LJf/UMC8OYcYEYo6c3jdkAo+w2xldZYCAl7Ak JD/r7AxkGGWJid7m3JTwLDqrUK2egDtJAXwLm5pjijXuPKwY96HzUVgnX2nE5WA8uZwb YR8HCjFTiFZ+Hm1705xvmaOW0ops0gTLrIjkLnsA4hoV7B/42plb/z5jByu1HnBzky8E 8pZw== X-Gm-Message-State: ALoCoQlIQWOQOWRQyVRoPwD47Op+sfThv89ArMwhQNSPSUvtg4O1I97TdnhjT+r30v9QQhNwWHhX X-Received: by 10.112.85.140 with SMTP id h12mr14577140lbz.67.1425080361982; Fri, 27 Feb 2015 15:39:21 -0800 (PST) Received: from wasted.cogentembedded.com (ppp83-237-57-108.pppoe.mtu-net.ru. [83.237.57.108]) by mx.google.com with ESMTPSA id l2sm602118lam.39.2015.02.27.15.39.20 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 27 Feb 2015 15:39:20 -0800 (PST) From: Sergei Shtylyov To: linus.walleij@linaro.org, linux-sh@vger.kernel.org, laurent.pinchart@ideasonboard.com, linux-gpio@vger.kernel.org Subject: [PATCH] sh-pfc: handle pin array holes in sh_pfc_map_pins() Date: Sat, 28 Feb 2015 02:39:19 +0300 Message-ID: <1528110.Mb5xiNU0rc@wasted.cogentembedded.com> Organization: Cogent Embedded Inc. User-Agent: KMail/4.14.4 (Linux/3.18.7-100.fc20.x86_64; KDE/4.14.4; x86_64; ; ) MIME-Version: 1.0 Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The pin array handled by sh_pfc_map_pins() may contain holes representing non- existing pins. We have to first count the valid pins in order to calculate the size of the memory to be allocated, then to skip over the non-existing pins when initializing the allocated arrays, and then to return the number of valid pins from sh_pfc_map_pins() instead of 0 on success. As we have to touch devm_kzalloc() calls anyway, use more fitting devm_kcalloc() instead which additionally checks the array size. And since PINMUX_TYPE_NONE is #define'd as 0, stop re-initializing already zeroed out 'pmx->configs' array. Signed-off-by: Sergei Shtylyov --- The patch is against the 'devel' branch of Linus W.'s 'linux-pinctrl.git' repo. This patch should be applied before my R8A7794 PFC support patch and before Laurent's patches removing non-existent GPIOs for R8A779[01], otherwise they would cause the kernel to hang while booting! drivers/pinctrl/sh-pfc/pinctrl.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-sh" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: linux-pinctrl/drivers/pinctrl/sh-pfc/pinctrl.c =================================================================== --- linux-pinctrl.orig/drivers/pinctrl/sh-pfc/pinctrl.c +++ linux-pinctrl/drivers/pinctrl/sh-pfc/pinctrl.c @@ -571,33 +571,39 @@ static const struct pinconf_ops sh_pfc_p /* PFC ranges -> pinctrl pin descs */ static int sh_pfc_map_pins(struct sh_pfc *pfc, struct sh_pfc_pinctrl *pmx) { - unsigned int i; + const struct sh_pfc_pin *info; + struct pinctrl_pin_desc *pin; + unsigned int i, n; + + /* Count the valid pins. */ + for (i = 0, info = pfc->info->pins, n = 0; + i < pfc->info->nr_pins; i++, info++) { + if (info->enum_id || info->configs) + n++; + } /* Allocate and initialize the pins and configs arrays. */ - pmx->pins = devm_kzalloc(pfc->dev, - sizeof(*pmx->pins) * pfc->info->nr_pins, - GFP_KERNEL); + pmx->pins = devm_kcalloc(pfc->dev, n, sizeof(*pmx->pins), GFP_KERNEL); if (unlikely(!pmx->pins)) return -ENOMEM; - pmx->configs = devm_kzalloc(pfc->dev, - sizeof(*pmx->configs) * pfc->info->nr_pins, + pmx->configs = devm_kcalloc(pfc->dev, n, sizeof(*pmx->configs), GFP_KERNEL); if (unlikely(!pmx->configs)) return -ENOMEM; - 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 (i = 0, info = pfc->info->pins, pin = pmx->pins; + i < pfc->info->nr_pins; i++, info++) { + if (!info->enum_id && !info->configs) + continue; /* 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; + pin++; } - return 0; + return n; } int sh_pfc_register_pinctrl(struct sh_pfc *pfc) @@ -622,7 +628,7 @@ int sh_pfc_register_pinctrl(struct sh_pf pmx->pctl_desc.pmxops = &sh_pfc_pinmux_ops; pmx->pctl_desc.confops = &sh_pfc_pinconf_ops; pmx->pctl_desc.pins = pmx->pins; - pmx->pctl_desc.npins = pfc->info->nr_pins; + pmx->pctl_desc.npins = ret; pmx->pctl = pinctrl_register(&pmx->pctl_desc, pfc->dev, pmx); if (pmx->pctl == NULL)