From patchwork Fri Jun 30 00:42:19 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timur Tabi X-Patchwork-Id: 9818217 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0B9E9603F2 for ; Fri, 30 Jun 2017 00:43:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EB45628511 for ; Fri, 30 Jun 2017 00:43:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DFB082851D; Fri, 30 Jun 2017 00:43:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 32F3C28511 for ; Fri, 30 Jun 2017 00:43:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=2RW+HOWtxOWUF4Pxm7X7uPQxPTQR0SIatvgS+QrqkPI=; b=qdkh+5bkq4ALMa3fts6T8iTkog o0/Rk2Qn8JdgYAy3rtRjnALJc875uZ7ZApGYDJ0kICE7BCTjBiSDdwpvf0m29jsE57QA/d4tx1x73 Vwif6f7aZaglH9bCJcDdxmqRmXF1d6lFDuVMEF2CJn/jfil62PpJY0YeMdRjwnGToHSc5jYMhLeTX YotjlUTUgTUzJxgTxGXfIJs1+BqcAcFHqy3OxaDldzJt2ffuucAlV26SozyvBfFOojq1E6+KlfO/l 6u2rJUSvj6CUQXGulSxEyWzGAi22esLw9f7M4p9untDaZUzrxxRYoLPTyXUkF8m2/vuHKiio1VWnI LPYFukvg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dQk1X-0000HI-2H; Fri, 30 Jun 2017 00:43:03 +0000 Received: from smtp.codeaurora.org ([198.145.29.96]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dQk1G-00084i-9Q for linux-arm-kernel@lists.infradead.org; Fri, 30 Jun 2017 00:42:48 +0000 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id A31CB60B7F; Fri, 30 Jun 2017 00:42:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1498783346; bh=ecYLJi8bIQzRScrVOkK717i+ywrgFvQAGJK6RlIkTNI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J2eDDSfubPfBwDdGHJcKUstWFxBnNHu4K9xdHZ+PCMvnJY7ltR/A8gvrRsGfgynZ8 Jn0hz11/feu0dHJb9uHxnpO2aijidz1V5UJ1kp02iN+BK27m6ZkwUllssBPMFwYGsP f3hi2TUpiEDGotx5/OusPVdSwhn+QYJ9ytpXZIio= Received: from timur-ubuntu.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: timur@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 31DAD609C3; Fri, 30 Jun 2017 00:42:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1498783345; bh=ecYLJi8bIQzRScrVOkK717i+ywrgFvQAGJK6RlIkTNI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=b1ERS5eMOT/avbREYZjBwzTsB8q0NNWWKkVNwYbPmOK27Zb5XLDl4i2ztUQD20XFw 45T37UjztmK5zOHJyyjf6L8j7v560dMyFmt+2DGfH3Fe/uZ1Rov1ZgNrLNG+1LfWcA p1Q0Jttwqtv7iYSLoTc08MkgG+WTbKOCZUqkdNn8= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 31DAD609C3 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=timur@codeaurora.org From: Timur Tabi To: andy.gross@linaro.org, david.brown@linaro.org, Linus Walleij , Bjorn Andersson , linux-gpio@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 2/2] [v2] pinctrl: qcom: qdf2xxx: expose only some GPIO pins Date: Thu, 29 Jun 2017 19:42:19 -0500 Message-Id: <1498783339-749-2-git-send-email-timur@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1498783339-749-1-git-send-email-timur@codeaurora.org> References: <1498783339-749-1-git-send-email-timur@codeaurora.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170629_174246_394691_566A5D84 X-CRM114-Status: GOOD ( 18.16 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: timur@codeaurora.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP On Qualcomm Technologies QDF2xxx platforms, only a subset of the GPIOs are actually available to the HLOS. The others are blocked by the XPU, and any attempt to access them will cause an XPU violation that halts the system. Instead, the ACPI table now lists only specific GPIOs that are exposed externally as generic GPIO pins. The full list of GPIOs is still registered, but the pin count for the unavailable GPIOs is set to zero. The pinctrl-msm driver will block those unavailable GPIOs from being accessed. Signed-off-by: Timur Tabi --- drivers/pinctrl/qcom/pinctrl-qdf2xxx.c | 112 +++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 39 deletions(-) diff --git a/drivers/pinctrl/qcom/pinctrl-qdf2xxx.c b/drivers/pinctrl/qcom/pinctrl-qdf2xxx.c index bb3ce5c..106e6c1 100644 --- a/drivers/pinctrl/qcom/pinctrl-qdf2xxx.c +++ b/drivers/pinctrl/qcom/pinctrl-qdf2xxx.c @@ -43,68 +43,102 @@ static int qdf2xxx_pinctrl_probe(struct platform_device *pdev) struct pinctrl_pin_desc *pins; struct msm_pingroup *groups; char (*names)[NAME_SIZE]; - unsigned int i; - u32 num_gpios; + unsigned int i, num_gpios, max_gpios; + u32 *gpios; int ret; - /* Query the number of GPIOs from ACPI */ - ret = device_property_read_u32(&pdev->dev, "num-gpios", &num_gpios); + /* The total number of GPIOs that exist */ + ret = device_property_read_u32(&pdev->dev, "num-gpios", &max_gpios); if (ret < 0) { - dev_warn(&pdev->dev, "missing num-gpios property\n"); + dev_err(&pdev->dev, "missing num-gpios property\n"); return ret; } + if (!max_gpios || max_gpios > MAX_GPIOS) { + dev_err(&pdev->dev, "invalid 'num-gpios' property\n"); + return -EINVAL; + } - if (!num_gpios || num_gpios > MAX_GPIOS) { - dev_warn(&pdev->dev, "invalid num-gpios property\n"); + /* The number of GPIOs in the approved list */ + num_gpios = ret = device_property_read_u32_array(&pdev->dev, "gpios", + NULL, 0); + if (ret < 0) { + dev_err(&pdev->dev, + "missing or invalid 'gpios' property (ret=%i)\n", ret); + return ret; + } + if (ret == 0) { + dev_warn(&pdev->dev, "no GPIOs defined\n"); return -ENODEV; } - pins = devm_kcalloc(&pdev->dev, num_gpios, + gpios = devm_kcalloc(&pdev->dev, num_gpios, sizeof(u32), GFP_KERNEL); + if (!gpios) + return -ENOMEM; + + ret = device_property_read_u32_array(&pdev->dev, "gpios", gpios, + num_gpios); + if (ret < 0) { + dev_err(&pdev->dev, + "could not read list of GPIOs (ret=%i)\n", ret); + return ret; + } + + pins = devm_kcalloc(&pdev->dev, max_gpios, sizeof(struct pinctrl_pin_desc), GFP_KERNEL); - groups = devm_kcalloc(&pdev->dev, num_gpios, + groups = devm_kcalloc(&pdev->dev, max_gpios, sizeof(struct msm_pingroup), GFP_KERNEL); names = devm_kcalloc(&pdev->dev, num_gpios, NAME_SIZE, GFP_KERNEL); if (!pins || !groups || !names) return -ENOMEM; - for (i = 0; i < num_gpios; i++) { - snprintf(names[i], NAME_SIZE, "gpio%u", i); - + /* + * Initialize the array. GPIOs not listed in the 'gpios' array + * still need a number and a name, but nothing else. + */ + for (i = 0; i < max_gpios; i++) { pins[i].number = i; - pins[i].name = names[i]; - - groups[i].npins = 1; - groups[i].name = names[i]; groups[i].pins = &pins[i].number; + } - groups[i].ctl_reg = 0x10000 * i; - groups[i].io_reg = 0x04 + 0x10000 * i; - groups[i].intr_cfg_reg = 0x08 + 0x10000 * i; - groups[i].intr_status_reg = 0x0c + 0x10000 * i; - groups[i].intr_target_reg = 0x08 + 0x10000 * i; - - groups[i].mux_bit = 2; - groups[i].pull_bit = 0; - groups[i].drv_bit = 6; - groups[i].oe_bit = 9; - groups[i].in_bit = 0; - groups[i].out_bit = 1; - groups[i].intr_enable_bit = 0; - groups[i].intr_status_bit = 0; - groups[i].intr_target_bit = 5; - groups[i].intr_target_kpss_val = 1; - groups[i].intr_raw_status_bit = 4; - groups[i].intr_polarity_bit = 1; - groups[i].intr_detection_bit = 2; - groups[i].intr_detection_width = 2; + /* Populate the entries that are meant to be exposes as GPIOs. */ + for (i = 0; i < num_gpios; i++) { + unsigned int gpio = gpios[i]; + + groups[gpio].npins = 1; + snprintf(names[i], NAME_SIZE, "gpio%u", gpio); + pins[gpio].name = names[i]; + groups[gpio].name = names[i]; + + groups[gpio].ctl_reg = 0x10000 * gpio; + groups[gpio].io_reg = 0x04 + 0x10000 * gpio; + groups[gpio].intr_cfg_reg = 0x08 + 0x10000 * gpio; + groups[gpio].intr_status_reg = 0x0c + 0x10000 * gpio; + groups[gpio].intr_target_reg = 0x08 + 0x10000 * gpio; + + groups[gpio].mux_bit = 2; + groups[gpio].pull_bit = 0; + groups[gpio].drv_bit = 6; + groups[gpio].oe_bit = 9; + groups[gpio].in_bit = 0; + groups[gpio].out_bit = 1; + groups[gpio].intr_enable_bit = 0; + groups[gpio].intr_status_bit = 0; + groups[gpio].intr_target_bit = 5; + groups[gpio].intr_target_kpss_val = 1; + groups[gpio].intr_raw_status_bit = 4; + groups[gpio].intr_polarity_bit = 1; + groups[gpio].intr_detection_bit = 2; + groups[gpio].intr_detection_width = 2; } + devm_kfree(&pdev->dev, gpios); + qdf2xxx_pinctrl.pins = pins; qdf2xxx_pinctrl.groups = groups; - qdf2xxx_pinctrl.npins = num_gpios; - qdf2xxx_pinctrl.ngroups = num_gpios; - qdf2xxx_pinctrl.ngpios = num_gpios; + qdf2xxx_pinctrl.npins = max_gpios; + qdf2xxx_pinctrl.ngroups = max_gpios; + qdf2xxx_pinctrl.ngpios = max_gpios; return msm_pinctrl_probe(pdev, &qdf2xxx_pinctrl); }