提交 a2363f9d 编写于 作者: L Linus Walleij 提交者: Wim Van Sebroeck

watchdog: gpio: Convert to use GPIO descriptors

This converts the GPIO watchdog driver to use GPIO descriptors
instead of relying on the old method to read out GPIO numbers
from the device tree and then using those with the old GPIO
API.

The descriptor API keeps track of whether the line is active
low so we can remove all active low handling and rely on the
GPIO descriptor to deal with this for us.
Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
Reviewed-by: NGuenter Roeck <linux@roeck-us.net>
Signed-off-by: NGuenter Roeck <linux@roeck-us.net>
Signed-off-by: NWim Van Sebroeck <wim@iguana.be>
上级 d0d0677e
...@@ -12,7 +12,8 @@ ...@@ -12,7 +12,8 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_gpio.h> #include <linux/gpio/consumer.h>
#include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/watchdog.h> #include <linux/watchdog.h>
...@@ -25,8 +26,7 @@ enum { ...@@ -25,8 +26,7 @@ enum {
}; };
struct gpio_wdt_priv { struct gpio_wdt_priv {
int gpio; struct gpio_desc *gpiod;
bool active_low;
bool state; bool state;
bool always_running; bool always_running;
unsigned int hw_algo; unsigned int hw_algo;
...@@ -35,11 +35,12 @@ struct gpio_wdt_priv { ...@@ -35,11 +35,12 @@ struct gpio_wdt_priv {
static void gpio_wdt_disable(struct gpio_wdt_priv *priv) static void gpio_wdt_disable(struct gpio_wdt_priv *priv)
{ {
gpio_set_value_cansleep(priv->gpio, !priv->active_low); /* Eternal ping */
gpiod_set_value_cansleep(priv->gpiod, 1);
/* Put GPIO back to tristate */ /* Put GPIO back to tristate */
if (priv->hw_algo == HW_ALGO_TOGGLE) if (priv->hw_algo == HW_ALGO_TOGGLE)
gpio_direction_input(priv->gpio); gpiod_direction_input(priv->gpiod);
} }
static int gpio_wdt_ping(struct watchdog_device *wdd) static int gpio_wdt_ping(struct watchdog_device *wdd)
...@@ -50,13 +51,13 @@ static int gpio_wdt_ping(struct watchdog_device *wdd) ...@@ -50,13 +51,13 @@ static int gpio_wdt_ping(struct watchdog_device *wdd)
case HW_ALGO_TOGGLE: case HW_ALGO_TOGGLE:
/* Toggle output pin */ /* Toggle output pin */
priv->state = !priv->state; priv->state = !priv->state;
gpio_set_value_cansleep(priv->gpio, priv->state); gpiod_set_value_cansleep(priv->gpiod, priv->state);
break; break;
case HW_ALGO_LEVEL: case HW_ALGO_LEVEL:
/* Pulse */ /* Pulse */
gpio_set_value_cansleep(priv->gpio, !priv->active_low); gpiod_set_value_cansleep(priv->gpiod, 1);
udelay(1); udelay(1);
gpio_set_value_cansleep(priv->gpio, priv->active_low); gpiod_set_value_cansleep(priv->gpiod, 0);
break; break;
} }
return 0; return 0;
...@@ -66,8 +67,8 @@ static int gpio_wdt_start(struct watchdog_device *wdd) ...@@ -66,8 +67,8 @@ static int gpio_wdt_start(struct watchdog_device *wdd)
{ {
struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd); struct gpio_wdt_priv *priv = watchdog_get_drvdata(wdd);
priv->state = priv->active_low; priv->state = 0;
gpio_direction_output(priv->gpio, priv->state); gpiod_direction_output(priv->gpiod, priv->state);
set_bit(WDOG_HW_RUNNING, &wdd->status); set_bit(WDOG_HW_RUNNING, &wdd->status);
...@@ -104,9 +105,8 @@ static int gpio_wdt_probe(struct platform_device *pdev) ...@@ -104,9 +105,8 @@ static int gpio_wdt_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct gpio_wdt_priv *priv; struct gpio_wdt_priv *priv;
enum of_gpio_flags flags; enum gpiod_flags gflags;
unsigned int hw_margin; unsigned int hw_margin;
unsigned long f = 0;
const char *algo; const char *algo;
int ret; int ret;
...@@ -116,29 +116,22 @@ static int gpio_wdt_probe(struct platform_device *pdev) ...@@ -116,29 +116,22 @@ static int gpio_wdt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv); platform_set_drvdata(pdev, priv);
priv->gpio = of_get_gpio_flags(np, 0, &flags);
if (!gpio_is_valid(priv->gpio))
return priv->gpio;
priv->active_low = flags & OF_GPIO_ACTIVE_LOW;
ret = of_property_read_string(np, "hw_algo", &algo); ret = of_property_read_string(np, "hw_algo", &algo);
if (ret) if (ret)
return ret; return ret;
if (!strcmp(algo, "toggle")) { if (!strcmp(algo, "toggle")) {
priv->hw_algo = HW_ALGO_TOGGLE; priv->hw_algo = HW_ALGO_TOGGLE;
f = GPIOF_IN; gflags = GPIOD_IN;
} else if (!strcmp(algo, "level")) { } else if (!strcmp(algo, "level")) {
priv->hw_algo = HW_ALGO_LEVEL; priv->hw_algo = HW_ALGO_LEVEL;
f = priv->active_low ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; gflags = GPIOD_OUT_LOW;
} else { } else {
return -EINVAL; return -EINVAL;
} }
ret = devm_gpio_request_one(dev, priv->gpio, f, priv->gpiod = devm_gpiod_get(dev, NULL, gflags);
dev_name(dev)); if (IS_ERR(priv->gpiod))
if (ret) return PTR_ERR(priv->gpiod);
return ret;
ret = of_property_read_u32(np, ret = of_property_read_u32(np,
"hw_margin_ms", &hw_margin); "hw_margin_ms", &hw_margin);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册