From patchwork Tue Nov 7 23:07:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timur Tabi X-Patchwork-Id: 10047361 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 A166360360 for ; Tue, 7 Nov 2017 23:08:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 93FDD29426 for ; Tue, 7 Nov 2017 23:08:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 88DE729AB5; Tue, 7 Nov 2017 23:08:58 +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=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable 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 3001B29426 for ; Tue, 7 Nov 2017 23:08:57 +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=yQSNGmNfO9dD0Svvce3V9WAn8nY6L8d/hSd8OpxzL5U=; b=QFpjV3gTo1qHnIaAucox8EhX4d uN17s0mqbKu9N8y3qn2QTvVB7regk1vyKA69eu/K6kGplgXabeuQuoTHYOC31vHklNvSvpZ8rdgqo xkduBqCaEIsdBPyJ96wd28C8omT9Zum34+FfAsNjdaXR0O8vuF+4mEM+VvQcTwyh18wzlbg8Eq+OS TfkQ4zb0bPTuAdKfhJxwTcwIsb3I9kdVoz2j1nDF0xWk/0f4K1iY9Wny7rf2++IaP8uNWjcdKMn/w Z/i2lPcZiCxNpVKdCPiyOKvknqCqBua0ac8adILGacPjhE9musncvuowtq1ZkkqSVe7eNmxjRa3Dj 8Wm+EaDQ==; 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 1eCCzI-00051I-1K; Tue, 07 Nov 2017 23:08:56 +0000 Received: from smtp.codeaurora.org ([198.145.29.96]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1eCCyR-0003yQ-Ue for linux-arm-kernel@lists.infradead.org; Tue, 07 Nov 2017 23:08:08 +0000 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 76896607CC; Tue, 7 Nov 2017 23:07:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1510096064; bh=R7ndrKGTIktDGV+djdhQcj5WwrpJ8Wbzx7iC9z/6F64=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fZH8S2A6A477fgz7fg8bUA/TDnHdGJp4TbRgEfSFWy5mDN4zr5Pgqn9FpP86WEEbh OpPe2AzKBMeVq27vpr5Oiw8rWi/8t0Z258ta3QD153GRGLB1sOtHC1yUT+nhH/HynG Vn0LmAZfvtN/aGyn/B10t+3m/injY7p2SoD3Wp6g= 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 B18B5607B3; Tue, 7 Nov 2017 23:07:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1510096063; bh=R7ndrKGTIktDGV+djdhQcj5WwrpJ8Wbzx7iC9z/6F64=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A/lZkTsNUtwNfgnJKpMNspgAKAbK7BnC33Rf9/nv6tbNohvu5i8SOY7ROrhxq1yg2 4WuL3XPgDLG1I36BsN8LeM5+FsAq8VdeK7lGuTOztgpZD4WUGGxVDdmrgAUzjCcf/w OoGuEsMszC4fmf+BpPr+MuffZJ9Zwg//Z6XgpA4s= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org B18B5607B3 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: linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, Linus Walleij , Andy Shevchenko , Mika Westerberg , thierry.reding@gmail.com, Stephen Boyd , david.brown@linaro.org, andy.gross@linaro.org, Bjorn Andersson Subject: [PATCH 2/4] gpiolib: add bitmask for valid GPIO lines Date: Tue, 7 Nov 2017 17:07:34 -0600 Message-Id: <1510096056-13765-3-git-send-email-timur@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1510096056-13765-1-git-send-email-timur@codeaurora.org> References: <1510096056-13765-1-git-send-email-timur@codeaurora.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171107_150804_168102_F39204B0 X-CRM114-Status: GOOD ( 16.41 ) 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 Add support for specifying that some GPIOs within a range are unavailable. Some systems have a sparse list of GPIOs, where a range of GPIOs is specified (usually 0 to n-1), but some subset within that range is absent or unavailable for whatever reason. To support this, allow drivers to specify a bitmask of GPIOs that are present or absent. Gpiolib will then block access to those that are absent. Signed-off-by: Timur Tabi --- drivers/gpio/gpiolib.c | 43 +++++++++++++++++++++++++++++++++++-------- include/linux/gpio/driver.h | 2 ++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 60553af4c004..c32387936cdd 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1481,22 +1481,36 @@ static struct gpio_chip *find_chip_by_name(const char *name) static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip) { - if (!gpiochip->irq_need_valid_mask) - return 0; + if (gpiochip->irq_need_valid_mask) { + gpiochip->irq_valid_mask = + kcalloc(BITS_TO_LONGS(gpiochip->ngpio), + sizeof(long), GFP_KERNEL); + if (!gpiochip->irq_valid_mask) + return -ENOMEM; - gpiochip->irq_valid_mask = kcalloc(BITS_TO_LONGS(gpiochip->ngpio), - sizeof(long), GFP_KERNEL); - if (!gpiochip->irq_valid_mask) - return -ENOMEM; + /* Assume by default all GPIOs are valid */ + bitmap_fill(gpiochip->irq_valid_mask, gpiochip->ngpio); + } - /* Assume by default all GPIOs are valid */ - bitmap_fill(gpiochip->irq_valid_mask, gpiochip->ngpio); + if (gpiochip->line_need_valid_mask) { + gpiochip->line_valid_mask = + kcalloc(BITS_TO_LONGS(gpiochip->ngpio), + sizeof(long), GFP_KERNEL); + if (!gpiochip->line_valid_mask) + return -ENOMEM; + + /* Assume by default all GPIOs are valid */ + bitmap_fill(gpiochip->line_valid_mask, gpiochip->ngpio); + } return 0; } static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip) { + kfree(gpiochip->line_valid_mask); + gpiochip->line_valid_mask = NULL; + kfree(gpiochip->irq_valid_mask); gpiochip->irq_valid_mask = NULL; } @@ -1510,6 +1524,15 @@ static bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gpiochip, return test_bit(offset, gpiochip->irq_valid_mask); } +static bool gpiochip_irqchip_line_valid(const struct gpio_chip *gpiochip, + unsigned int offset) +{ + /* No mask means all valid */ + if (likely(!gpiochip->line_valid_mask)) + return true; + return test_bit(offset, gpiochip->line_valid_mask); +} + /** * gpiochip_set_cascaded_irqchip() - connects a cascaded irqchip to a gpiochip * @gpiochip: the gpiochip to set the irqchip chain to @@ -3320,6 +3343,10 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev, return desc; } + /* Make sure the GPIO is valid before we request it. */ + if (!gpiochip_irqchip_line_valid(desc->gdev->chip, idx)) + return ERR_PTR(-EACCES); + status = gpiod_request(desc, con_id); if (status < 0) return ERR_PTR(status); diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 424e5139ff10..853828ccabc8 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -173,6 +173,8 @@ struct gpio_chip { bool irq_nested; bool irq_need_valid_mask; unsigned long *irq_valid_mask; + bool line_need_valid_mask; + unsigned long *line_valid_mask; struct lock_class_key *lock_key; #endif