All of lore.kernel.org
 help / color / mirror / Atom feed
From: Krystian Garbaciak <krystian.garbaciak@diasemi.com>
To: linux-kernel@vger.kernel.org, rtc-linux@googlegroups.com,
	lm-sensors@lm-sensors.org, linux-input@vger.kernel.org,
	linux-watchdog@vger.kernel.org, linux-leds@vger.kernel.org
Cc: Alessandro Zummo <a.zummo@towertech.it>,
	Andrew Jones <drjones@redhat.com>,
	Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	Samuel Ortiz <sameo@linux.intel.com>,
	Ashish Jangam <ashish.jangam@kpitcummins.com>,
	Mark Brown <broonie@opensource.wolfsonmicro.com>,
	Donggeun Kim <dg77.kim@samsung.com>,
	Wim Van Sebroeck <wim@iguana.be>,
	"Richard Purdie <rpurdie@rpsys.net> Anthony Olech"
	<anthony.olech@diasemi.com>, Bryan Wu <bryan.wu@canonical.com>,
	Liam Girdwood <lrg@ti.com>
Subject: [RFC PATCH 7/8] watchdog: Add DA906x PMIC watchdog driver.
Date: Fri, 24 Aug 2012 15:20:00 +0100	[thread overview]
Message-ID: <201208241520@sw-eng-lt-dc-vm2> (raw)
In-Reply-To: <201208241515@sw-eng-lt-dc-vm2>

This driver supports watchdog device inside DA906x PMIC.

Signed-off-by: Krystian Garbaciak <krystian.garbaciak@diasemi.com>
---
 drivers/watchdog/Kconfig      |   27 ++++
 drivers/watchdog/Makefile     |    1 +
 drivers/watchdog/da906x_wdt.c |  276 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 304 insertions(+), 0 deletions(-)
 create mode 100644 drivers/watchdog/da906x_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 53d7571..ef07575 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -76,6 +76,33 @@ config DA9052_WATCHDOG
           Alternatively say M to compile the driver as a module,
           which will be called da9052_wdt.
 
+config DA906X_WATCHDOG
+	tristate "Dialog DA906X Watchdog"
+	depends on MFD_DA906X
+	select WATCHDOG_CORE
+	help
+	  Support for the watchdog in the DA906X PMIC.
+
+config DA906X_WDT_DEFAULT_TIMEOUT
+	int "Watchdog timeout in seconds <2, 4, 8, 16, 32, 65, 131>"
+	depends on DA906X_WATCHDOG
+	default 8
+	range 2 131
+	help
+	  Select the default watchdog timer period to be used by the
+	  Dialog DA906x watchdog driver. Supported values are:
+	  2, 4, 8, 16, 32, 65, 131 seconds.
+
+config DA906X_WDT_FLEXIBLE_TIMEOUT
+	bool "Flexible watchdog timeout (when requested value is unsupported)"
+	depends on DA906X_WATCHDOG
+	default y
+	help
+	  Say Y here to allow to select longer watchdog timer period to be
+	  used when requested value is not supported. The lowest available
+	  value higher than requested will be used (watchdog will never
+	  expire before requested timeout).
+
 config WM831X_WATCHDOG
 	tristate "WM831x watchdog"
 	depends on MFD_WM831X
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 572b39b..0746a87 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -164,6 +164,7 @@ obj-$(CONFIG_XEN_WDT) += xen_wdt.o
 
 # Architecture Independent
 obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o
+obj-$(CONFIG_DA906X_WATCHDOG) += da906x_wdt.o
 obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
 obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
 obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
diff --git a/drivers/watchdog/da906x_wdt.c b/drivers/watchdog/da906x_wdt.c
new file mode 100644
index 0000000..a67e4fa
--- /dev/null
+++ b/drivers/watchdog/da906x_wdt.c
@@ -0,0 +1,276 @@
+/*
+ * Watchdog driver for DA906X PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: Mariusz Wojtasik <mariusz.wojtasik@diasemi.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/watchdog.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <linux/mfd/da906x/registers.h>
+#include <linux/mfd/da906x/core.h>
+
+#define	SUPPORTED_TIMEOUTS_STR		"2, 4, 8, 16, 32, 65, 131"
+
+/* Watchdog selector to timeout in seconds.
+   0: WDT disabled;
+   others: timeout = 2048 ms * 2^(TWDSCALE-1). */
+const int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 };
+#define DA906X_TWDSCALE_DISABLE		0
+#define DA906X_TWDSCALE_MIN		1
+#define DA906X_TWDSCALE_MAX		(ARRAY_SIZE(wdt_timeout) - 1)
+#define DA906X_WDT_MIN_TIMEOUT		wdt_timeout[DA906X_TWDSCALE_MIN]
+#define DA906X_WDT_MAX_TIMEOUT		wdt_timeout[DA906X_TWDSCALE_MAX]
+#define WATCHDOG_DEFAULT_TIMEOUT	wdt_timeout[3];
+
+/* module parameters */
+static int default_timeout = CONFIG_DA906X_WDT_DEFAULT_TIMEOUT;
+module_param(default_timeout, int, 0);
+MODULE_PARM_DESC(default_timeout,
+	"Watchdog timeout in seconds (select from: " SUPPORTED_TIMEOUTS_STR
+	" default=" __stringify(CONFIG_DA906X_WDT_DEFAULT_TIMEOUT) ")");
+
+static bool flex_timeout = CONFIG_DA906X_WDT_FLEXIBLE_TIMEOUT;
+module_param(flex_timeout, bool, false);
+MODULE_PARM_DESC(flex_timeout,
+	"Watchdog flexible timeout, allows longer timeout than requested"
+	" (default=" __stringify(CONFIG_DA906X_WDT_FLEXIBLE_TIMEOUT) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout,
+		 "Watchdog cannot be stopped once started (default="
+		 __stringify(WATCHDOG_NOWAYOUT) ")");
+
+
+struct da906x_watchdog {
+	struct da906x *da906x;
+	struct watchdog_device *wdtdev;
+	struct mutex lock;
+};
+static struct da906x_watchdog da906x_watchdog;
+
+static int _da906x_wdt_timeout_to_sel(int secs)
+{
+	int i;
+
+	for (i = DA906X_TWDSCALE_MIN; i <= DA906X_TWDSCALE_MAX; i++) {
+		if (wdt_timeout[i] == secs ||
+		    (flex_timeout && wdt_timeout[i] > secs))
+			return i;
+	}
+
+	return 0;
+}
+
+static int _da906x_wdt_disable(struct da906x *da906x)
+{
+	return da906x_reg_update(da906x, DA906X_REG_CONTROL_D,
+			DA906X_TWDSCALE_MASK,
+			DA906X_TWDSCALE_DISABLE << DA906X_TWDSCALE_SHIFT);
+}
+
+static int _da906x_wdt_set_timeout(struct da906x *da906x, unsigned int regval)
+{
+	if (regval > DA906X_TWDSCALE_MAX)
+		return -EINVAL;
+
+	return da906x_reg_update(da906x, DA906X_REG_CONTROL_D,
+			DA906X_TWDSCALE_MASK, regval << DA906X_TWDSCALE_SHIFT);
+}
+
+static int _da906x_wdt_kick(struct da906x *da906x)
+{
+	return da906x_reg_write(da906x, DA906X_REG_CONTROL_F, DA906X_WATCHDOG);
+}
+
+static int da906x_wdt_start(struct watchdog_device *wdd)
+{
+	struct da906x_watchdog *wdt = watchdog_get_drvdata(wdd);
+	unsigned int selector;
+	int ret = 0;
+
+	mutex_lock(&wdt->lock);
+	selector = _da906x_wdt_timeout_to_sel(wdt->wdtdev->timeout);
+	ret = _da906x_wdt_set_timeout(wdt->da906x, selector);
+	if (ret != 0) {
+		dev_err(wdt->da906x->dev,
+			"Watchdog failed to start (err = %d)\n", ret);
+	}
+	mutex_unlock(&wdt->lock);
+
+	return ret;
+}
+
+static int da906x_wdt_stop(struct watchdog_device *wdd)
+{
+	struct da906x_watchdog *wdt = watchdog_get_drvdata(wdd);
+	int ret = 0;
+
+	mutex_lock(&wdt->lock);
+	ret = _da906x_wdt_disable(wdt->da906x);
+	if (ret < 0)
+		dev_alert(wdt->da906x->dev,
+			  "Watchdog failed to stop (err = %d)\n", ret);
+	mutex_unlock(&wdt->lock);
+
+	return ret;
+}
+
+static int da906x_wdt_ping(struct watchdog_device *wdd)
+{
+	struct da906x_watchdog *wdt = watchdog_get_drvdata(wdd);
+	int ret = 0;
+
+	mutex_lock(&wdt->lock);
+	ret = _da906x_wdt_kick(wdt->da906x);
+	if (ret < 0)
+		dev_alert(wdt->da906x->dev,
+			  "Failed to ping the watchdog (err = %d)\n", ret);
+	mutex_unlock(&wdt->lock);
+
+	return ret;
+}
+
+static int da906x_wdt_set_timeout(struct watchdog_device *wdd,
+							unsigned int timeout)
+{
+	struct da906x_watchdog *wdt = watchdog_get_drvdata(wdd);
+	unsigned int selector;
+	int ret = 0;
+
+	mutex_lock(&wdt->lock);
+	selector = _da906x_wdt_timeout_to_sel(timeout);
+	if (selector == 0) {
+		dev_err(wdt->da906x->dev,
+			"Unsupported watchdog timeout (selecto from: "
+			SUPPORTED_TIMEOUTS_STR ")\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = _da906x_wdt_set_timeout(wdt->da906x, selector);
+	if (ret < 0) {
+		dev_err(wdt->da906x->dev,
+			"Failed to set watchdog timeout (err = %d)\n", ret);
+		goto out;
+	}
+
+	wdd->timeout = wdt_timeout[selector];
+
+out:
+	mutex_unlock(&wdt->lock);
+
+	return ret;
+}
+
+static struct watchdog_info da906x_watchdog_info = {
+	.options	= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+	.identity	= "DA906x Watchdog",
+};
+
+static struct watchdog_ops da906x_watchdog_ops = {
+	.owner	= THIS_MODULE,
+	.start		= da906x_wdt_start,
+	.stop		= da906x_wdt_stop,
+	.ping		= da906x_wdt_ping,
+	.set_timeout	= da906x_wdt_set_timeout,
+};
+
+static struct watchdog_device da906x_watchdog_device = {
+	.info	= &da906x_watchdog_info,
+	.ops	= &da906x_watchdog_ops,
+	.driver_data = &da906x_watchdog,
+};
+
+static int __devinit da906x_wdt_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct da906x *da906x = dev_get_drvdata(pdev->dev.parent);
+	struct da906x_watchdog *wdt = &da906x_watchdog;
+	unsigned int selector;
+
+	if (wdt->da906x != NULL) {
+		dev_err(da906x->dev, DA906X_DRVNAME_WATCHDOG
+			" already registered.\n");
+		return -EBUSY;
+	}
+
+	wdt->da906x = da906x;
+	wdt->wdtdev = &da906x_watchdog_device;
+	mutex_init(&wdt->lock);
+
+	if (nowayout)
+		set_bit(WDOG_NO_WAY_OUT, &wdt->wdtdev->status);
+
+	if (flex_timeout)
+		wdt->wdtdev->min_timeout = 1;
+	else
+		wdt->wdtdev->min_timeout = DA906X_WDT_MIN_TIMEOUT;
+
+	wdt->wdtdev->max_timeout = DA906X_WDT_MAX_TIMEOUT;
+
+	selector = _da906x_wdt_timeout_to_sel(default_timeout);
+	if (selector == 0) {
+		wdt->wdtdev->timeout = WATCHDOG_DEFAULT_TIMEOUT;
+		dev_warn(da906x->dev,
+			 "Invalid default timeout: %d "
+			 "(select from: " SUPPORTED_TIMEOUTS_STR ").\n",
+			 default_timeout);
+		dev_warn(da906x->dev, "Default timeout is %d secs.\n",
+			 wdt->wdtdev->timeout);
+	} else {
+		wdt->wdtdev->timeout = wdt_timeout[selector];
+		if (wdt->wdtdev->timeout != default_timeout) {
+			dev_info(da906x->dev, "Using %d secs timeout.\n",
+				 wdt->wdtdev->timeout);
+		}
+	}
+
+	ret = watchdog_register_device(wdt->wdtdev);
+	if (ret)
+		dev_err(da906x->dev, DA906X_DRVNAME_WATCHDOG
+			" registration failed (err = %d)", ret);
+
+	return ret;
+}
+
+static int __devexit da906x_wdt_remove(struct platform_device *dev)
+{
+	struct da906x_watchdog *wdt = &da906x_watchdog;
+
+	watchdog_unregister_device(&da906x_watchdog_device);
+	wdt->da906x = NULL;
+	wdt->wdtdev = NULL;
+
+	return 0;
+}
+
+static struct platform_driver da906x_wdt_driver = {
+	.probe = da906x_wdt_probe,
+	.remove = __devexit_p(da906x_wdt_remove),
+	.driver = {
+		.name	= DA906X_DRVNAME_WATCHDOG,
+		.owner	= THIS_MODULE,
+	},
+};
+
+module_platform_driver(da906x_wdt_driver);
+
+MODULE_AUTHOR("Mariusz Wojtasik <mariusz.wojtasik@diasemi.com>");
+MODULE_DESCRIPTION("Watchdog driver for Dialog DA906x");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DA906X_DRVNAME_WATCHDOG);
-- 
1.7.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

WARNING: multiple messages have this Message-ID (diff)
From: Krystian Garbaciak <krystian.garbaciak@diasemi.com>
To: linux-kernel@vger.kernel.org, rtc-linux@googlegroups.com,
	lm-sensors@lm-sensors.org, linux-input@vger.kernel.org,
	linux-watchdog@vger.kernel.org, linux-leds@vger.kernel.org
Cc: Alessandro Zummo <a.zummo@towertech.it>,
	Andrew Jones <drjones@redhat.com>,
	Dmitry Torokhov <dmitry.torokhov@gmail.com>,
	Samuel Ortiz <sameo@linux.intel.com>,
	Ashish Jangam <ashish.jangam@kpitcummins.com>,
	Mark Brown <broonie@opensource.wolfsonmicro.com>,
	Donggeun Kim <dg77.kim@samsung.com>,
	Wim Van Sebroeck <wim@iguana.be>,
	"Richard Purdie <rpurdie@rpsys.net> Anthony Olech"
	<anthony.olech@diasemi.com>, Bryan Wu <bryan.wu@canonical.com>,
	Liam Girdwood <lrg@ti.com>
Subject: [lm-sensors] [RFC PATCH 7/8] watchdog: Add DA906x PMIC watchdog driver.
Date: Fri, 24 Aug 2012 14:20:00 +0000	[thread overview]
Message-ID: <201208241520@sw-eng-lt-dc-vm2> (raw)
In-Reply-To: <201208241515@sw-eng-lt-dc-vm2>

This driver supports watchdog device inside DA906x PMIC.

Signed-off-by: Krystian Garbaciak <krystian.garbaciak@diasemi.com>
---
 drivers/watchdog/Kconfig      |   27 ++++
 drivers/watchdog/Makefile     |    1 +
 drivers/watchdog/da906x_wdt.c |  276 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 304 insertions(+), 0 deletions(-)
 create mode 100644 drivers/watchdog/da906x_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 53d7571..ef07575 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -76,6 +76,33 @@ config DA9052_WATCHDOG
           Alternatively say M to compile the driver as a module,
           which will be called da9052_wdt.
 
+config DA906X_WATCHDOG
+	tristate "Dialog DA906X Watchdog"
+	depends on MFD_DA906X
+	select WATCHDOG_CORE
+	help
+	  Support for the watchdog in the DA906X PMIC.
+
+config DA906X_WDT_DEFAULT_TIMEOUT
+	int "Watchdog timeout in seconds <2, 4, 8, 16, 32, 65, 131>"
+	depends on DA906X_WATCHDOG
+	default 8
+	range 2 131
+	help
+	  Select the default watchdog timer period to be used by the
+	  Dialog DA906x watchdog driver. Supported values are:
+	  2, 4, 8, 16, 32, 65, 131 seconds.
+
+config DA906X_WDT_FLEXIBLE_TIMEOUT
+	bool "Flexible watchdog timeout (when requested value is unsupported)"
+	depends on DA906X_WATCHDOG
+	default y
+	help
+	  Say Y here to allow to select longer watchdog timer period to be
+	  used when requested value is not supported. The lowest available
+	  value higher than requested will be used (watchdog will never
+	  expire before requested timeout).
+
 config WM831X_WATCHDOG
 	tristate "WM831x watchdog"
 	depends on MFD_WM831X
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 572b39b..0746a87 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -164,6 +164,7 @@ obj-$(CONFIG_XEN_WDT) += xen_wdt.o
 
 # Architecture Independent
 obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o
+obj-$(CONFIG_DA906X_WATCHDOG) += da906x_wdt.o
 obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
 obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
 obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
diff --git a/drivers/watchdog/da906x_wdt.c b/drivers/watchdog/da906x_wdt.c
new file mode 100644
index 0000000..a67e4fa
--- /dev/null
+++ b/drivers/watchdog/da906x_wdt.c
@@ -0,0 +1,276 @@
+/*
+ * Watchdog driver for DA906X PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: Mariusz Wojtasik <mariusz.wojtasik@diasemi.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/watchdog.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <linux/mfd/da906x/registers.h>
+#include <linux/mfd/da906x/core.h>
+
+#define	SUPPORTED_TIMEOUTS_STR		"2, 4, 8, 16, 32, 65, 131"
+
+/* Watchdog selector to timeout in seconds.
+   0: WDT disabled;
+   others: timeout = 2048 ms * 2^(TWDSCALE-1). */
+const int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 };
+#define DA906X_TWDSCALE_DISABLE		0
+#define DA906X_TWDSCALE_MIN		1
+#define DA906X_TWDSCALE_MAX		(ARRAY_SIZE(wdt_timeout) - 1)
+#define DA906X_WDT_MIN_TIMEOUT		wdt_timeout[DA906X_TWDSCALE_MIN]
+#define DA906X_WDT_MAX_TIMEOUT		wdt_timeout[DA906X_TWDSCALE_MAX]
+#define WATCHDOG_DEFAULT_TIMEOUT	wdt_timeout[3];
+
+/* module parameters */
+static int default_timeout = CONFIG_DA906X_WDT_DEFAULT_TIMEOUT;
+module_param(default_timeout, int, 0);
+MODULE_PARM_DESC(default_timeout,
+	"Watchdog timeout in seconds (select from: " SUPPORTED_TIMEOUTS_STR
+	" default=" __stringify(CONFIG_DA906X_WDT_DEFAULT_TIMEOUT) ")");
+
+static bool flex_timeout = CONFIG_DA906X_WDT_FLEXIBLE_TIMEOUT;
+module_param(flex_timeout, bool, false);
+MODULE_PARM_DESC(flex_timeout,
+	"Watchdog flexible timeout, allows longer timeout than requested"
+	" (default=" __stringify(CONFIG_DA906X_WDT_FLEXIBLE_TIMEOUT) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout,
+		 "Watchdog cannot be stopped once started (default="
+		 __stringify(WATCHDOG_NOWAYOUT) ")");
+
+
+struct da906x_watchdog {
+	struct da906x *da906x;
+	struct watchdog_device *wdtdev;
+	struct mutex lock;
+};
+static struct da906x_watchdog da906x_watchdog;
+
+static int _da906x_wdt_timeout_to_sel(int secs)
+{
+	int i;
+
+	for (i = DA906X_TWDSCALE_MIN; i <= DA906X_TWDSCALE_MAX; i++) {
+		if (wdt_timeout[i] = secs ||
+		    (flex_timeout && wdt_timeout[i] > secs))
+			return i;
+	}
+
+	return 0;
+}
+
+static int _da906x_wdt_disable(struct da906x *da906x)
+{
+	return da906x_reg_update(da906x, DA906X_REG_CONTROL_D,
+			DA906X_TWDSCALE_MASK,
+			DA906X_TWDSCALE_DISABLE << DA906X_TWDSCALE_SHIFT);
+}
+
+static int _da906x_wdt_set_timeout(struct da906x *da906x, unsigned int regval)
+{
+	if (regval > DA906X_TWDSCALE_MAX)
+		return -EINVAL;
+
+	return da906x_reg_update(da906x, DA906X_REG_CONTROL_D,
+			DA906X_TWDSCALE_MASK, regval << DA906X_TWDSCALE_SHIFT);
+}
+
+static int _da906x_wdt_kick(struct da906x *da906x)
+{
+	return da906x_reg_write(da906x, DA906X_REG_CONTROL_F, DA906X_WATCHDOG);
+}
+
+static int da906x_wdt_start(struct watchdog_device *wdd)
+{
+	struct da906x_watchdog *wdt = watchdog_get_drvdata(wdd);
+	unsigned int selector;
+	int ret = 0;
+
+	mutex_lock(&wdt->lock);
+	selector = _da906x_wdt_timeout_to_sel(wdt->wdtdev->timeout);
+	ret = _da906x_wdt_set_timeout(wdt->da906x, selector);
+	if (ret != 0) {
+		dev_err(wdt->da906x->dev,
+			"Watchdog failed to start (err = %d)\n", ret);
+	}
+	mutex_unlock(&wdt->lock);
+
+	return ret;
+}
+
+static int da906x_wdt_stop(struct watchdog_device *wdd)
+{
+	struct da906x_watchdog *wdt = watchdog_get_drvdata(wdd);
+	int ret = 0;
+
+	mutex_lock(&wdt->lock);
+	ret = _da906x_wdt_disable(wdt->da906x);
+	if (ret < 0)
+		dev_alert(wdt->da906x->dev,
+			  "Watchdog failed to stop (err = %d)\n", ret);
+	mutex_unlock(&wdt->lock);
+
+	return ret;
+}
+
+static int da906x_wdt_ping(struct watchdog_device *wdd)
+{
+	struct da906x_watchdog *wdt = watchdog_get_drvdata(wdd);
+	int ret = 0;
+
+	mutex_lock(&wdt->lock);
+	ret = _da906x_wdt_kick(wdt->da906x);
+	if (ret < 0)
+		dev_alert(wdt->da906x->dev,
+			  "Failed to ping the watchdog (err = %d)\n", ret);
+	mutex_unlock(&wdt->lock);
+
+	return ret;
+}
+
+static int da906x_wdt_set_timeout(struct watchdog_device *wdd,
+							unsigned int timeout)
+{
+	struct da906x_watchdog *wdt = watchdog_get_drvdata(wdd);
+	unsigned int selector;
+	int ret = 0;
+
+	mutex_lock(&wdt->lock);
+	selector = _da906x_wdt_timeout_to_sel(timeout);
+	if (selector = 0) {
+		dev_err(wdt->da906x->dev,
+			"Unsupported watchdog timeout (selecto from: "
+			SUPPORTED_TIMEOUTS_STR ")\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = _da906x_wdt_set_timeout(wdt->da906x, selector);
+	if (ret < 0) {
+		dev_err(wdt->da906x->dev,
+			"Failed to set watchdog timeout (err = %d)\n", ret);
+		goto out;
+	}
+
+	wdd->timeout = wdt_timeout[selector];
+
+out:
+	mutex_unlock(&wdt->lock);
+
+	return ret;
+}
+
+static struct watchdog_info da906x_watchdog_info = {
+	.options	= WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
+	.identity	= "DA906x Watchdog",
+};
+
+static struct watchdog_ops da906x_watchdog_ops = {
+	.owner	= THIS_MODULE,
+	.start		= da906x_wdt_start,
+	.stop		= da906x_wdt_stop,
+	.ping		= da906x_wdt_ping,
+	.set_timeout	= da906x_wdt_set_timeout,
+};
+
+static struct watchdog_device da906x_watchdog_device = {
+	.info	= &da906x_watchdog_info,
+	.ops	= &da906x_watchdog_ops,
+	.driver_data = &da906x_watchdog,
+};
+
+static int __devinit da906x_wdt_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct da906x *da906x = dev_get_drvdata(pdev->dev.parent);
+	struct da906x_watchdog *wdt = &da906x_watchdog;
+	unsigned int selector;
+
+	if (wdt->da906x != NULL) {
+		dev_err(da906x->dev, DA906X_DRVNAME_WATCHDOG
+			" already registered.\n");
+		return -EBUSY;
+	}
+
+	wdt->da906x = da906x;
+	wdt->wdtdev = &da906x_watchdog_device;
+	mutex_init(&wdt->lock);
+
+	if (nowayout)
+		set_bit(WDOG_NO_WAY_OUT, &wdt->wdtdev->status);
+
+	if (flex_timeout)
+		wdt->wdtdev->min_timeout = 1;
+	else
+		wdt->wdtdev->min_timeout = DA906X_WDT_MIN_TIMEOUT;
+
+	wdt->wdtdev->max_timeout = DA906X_WDT_MAX_TIMEOUT;
+
+	selector = _da906x_wdt_timeout_to_sel(default_timeout);
+	if (selector = 0) {
+		wdt->wdtdev->timeout = WATCHDOG_DEFAULT_TIMEOUT;
+		dev_warn(da906x->dev,
+			 "Invalid default timeout: %d "
+			 "(select from: " SUPPORTED_TIMEOUTS_STR ").\n",
+			 default_timeout);
+		dev_warn(da906x->dev, "Default timeout is %d secs.\n",
+			 wdt->wdtdev->timeout);
+	} else {
+		wdt->wdtdev->timeout = wdt_timeout[selector];
+		if (wdt->wdtdev->timeout != default_timeout) {
+			dev_info(da906x->dev, "Using %d secs timeout.\n",
+				 wdt->wdtdev->timeout);
+		}
+	}
+
+	ret = watchdog_register_device(wdt->wdtdev);
+	if (ret)
+		dev_err(da906x->dev, DA906X_DRVNAME_WATCHDOG
+			" registration failed (err = %d)", ret);
+
+	return ret;
+}
+
+static int __devexit da906x_wdt_remove(struct platform_device *dev)
+{
+	struct da906x_watchdog *wdt = &da906x_watchdog;
+
+	watchdog_unregister_device(&da906x_watchdog_device);
+	wdt->da906x = NULL;
+	wdt->wdtdev = NULL;
+
+	return 0;
+}
+
+static struct platform_driver da906x_wdt_driver = {
+	.probe = da906x_wdt_probe,
+	.remove = __devexit_p(da906x_wdt_remove),
+	.driver = {
+		.name	= DA906X_DRVNAME_WATCHDOG,
+		.owner	= THIS_MODULE,
+	},
+};
+
+module_platform_driver(da906x_wdt_driver);
+
+MODULE_AUTHOR("Mariusz Wojtasik <mariusz.wojtasik@diasemi.com>");
+MODULE_DESCRIPTION("Watchdog driver for Dialog DA906x");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DA906X_DRVNAME_WATCHDOG);
-- 
1.7.0.4


_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

  reply	other threads:[~2012-08-24 14:20 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-24 13:45 [RFC PATCH 0/8] DA906x PMIC driver Krystian Garbaciak
2012-08-24 13:45 ` [lm-sensors] " Krystian Garbaciak
2012-08-24 13:50 ` [PATCH 1/8] mfd: Add Dialog DA906x core driver Krystian Garbaciak
2012-08-24 13:50   ` [lm-sensors] " Krystian Garbaciak
2012-08-24 13:55   ` [RFC PATCH 2/8] regulator: Add Dialog DA906x voltage regulators support Krystian Garbaciak
2012-08-24 13:55     ` [lm-sensors] " Krystian Garbaciak
2012-08-24 14:00     ` [RFC PATCH 3/8] rtc: Add RTC driver for DA906x PMIC Krystian Garbaciak
2012-08-24 14:00       ` [lm-sensors] " Krystian Garbaciak
2012-08-24 14:05       ` [RFC PATCH 4/8] hwmon: Add DA906x hardware monitoring support Krystian Garbaciak
2012-08-24 14:05         ` [lm-sensors] " Krystian Garbaciak
2012-08-24 14:10         ` [RFC PATCH 5/8] input: Add support for DA906x PMIC OnKey detection Krystian Garbaciak
2012-08-24 14:10           ` [lm-sensors] " Krystian Garbaciak
2012-08-24 14:15           ` [RFC PATCH 6/8] input: Add support for DA906x vibration motor driver Krystian Garbaciak
2012-08-24 14:15             ` [lm-sensors] " Krystian Garbaciak
2012-08-24 14:20             ` Krystian Garbaciak [this message]
2012-08-24 14:20               ` [lm-sensors] [RFC PATCH 7/8] watchdog: Add DA906x PMIC watchdog driver Krystian Garbaciak
2012-08-24 14:25               ` [RFC PATCH 8/8] leds: Add DA906x PMIC LED driver Krystian Garbaciak
2012-08-24 14:25                 ` [lm-sensors] " Krystian Garbaciak
2012-08-24 18:45         ` [RFC PATCH 4/8] hwmon: Add DA906x hardware monitoring support Guenter Roeck
2012-08-24 18:45           ` [lm-sensors] " Guenter Roeck
2012-08-29 13:25           ` [PATCH] regulator: Fix bug in regulator_mode_to_status() core function Krystian Garbaciak
2012-08-29 13:25             ` [lm-sensors] " Krystian Garbaciak
2012-08-25 15:10     ` [RFC PATCH 2/8] regulator: Add Dialog DA906x voltage regulators support Mark Brown
2012-08-25 15:10       ` [lm-sensors] " Mark Brown
2012-08-29 14:50       ` Krystian Garbaciak
2012-08-29 14:50         ` [lm-sensors] " Krystian Garbaciak
2012-08-29 14:50         ` Krystian Garbaciak
2012-08-30 17:47         ` Mark Brown
2012-08-30 17:47           ` [lm-sensors] " Mark Brown
2012-08-31 10:00           ` Krystian Garbaciak
2012-08-31 10:00             ` [lm-sensors] " Krystian Garbaciak
2012-08-31 10:00             ` Krystian Garbaciak
2013-05-09 14:05             ` Guennadi Liakhovetski
2013-05-09 14:18               ` Anthony Olech
2013-05-09 14:28                 ` Guennadi Liakhovetski
2013-05-09 14:42                   ` Anthony Olech
2013-05-09 14:50                     ` Guennadi Liakhovetski
2012-08-25 18:31   ` [PATCH 1/8] mfd: Add Dialog DA906x core driver Mark Brown
2012-08-25 18:31     ` [lm-sensors] " Mark Brown
2012-08-31 11:20     ` Krystian Garbaciak
2012-08-31 11:20       ` [lm-sensors] " Krystian Garbaciak
2012-08-31 11:20       ` Krystian Garbaciak
2012-08-31 11:37       ` Philippe Rétornaz
2012-08-31 11:37         ` [lm-sensors] " Philippe Rétornaz
2012-08-31 11:37         ` Philippe Rétornaz
2012-08-31 11:37         ` Philippe Rétornaz
2012-08-31 17:16       ` Mark Brown
2012-08-31 17:16         ` [lm-sensors] " Mark Brown
  -- strict thread matches above, loose matches on Subject: below --
2012-08-24  8:32 [RFC PATCH 0/8] DA906x PMIC driver Krystian Garbaciak
2012-08-24  8:32 ` [lm-sensors] " Krystian Garbaciak
2012-08-24  8:32 ` [PATCH 1/8] mfd: Add Dialog DA906x core driver Krystian Garbaciak
2012-08-24  8:32   ` [lm-sensors] " Krystian Garbaciak
2012-08-24  8:32   ` [PATCH 2/8] regulator: Add Dialog DA906x voltage regulators support Krystian Garbaciak
2012-08-24  8:32     ` [lm-sensors] " Krystian Garbaciak
2012-08-24  8:32     ` [PATCH 3/8] rtc: Add RTC driver for DA906x PMIC Krystian Garbaciak
2012-08-24  8:32       ` [lm-sensors] " Krystian Garbaciak
2012-08-24  8:32       ` [PATCH 4/8] hwmon: Add DA906x hardware monitoring support Krystian Garbaciak
2012-08-24  8:32         ` [lm-sensors] " Krystian Garbaciak
2012-08-24  8:32         ` [PATCH 5/8] input: Add support for DA906x PMIC OnKey detection Krystian Garbaciak
2012-08-24  8:32           ` [lm-sensors] " Krystian Garbaciak

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=201208241520@sw-eng-lt-dc-vm2 \
    --to=krystian.garbaciak@diasemi.com \
    --cc=a.zummo@towertech.it \
    --cc=anthony.olech@diasemi.com \
    --cc=ashish.jangam@kpitcummins.com \
    --cc=broonie@opensource.wolfsonmicro.com \
    --cc=bryan.wu@canonical.com \
    --cc=dg77.kim@samsung.com \
    --cc=dmitry.torokhov@gmail.com \
    --cc=drjones@redhat.com \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=linux-watchdog@vger.kernel.org \
    --cc=lm-sensors@lm-sensors.org \
    --cc=lrg@ti.com \
    --cc=rtc-linux@googlegroups.com \
    --cc=sameo@linux.intel.com \
    --cc=wim@iguana.be \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.