devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Zhou Wang <wangzhou.bry@gmail.com>
To: Russell King <linux@arm.linux.org.uk>,
	Haojian Zhuang <haojian.zhuang@linaro.org>,
	Wei Xu <xuwei5@hisilicon.com>, Olof Johansson <olof@lixom.net>,
	Kevin Hilman <khilman@linaro.org>, Arnd Bergmann <arnd@arndb.de>,
	Linus Walleij <linus.walleij@linaro.org>,
	Alexandre Courbot <gnurou@gmail.com>,
	liguozhu@hisilicon.com
Cc: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com,
	ijc+devicetree@hellion.org.uk, galak@codeaurora.org,
	atull@altera.com, sebastian.hesselbarth@gmail.com,
	bigeasy@linutronix.de, jamie@jamieiles.com,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-gpio@vger.kernel.org, wangzhou1@hisilicon.com,
	Zhou Wang <wangzhou.bry@gmail.com>
Subject: [PATCH v4 3/4] gpio: Add find GPIO base in increasing order
Date: Fri,  5 Dec 2014 11:38:41 +0800	[thread overview]
Message-ID: <1417750722-14027-4-git-send-email-wangzhou.bry@gmail.com> (raw)
In-Reply-To: <1417750722-14027-1-git-send-email-wangzhou.bry@gmail.com>

In function gpiochip_find_base, base number of a GPIO controller
is found in decreasing order. ARCH_NR_GPIOS is used to define from
which number we begin to search for base number of a GPIO controller.

In fact, ARCH_NR_GPIOS brings us some multiplatform problems, like:
http://www.spinics.net/lists/devicetree/msg60433.html

This patch adds the support to find base number of a GPIO controller
in increasing order. It will assign base number from 0.
A new dts property called gpio-number-forward must be add to the related
GPIO dts nodes if you want it works well.

Signed-off-by: Zhou Wang <wangzhou.bry@gmail.com>
---
 drivers/gpio/gpiolib.c |   63 +++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 54 insertions(+), 9 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index e8e98ca..d5e8e13 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -55,6 +55,15 @@ static DEFINE_MUTEX(gpio_lookup_lock);
 static LIST_HEAD(gpio_lookup_list);
 LIST_HEAD(gpio_chips);
 
+/* check find_base_order to find if prior GPIO controller and current GPIO
+ * controller find base number in different orders. Backward is default.
+ */
+static enum {
+	gpio_number_backward,
+	gpio_number_forward,
+	gpio_order_different,
+} find_base_order;
+
 static inline void desc_set_label(struct gpio_desc *d, const char *label)
 {
 	d->label = label;
@@ -107,18 +116,54 @@ struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc)
 EXPORT_SYMBOL_GPL(gpiod_to_chip);
 
 /* dynamic allocation of GPIOs, e.g. on a hotplugged device */
-static int gpiochip_find_base(int ngpio)
+static int gpiochip_find_base(struct gpio_chip *gpio_chip)
 {
+	int base;
 	struct gpio_chip *chip;
-	int base = ARCH_NR_GPIOS - ngpio;
+	int ngpio = gpio_chip->ngpio;
 
-	list_for_each_entry_reverse(chip, &gpio_chips, list) {
-		/* found a free space? */
-		if (chip->base + chip->ngpio <= base)
-			break;
-		else
+	if (find_base_order == gpio_order_different) {
+		pr_err("%s: stop adding gpio chip\n", __func__);
+		return -EINVAL;
+	}
+
+	if (of_property_read_bool(gpio_chip->dev->of_node,
+	    "gpio-number-forward")) {
+		/* find base in increasing order */
+		base = 0;
+
+		if (!list_empty(&gpio_chips)) {
+			if (find_base_order == gpio_number_backward) {
+				find_base_order = gpio_order_different;
+				pr_err("%s: find base in different order\n",
+					__func__);
+				return -EINVAL;
+			}
+			chip = list_last_entry(&gpio_chips, struct gpio_chip,
+						list);
+			base = chip->base + chip->ngpio;
+		}
+
+		find_base_order = gpio_number_forward;
+	} else {
+		if (find_base_order == gpio_number_forward) {
+			find_base_order = gpio_order_different;
+			pr_err("%s: find base in different order\n", __func__);
+			return -EINVAL;
+		}
+
+		base = ARCH_NR_GPIOS - ngpio;
+
+		list_for_each_entry_reverse(chip, &gpio_chips, list) {
+			/* found a free space? */
+			if (chip->base + chip->ngpio <= base)
+				break;
+			else
 			/* nope, check the space right before the chip */
-			base = chip->base - ngpio;
+				base = chip->base - ngpio;
+		}
+
+		find_base_order = gpio_number_backward;
 	}
 
 	if (gpio_is_valid(base)) {
@@ -236,7 +281,7 @@ int gpiochip_add(struct gpio_chip *chip)
 	spin_lock_irqsave(&gpio_lock, flags);
 
 	if (base < 0) {
-		base = gpiochip_find_base(chip->ngpio);
+		base = gpiochip_find_base(chip);
 		if (base < 0) {
 			status = base;
 			goto unlock;
-- 
1.7.9.5


  parent reply	other threads:[~2014-12-05  3:38 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-05  3:38 [PATCH v4 0/4] ARM: hip04: add GPIO support Zhou Wang
2014-12-05  3:38 ` [PATCH v4 1/4] ARM: hip04: add GPIO configure in hisi_defconfig Zhou Wang
2014-12-05  3:38 ` [PATCH v4 2/4] ARM: dts: hip04: add GPIO pieces Zhou Wang
2014-12-05  3:38 ` Zhou Wang [this message]
2014-12-10  8:51   ` [PATCH v4 3/4] gpio: Add find GPIO base in increasing order Alexandre Courbot
2014-12-15  4:01     ` Zhou Wang
2014-12-17  3:09       ` Alexandre Courbot
2014-12-17 11:13         ` Zhou Wang
2015-01-14  8:13     ` Linus Walleij
2015-01-14  8:17       ` Alexandre Courbot
     [not found]         ` <CAAVeFuJkr9mFwJq0GdbLO7EgbffvD25bjBVdXAFZubq5Sz4MZQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-01-16 15:24           ` Linus Walleij
     [not found]             ` <CACRpkdYeiaWxPeeoJjX6BKDmnk2swKCnGgJCW6p9AZ3fdFVSpQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-01-18  7:04               ` Alexandre Courbot
2014-12-05  3:38 ` [PATCH v4 4/4] Documentation: dt: gpio: Add gpio-number-forward property in snps gpio binding doc Zhou Wang
2014-12-31  8:18   ` Linus Walleij

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1417750722-14027-4-git-send-email-wangzhou.bry@gmail.com \
    --to=wangzhou.bry@gmail.com \
    --cc=arnd@arndb.de \
    --cc=atull@altera.com \
    --cc=bigeasy@linutronix.de \
    --cc=devicetree@vger.kernel.org \
    --cc=galak@codeaurora.org \
    --cc=gnurou@gmail.com \
    --cc=haojian.zhuang@linaro.org \
    --cc=ijc+devicetree@hellion.org.uk \
    --cc=jamie@jamieiles.com \
    --cc=khilman@linaro.org \
    --cc=liguozhu@hisilicon.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=mark.rutland@arm.com \
    --cc=olof@lixom.net \
    --cc=pawel.moll@arm.com \
    --cc=robh+dt@kernel.org \
    --cc=sebastian.hesselbarth@gmail.com \
    --cc=wangzhou1@hisilicon.com \
    --cc=xuwei5@hisilicon.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).