From be7c703e5078abb5f39b9ad435c47db2f9c1f0ec Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Tue, 4 Jan 2022 05:22:04 +0100
Subject: [PATCH] Revert "gpio-button-hotplug: convert to gpio descriptor
 (gpiod_) API"

This reverts commit 6fe4b7aa2b00b4e93871454e6a6fc41eb192c784.
---
 .../src/gpio-button-hotplug.c                 | 142 ++++++++++--------
 1 file changed, 79 insertions(+), 63 deletions(-)

diff --git a/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c b/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c
index fcaf7f59de..9575c6245b 100644
--- a/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c
+++ b/package/kernel/gpio-button-hotplug/src/gpio-button-hotplug.c
@@ -242,11 +242,11 @@ static int gpio_button_get_value(struct gpio_keys_button_data *bdata)
 	int val;
 
 	if (bdata->can_sleep)
-		val = !!gpiod_get_value_cansleep(bdata->gpiod);
+		val = !!gpio_get_value_cansleep(bdata->b->gpio);
 	else
-		val = !!gpiod_get_value(bdata->gpiod);
+		val = !!gpio_get_value(bdata->b->gpio);
 
-	return val;
+	return val ^ bdata->b->active_low;
 }
 
 static void gpio_keys_handle_button(struct gpio_keys_button_data *bdata)
@@ -365,6 +365,7 @@ gpio_keys_get_devtree_pdata(struct device *dev)
 	struct device_node *node, *pp;
 	struct gpio_keys_platform_data *pdata;
 	struct gpio_keys_button *button;
+	int error;
 	int nbuttons;
 	int i = 0;
 
@@ -374,12 +375,14 @@ gpio_keys_get_devtree_pdata(struct device *dev)
 
 	nbuttons = of_get_child_count(node);
 	if (nbuttons == 0)
-		return ERR_PTR(-EINVAL);
+		return NULL;
 
 	pdata = devm_kzalloc(dev, sizeof(*pdata) + nbuttons * (sizeof *button),
 		GFP_KERNEL);
-	if (!pdata)
-		return ERR_PTR(-ENOMEM);
+	if (!pdata) {
+		error = -ENOMEM;
+		goto err_out;
+	}
 
 	pdata->buttons = (struct gpio_keys_button *)(pdata + 1);
 	pdata->nbuttons = nbuttons;
@@ -388,13 +391,37 @@ gpio_keys_get_devtree_pdata(struct device *dev)
 	of_property_read_u32(node, "poll-interval", &pdata->poll_interval);
 
 	for_each_child_of_node(node, pp) {
+		enum of_gpio_flags flags;
+
+		if (!of_find_property(pp, "gpios", NULL)) {
+			pdata->nbuttons--;
+			dev_warn(dev, "Found button without gpios\n");
+			continue;
+		}
+
 		button = (struct gpio_keys_button *)(&pdata->buttons[i++]);
 
+		button->irq = irq_of_parse_and_map(pp, 0);
+
+		button->gpio = of_get_gpio_flags(pp, 0, &flags);
+		if (button->gpio < 0) {
+			error = button->gpio;
+			if (error != -ENOENT) {
+				if (error != -EPROBE_DEFER)
+					dev_err(dev,
+						"Failed to get gpio flags, error: %d\n",
+						error);
+				return ERR_PTR(error);
+			}
+		} else {
+			button->active_low = !!(flags & OF_GPIO_ACTIVE_LOW);
+		}
+
 		if (of_property_read_u32(pp, "linux,code", &button->code)) {
-			dev_err(dev, "Button node '%s' without keycode\n",
-				pp->full_name);
-			of_node_put(pp);
-			return ERR_PTR(-EINVAL);
+			dev_err(dev, "Button without keycode: 0x%x\n",
+				button->gpio);
+			error = -EINVAL;
+			goto err_out;
 		}
 
 		button->desc = of_get_property(pp, "label", NULL);
@@ -407,12 +434,17 @@ gpio_keys_get_devtree_pdata(struct device *dev)
 		if (of_property_read_u32(pp, "debounce-interval",
 					&button->debounce_interval))
 			button->debounce_interval = 5;
+	}
 
-		button->irq = irq_of_parse_and_map(pp, 0);
-		button->gpio = -ENOENT; /* mark this as device-tree */
+	if (pdata->nbuttons == 0) {
+		error = -EINVAL;
+		goto err_out;
 	}
 
 	return pdata;
+
+err_out:
+	return ERR_PTR(error);
 }
 
 static struct of_device_id gpio_keys_of_match[] = {
@@ -439,12 +471,11 @@ gpio_keys_get_devtree_pdata(struct device *dev)
 static int gpio_keys_button_probe(struct platform_device *pdev,
 		struct gpio_keys_button_dev **_bdev, int polled)
 {
+	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
 	struct device *dev = &pdev->dev;
-	struct gpio_keys_platform_data *pdata = dev_get_platdata(dev);
 	struct gpio_keys_button_dev *bdev;
 	struct gpio_keys_button *buttons;
-	struct device_node *prev = NULL;
-	int error = 0;
+	int error;
 	int i;
 
 	if (!pdata) {
@@ -483,67 +514,46 @@ static int gpio_keys_button_probe(struct platform_device *pdev,
 	for (i = 0; i < pdata->nbuttons; i++) {
 		struct gpio_keys_button *button = &buttons[i];
 		struct gpio_keys_button_data *bdata = &bdev->data[i];
-		const char *desc = button->desc ? button->desc : DRV_NAME;
+		unsigned int gpio = button->gpio;
 
 		if (button->wakeup) {
 			dev_err(dev, "does not support wakeup\n");
-			error = -EINVAL;
-			goto out;
+			return -EINVAL;
 		}
 
 		bdata->map_entry = button_get_index(button->code);
 		if (bdata->map_entry < 0) {
-			dev_err(dev, "does not support key code:%u\n",
+			dev_warn(dev, "does not support key code:%u\n",
 				button->code);
-			error = -EINVAL;
-			goto out;
+			continue;
 		}
 
 		if (!(button->type == 0 || button->type == EV_KEY ||
 		      button->type == EV_SW)) {
-			dev_err(dev, "only supports buttons or switches\n");
-			error = -EINVAL;
-			goto out;
+			dev_warn(dev, "only supports buttons or switches\n");
+			continue;
 		}
 
-		if (gpio_is_valid(button->gpio)) {
-			/* legacy platform data... but is it the lookup table? */
-			bdata->gpiod = devm_gpiod_get_index(dev, desc, i,
-							    GPIOD_IN);
-			if (IS_ERR(bdata->gpiod)) {
-				/* or the legacy (button->gpio is good) way? */
-				error = devm_gpio_request_one(dev,
-					button->gpio, GPIOF_IN | (
-					button->active_low ? GPIOF_ACTIVE_LOW :
-					0), desc);
-				if (error) {
-					if (error != -EPROBE_DEFER) {
-						dev_err(dev, "unable to claim gpio %d, err=%d\n",
-							button->gpio, error);
-					}
-					goto out;
-				}
-
-				bdata->gpiod = gpio_to_desc(button->gpio);
-			}
-		} else {
-			/* Device-tree */
-			struct device_node *child =
-				of_get_next_child(dev->of_node, prev);
-
-			bdata->gpiod = devm_gpiod_get_from_of_node(dev,
-				child, "gpios", 0, GPIOD_IN, desc);
-
-			prev = child;
+		error = devm_gpio_request(dev, gpio,
+				     button->desc ? button->desc : DRV_NAME);
+		if (error) {
+			dev_err(dev, "unable to claim gpio %u, err=%d\n",
+				gpio, error);
+			return error;
 		}
+		bdata->gpiod = gpio_to_desc(gpio);
+		if (!bdata->gpiod)
+			return -EINVAL;
 
-		if (IS_ERR_OR_NULL(bdata->gpiod)) {
-			error = IS_ERR(bdata->gpiod) ? PTR_ERR(bdata->gpiod) :
-				-EINVAL;
-			goto out;
+		error = gpio_direction_input(gpio);
+		if (error) {
+			dev_err(dev,
+				"unable to set direction on gpio %u, err=%d\n",
+				gpio, error);
+			return error;
 		}
 
-		bdata->can_sleep = gpiod_cansleep(bdata->gpiod);
+		bdata->can_sleep = gpio_cansleep(gpio);
 		bdata->last_state = -1; /* Unknown state on boot */
 
 		if (bdev->polled) {
@@ -574,11 +584,8 @@ static int gpio_keys_button_probe(struct platform_device *pdev,
 	platform_set_drvdata(pdev, bdev);
 
 	*_bdev = bdev;
-	error = 0;
 
-out:
-	of_node_put(prev);
-	return error;
+	return 0;
 }
 
 static int gpio_keys_probe(struct platform_device *pdev)
@@ -587,7 +594,9 @@ static int gpio_keys_probe(struct platform_device *pdev)
 	struct gpio_keys_button_dev *bdev;
 	int ret, i;
 
+
 	ret = gpio_keys_button_probe(pdev, &bdev, 0);
+
 	if (ret)
 		return ret;
 
@@ -599,8 +608,12 @@ static int gpio_keys_probe(struct platform_device *pdev)
 
 		INIT_DELAYED_WORK(&bdata->work, gpio_keys_irq_work_func);
 
+		if (!bdata->gpiod)
+			continue;
+
 		if (!button->irq) {
-			bdata->irq = gpiod_to_irq(bdata->gpiod);
+			bdata->irq = gpio_to_irq(button->gpio);
+
 			if (bdata->irq < 0) {
 				dev_err(&pdev->dev, "failed to get irq for gpio:%d\n",
 					button->gpio);
@@ -618,6 +631,7 @@ static int gpio_keys_probe(struct platform_device *pdev)
 		ret = devm_request_threaded_irq(&pdev->dev,
 			bdata->irq, NULL, button_handle_irq,
 			irqflags, dev_name(&pdev->dev), bdata);
+
 		if (ret < 0) {
 			bdata->irq = 0;
 			dev_err(&pdev->dev, "failed to request irq:%d for gpio:%d\n",
@@ -639,12 +653,14 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
 	int ret;
 
 	ret = gpio_keys_button_probe(pdev, &bdev, 1);
+
 	if (ret)
 		return ret;
 
 	INIT_DELAYED_WORK(&bdev->work, gpio_keys_polled_poll);
 
 	pdata = bdev->pdata;
+
 	if (pdata->enable)
 		pdata->enable(bdev->dev);
 
-- 
2.25.1

