Add device tree support to extcon-gpio driver.
Add devicetree binding documentation

While at that
        - Cleanup the pdata as there are no users for the same.
        - Convert the driver to use gpiod_* API's.
        - Some gpio's can sleep while reading, so always use 
gpio_get_value_cansleep
        to get data. This fixes warning from gpiolib due to wrong API usage.

Signed-off-by: George Cherian <george.cher...@ti.com>
---
 .../devicetree/bindings/extcon/extcon-gpio.txt     | 21 ++++++
 drivers/extcon/extcon-gpio.c                       | 83 +++++++---------------
 include/linux/extcon/extcon-gpio.h                 | 59 ---------------
 3 files changed, 46 insertions(+), 117 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/extcon/extcon-gpio.txt
 delete mode 100644 include/linux/extcon/extcon-gpio.h

diff --git a/Documentation/devicetree/bindings/extcon/extcon-gpio.txt 
b/Documentation/devicetree/bindings/extcon/extcon-gpio.txt
new file mode 100644
index 0000000..30aa2e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/extcon/extcon-gpio.txt
@@ -0,0 +1,21 @@
+GPIO based EXTCON
+
+EXTCON GPIO
+-----------
+
+Required Properties:
+ - compatible: should be:
+       * "linux,extcon-gpio"
+ - gpios: specifies the gpio pin used.
+
+Optional Properties:
+ - debounce: Debounce time for GPIO IRQ in ms
+
+
+Eg:
+
+       extcon1: am43_usbid_extcon1 {
+               compatible = "linux,extcon-gpio";
+               gpios = <&gpio3 12 GPIO_ACTIVE_HIGH>;
+               debounce = <20>;
+               };
diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c
index 72f19a3..85795de 100644
--- a/drivers/extcon/extcon-gpio.c
+++ b/drivers/extcon/extcon-gpio.c
@@ -21,26 +21,23 @@
 */
 
 #include <linux/extcon.h>
-#include <linux/extcon/extcon-gpio.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 
 struct gpio_extcon_data {
        struct extcon_dev *edev;
-       unsigned gpio;
-       bool gpio_active_low;
-       const char *state_on;
-       const char *state_off;
+       struct gpio_desc *gpiod;
        int irq;
        struct delayed_work work;
        unsigned long debounce_jiffies;
-       bool check_on_resume;
 };
 
 static void gpio_extcon_work(struct work_struct *work)
@@ -50,9 +47,7 @@ static void gpio_extcon_work(struct work_struct *work)
                container_of(to_delayed_work(work), struct gpio_extcon_data,
                             work);
 
-       state = gpio_get_value(data->gpio);
-       if (data->gpio_active_low)
-               state = !state;
+       state = gpiod_get_value_cansleep(data->gpiod);
        extcon_set_state(data->edev, state);
 }
 
@@ -65,34 +60,16 @@ static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-static ssize_t extcon_gpio_print_state(struct extcon_dev *edev, char *buf)
-{
-       struct device *dev = edev->dev.parent;
-       struct gpio_extcon_data *extcon_data = dev_get_drvdata(dev);
-       const char *state;
-
-       if (extcon_get_state(edev))
-               state = extcon_data->state_on;
-       else
-               state = extcon_data->state_off;
-
-       if (state)
-               return sprintf(buf, "%s\n", state);
-       return -EINVAL;
-}
-
 static int gpio_extcon_probe(struct platform_device *pdev)
 {
-       struct gpio_extcon_platform_data *pdata = dev_get_platdata(&pdev->dev);
+       struct device_node *np = pdev->dev.of_node;
        struct gpio_extcon_data *extcon_data;
+       unsigned int irq_flags;
+       unsigned int debounce = 0;
        int ret;
 
-       if (!pdata)
-               return -EBUSY;
-       if (!pdata->irq_flags) {
-               dev_err(&pdev->dev, "IRQ flag is not specified.\n");
+       if (!np)
                return -EINVAL;
-       }
 
        extcon_data = devm_kzalloc(&pdev->dev, sizeof(struct gpio_extcon_data),
                                   GFP_KERNEL);
@@ -104,27 +81,23 @@ static int gpio_extcon_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to allocate extcon device\n");
                return -ENOMEM;
        }
-       extcon_data->edev->name = pdata->name;
-
-       extcon_data->gpio = pdata->gpio;
-       extcon_data->gpio_active_low = pdata->gpio_active_low;
-       extcon_data->state_on = pdata->state_on;
-       extcon_data->state_off = pdata->state_off;
-       extcon_data->check_on_resume = pdata->check_on_resume;
-       if (pdata->state_on && pdata->state_off)
-               extcon_data->edev->print_state = extcon_gpio_print_state;
-
-       ret = devm_gpio_request_one(&pdev->dev, extcon_data->gpio, GPIOF_DIR_IN,
-                                   pdev->name);
-       if (ret < 0)
-               return ret;
+       extcon_data->edev->name = np->name;
+       extcon_data->gpiod = gpiod_get(&pdev->dev, NULL);
+       if (IS_ERR(extcon_data->gpiod))
+               return PTR_ERR(extcon_data->gpiod);
 
-       if (pdata->debounce) {
-               ret = gpio_set_debounce(extcon_data->gpio,
-                                       pdata->debounce * 1000);
+       extcon_data->irq = gpiod_to_irq(extcon_data->gpiod);
+       if (extcon_data->irq < 0)
+               return extcon_data->irq;
+
+       irq_flags = irq_get_trigger_type(extcon_data->irq);
+       of_property_read_u32(np, "debounce", &debounce);
+       if (debounce) {
+               ret = gpiod_set_debounce(extcon_data->gpiod,
+                                        debounce * 1000);
                if (ret < 0)
                        extcon_data->debounce_jiffies =
-                               msecs_to_jiffies(pdata->debounce);
+                               msecs_to_jiffies(debounce);
        }
 
        ret = devm_extcon_dev_register(&pdev->dev, extcon_data->edev);
@@ -132,13 +105,8 @@ static int gpio_extcon_probe(struct platform_device *pdev)
                return ret;
 
        INIT_DELAYED_WORK(&extcon_data->work, gpio_extcon_work);
-
-       extcon_data->irq = gpio_to_irq(extcon_data->gpio);
-       if (extcon_data->irq < 0)
-               return extcon_data->irq;
-
        ret = request_any_context_irq(extcon_data->irq, gpio_irq_handler,
-                                     pdata->irq_flags, pdev->name,
+                                     irq_flags, pdev->name,
                                      extcon_data);
        if (ret < 0)
                return ret;
@@ -166,9 +134,8 @@ static int gpio_extcon_resume(struct device *dev)
        struct gpio_extcon_data *extcon_data;
 
        extcon_data = dev_get_drvdata(dev);
-       if (extcon_data->check_on_resume)
-               queue_delayed_work(system_power_efficient_wq,
-                       &extcon_data->work, extcon_data->debounce_jiffies);
+       queue_delayed_work(system_power_efficient_wq,
+                          &extcon_data->work, extcon_data->debounce_jiffies);
 
        return 0;
 }
diff --git a/include/linux/extcon/extcon-gpio.h 
b/include/linux/extcon/extcon-gpio.h
deleted file mode 100644
index 0b17ad4..0000000
--- a/include/linux/extcon/extcon-gpio.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  External connector (extcon) class generic GPIO driver
- *
- * Copyright (C) 2012 Samsung Electronics
- * Author: MyungJoo Ham <myungjoo....@samsung.com>
- *
- * based on switch class driver
- * Copyright (C) 2008 Google, Inc.
- * Author: Mike Lockwood <lockw...@android.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
-*/
-#ifndef __EXTCON_GPIO_H__
-#define __EXTCON_GPIO_H__ __FILE__
-
-#include <linux/extcon.h>
-
-/**
- * struct gpio_extcon_platform_data - A simple GPIO-controlled extcon device.
- * @name:              The name of this GPIO extcon device.
- * @gpio:              Corresponding GPIO.
- * @gpio_active_low:   Boolean describing whether gpio active state is 1 or 0
- *                     If true, low state of gpio means active.
- *                     If false, high state of gpio means active.
- * @debounce:          Debounce time for GPIO IRQ in ms.
- * @irq_flags:         IRQ Flags (e.g., IRQF_TRIGGER_LOW).
- * @state_on:          print_state is overriden with state_on if attached.
- *                     If NULL, default method of extcon class is used.
- * @state_off:         print_state is overriden with state_off if detached.
- *                     If NUll, default method of extcon class is used.
- * @check_on_resume:   Boolean describing whether to check the state of gpio
- *                     while resuming from sleep.
- *
- * Note that in order for state_on or state_off to be valid, both state_on
- * and state_off should be not NULL. If at least one of them is NULL,
- * the print_state is not overriden.
- */
-struct gpio_extcon_platform_data {
-       const char *name;
-       unsigned gpio;
-       bool gpio_active_low;
-       unsigned long debounce;
-       unsigned long irq_flags;
-
-       /* if NULL, "0" or "1" will be printed */
-       const char *state_on;
-       const char *state_off;
-       bool check_on_resume;
-};
-
-#endif /* __EXTCON_GPIO_H__ */
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to