Re: [RFC PATCH v5 10/10] watchdog: bd70528: Initial support for ROHM BD70528 watchdog block

2019-02-04 Thread Matti Vaittinen
On Mon, Feb 04, 2019 at 06:38:43AM -0800, Guenter Roeck wrote:
> On 2/4/19 4:49 AM, Matti Vaittinen wrote:
> > Initial support for watchdog block included in ROHM BD70528
> > power management IC.
> > 
> > Configurations for low power states are still to be checked.
> > 
> > Signed-off-by: Matti Vaittinen 
> > ---
> >   drivers/watchdog/Kconfig   |  12 +++
> >   drivers/watchdog/Makefile  |   1 +
> >   drivers/watchdog/bd70528_wdt.c | 187 
> > +
> >   3 files changed, 200 insertions(+)
> >   create mode 100644 drivers/watchdog/bd70528_wdt.c
> > 
> > +
> > +struct wdtbd70528 {
> > +   struct device *dev;
> > +   struct regmap *regmap;
> > +   struct mutex *rtc_lock;
> > +   struct watchdog_device wdt;
> > +};
> > +
> > +static int bd70528_wdt_set_locked(struct wdtbd70528 *w, int enable)
> > +{
> > +   struct bd70528 *bd70528;
> > +
> > +   bd70528 = container_of(w->rtc_lock, struct bd70528, rtc_timer_lock);
> > +   return bd70528->wdt_set(bd70528, enable, NULL);
> > +}
> 
> Please add an empty line here.

Ok. 

> > +static int bd70528_wdt_set(struct wdtbd70528 *w, int enable)
> > +{
> > +   int ret;
> > +
> > +   mutex_lock(w->rtc_lock);
> > +   ret = bd70528_wdt_set_locked(w, enable);
> > +   mutex_unlock(w->rtc_lock);
> > +
> > +   return ret;
> > +}
> > +
> > +static int bd70528_wdt_start(struct watchdog_device *wdt)
> > +{
> > +   struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
> > +
> > +   dev_dbg(w->dev, "WDT ping...\n");
> > +   return bd70528_wdt_set(w, 1);
> > +}
> > +
> > +static int bd70528_wdt_stop(struct watchdog_device *wdt)
> > +{
> > +   struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
> > +
> > +   dev_dbg(w->dev, "WDT stopping...\n");
> > +   return bd70528_wdt_set(w, 0);
> > +}
> > +
> > +static int bd70528_wdt_set_timeout(struct watchdog_device *wdt,
> > +   unsigned int timeout)
> > +{
> > +   unsigned int hours;
> > +   unsigned int minutes;
> > +   unsigned int seconds;
> > +   int ret;
> > +   struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
> > +
> > +   seconds = timeout;
> > +   hours = timeout / (60 * 60);
> > +   /* Maximum timeout is 1h 59m 59s => hours is 1 or 0 */
> > +   if (hours)
> > +   seconds -= (60 * 60);
> > +   minutes = seconds / 60;
> > +   seconds = seconds % 60;
> > +
> > +   mutex_lock(w->rtc_lock);
> > +
> > +   ret = bd70528_wdt_set_locked(w, 0);
> > +   if (ret)
> > +   goto out_unlock;
> > +
> > +   ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_HOUR,
> > +BD70528_MASK_WDT_HOUR, hours);
> > +   if (ret) {
> > +   dev_err(w->dev, "Failed to set WDT hours\n");
> > +   goto out_en_unlock;
> > +   }
> > +   ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_MINUTE,
> > +BD70528_MASK_WDT_MINUTE, bin2bcd(minutes));
> > +   if (ret) {
> > +   dev_err(w->dev, "Failed to set WDT minutes\n");
> > +   goto out_en_unlock;
> > +   }
> > +   ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_SEC,
> > +BD70528_MASK_WDT_SEC, bin2bcd(seconds));
> > +   if (ret)
> > +   dev_err(w->dev, "Failed to set WDT seconds\n");
> > +   else
> > +   dev_dbg(w->dev, "WDT tmo set to %u\n", timeout);
> > +
> > +out_en_unlock:
> > +   ret = bd70528_wdt_set_locked(w, 1);
> > +out_unlock:
> > +   mutex_unlock(w->rtc_lock);
> > +
> > +   return ret;
> > +}
> > +
> > +static const struct watchdog_info bd70528_wdt_info = {
> > +   .identity = "bd70528-wdt",
> > +   .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
> > +};
> > +
> > +static const struct watchdog_ops bd70528_wdt_ops = {
> > +   .start  = bd70528_wdt_start,
> > +   .stop   = bd70528_wdt_stop,
> > +   .set_timeout= bd70528_wdt_set_timeout,
> > +};
> > +
> > +/* Max time we can set is 1 hour, 59 minutes and 59 seconds */
> > +#define WDT_MAX_MS ((2 * 60 * 60 - 1) * 1000)
> > +/* Minimum time is 1 second */
> > +#define WDT_MIN_MS 1000
> > +#define DEFAULT_TIMEOUT 60
> > +
> 
> Please move to top, and tab-align the values.

Ok.

> Otherwise I am ok with the patch.
> 
> On a side note, isn't it past time to drop the RFC ?

Well, the two main things for me to send this as RFC were the
regmap-irq change (which I had already discussed with Mark, and which is
now applied already - so that's Ok) and splitting the existing
include/linux/mfd/rohm-bd718x7.h header (patches 1 - 3). I hoped to get
commnts from Lee, Stephen and Mark for the idea of header split (this
impacts to already submitted bd718x7 driver and I was unsure if this good
or bad approach) but I haven't heard of Lee or Stephen yet.

Still, I have now received acks for dt-bindings, regulators, gpio and
now also for wdt - and I don't think these are heavily impacted even if
the header split was not Ok - so I guess dropping the RFC makes sense.
Thanks for pointing that out.

I'll send v6 with changes you 

Re: [RFC PATCH v5 10/10] watchdog: bd70528: Initial support for ROHM BD70528 watchdog block

2019-02-04 Thread Guenter Roeck

On 2/4/19 4:49 AM, Matti Vaittinen wrote:

Initial support for watchdog block included in ROHM BD70528
power management IC.

Configurations for low power states are still to be checked.

Signed-off-by: Matti Vaittinen 
---
  drivers/watchdog/Kconfig   |  12 +++
  drivers/watchdog/Makefile  |   1 +
  drivers/watchdog/bd70528_wdt.c | 187 +
  3 files changed, 200 insertions(+)
  create mode 100644 drivers/watchdog/bd70528_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 57f017d74a97..f30e3a3e886e 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -90,6 +90,18 @@ config SOFT_WATCHDOG_PRETIMEOUT
  watchdog. Be aware that governors might affect the watchdog because it
  is purely software, e.g. the panic governor will stall it!
  
+config BD70528_WATCHDOG

+   tristate "ROHM BD70528 PMIC Watchdog"
+   depends on MFD_ROHM_BD70528
+   select WATCHDOG_CORE
+   help
+ Support for the watchdog in the ROHM BD70528 PMIC. Watchdog trigger
+ cause system reset.
+
+ Say Y here to include support for the ROHM BD70528 watchdog.
+ Alternatively say M to compile the driver as a module,
+ which will be called bd70528_wdt.
+
  config DA9052_WATCHDOG
tristate "Dialog DA9052 Watchdog"
depends on PMIC_DA9052 || COMPILE_TEST
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index a0917ef28e07..1ce87a3b1172 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -204,6 +204,7 @@ obj-$(CONFIG_WATCHDOG_SUN4V)+= sun4v_wdt.o
  obj-$(CONFIG_XEN_WDT) += xen_wdt.o
  
  # Architecture Independent

+obj-$(CONFIG_BD70528_WATCHDOG) += bd70528_wdt.o
  obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o
  obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o
  obj-$(CONFIG_DA9062_WATCHDOG) += da9062_wdt.o
diff --git a/drivers/watchdog/bd70528_wdt.c b/drivers/watchdog/bd70528_wdt.c
new file mode 100644
index ..c24d4cce5e9c
--- /dev/null
+++ b/drivers/watchdog/bd70528_wdt.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 ROHM Semiconductors
+// ROHM BD70528MWV watchdog driver
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct wdtbd70528 {
+   struct device *dev;
+   struct regmap *regmap;
+   struct mutex *rtc_lock;
+   struct watchdog_device wdt;
+};
+
+static int bd70528_wdt_set_locked(struct wdtbd70528 *w, int enable)
+{
+   struct bd70528 *bd70528;
+
+   bd70528 = container_of(w->rtc_lock, struct bd70528, rtc_timer_lock);
+   return bd70528->wdt_set(bd70528, enable, NULL);
+}


Please add an empty line here.


+static int bd70528_wdt_set(struct wdtbd70528 *w, int enable)
+{
+   int ret;
+
+   mutex_lock(w->rtc_lock);
+   ret = bd70528_wdt_set_locked(w, enable);
+   mutex_unlock(w->rtc_lock);
+
+   return ret;
+}
+
+static int bd70528_wdt_start(struct watchdog_device *wdt)
+{
+   struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
+
+   dev_dbg(w->dev, "WDT ping...\n");
+   return bd70528_wdt_set(w, 1);
+}
+
+static int bd70528_wdt_stop(struct watchdog_device *wdt)
+{
+   struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
+
+   dev_dbg(w->dev, "WDT stopping...\n");
+   return bd70528_wdt_set(w, 0);
+}
+
+static int bd70528_wdt_set_timeout(struct watchdog_device *wdt,
+   unsigned int timeout)
+{
+   unsigned int hours;
+   unsigned int minutes;
+   unsigned int seconds;
+   int ret;
+   struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
+
+   seconds = timeout;
+   hours = timeout / (60 * 60);
+   /* Maximum timeout is 1h 59m 59s => hours is 1 or 0 */
+   if (hours)
+   seconds -= (60 * 60);
+   minutes = seconds / 60;
+   seconds = seconds % 60;
+
+   mutex_lock(w->rtc_lock);
+
+   ret = bd70528_wdt_set_locked(w, 0);
+   if (ret)
+   goto out_unlock;
+
+   ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_HOUR,
+BD70528_MASK_WDT_HOUR, hours);
+   if (ret) {
+   dev_err(w->dev, "Failed to set WDT hours\n");
+   goto out_en_unlock;
+   }
+   ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_MINUTE,
+BD70528_MASK_WDT_MINUTE, bin2bcd(minutes));
+   if (ret) {
+   dev_err(w->dev, "Failed to set WDT minutes\n");
+   goto out_en_unlock;
+   }
+   ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_SEC,
+BD70528_MASK_WDT_SEC, bin2bcd(seconds));
+   if (ret)
+   dev_err(w->dev, "Failed to set WDT seconds\n");
+   else
+   dev_dbg(w->dev, "WDT tmo set to %u\n", timeout);
+
+out_en_unlock:
+   ret = bd70528_wdt_set_locked(w, 1);
+out_unlock:
+   

[RFC PATCH v5 10/10] watchdog: bd70528: Initial support for ROHM BD70528 watchdog block

2019-02-04 Thread Matti Vaittinen
Initial support for watchdog block included in ROHM BD70528
power management IC.

Configurations for low power states are still to be checked.

Signed-off-by: Matti Vaittinen 
---
 drivers/watchdog/Kconfig   |  12 +++
 drivers/watchdog/Makefile  |   1 +
 drivers/watchdog/bd70528_wdt.c | 187 +
 3 files changed, 200 insertions(+)
 create mode 100644 drivers/watchdog/bd70528_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 57f017d74a97..f30e3a3e886e 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -90,6 +90,18 @@ config SOFT_WATCHDOG_PRETIMEOUT
  watchdog. Be aware that governors might affect the watchdog because it
  is purely software, e.g. the panic governor will stall it!
 
+config BD70528_WATCHDOG
+   tristate "ROHM BD70528 PMIC Watchdog"
+   depends on MFD_ROHM_BD70528
+   select WATCHDOG_CORE
+   help
+ Support for the watchdog in the ROHM BD70528 PMIC. Watchdog trigger
+ cause system reset.
+
+ Say Y here to include support for the ROHM BD70528 watchdog.
+ Alternatively say M to compile the driver as a module,
+ which will be called bd70528_wdt.
+
 config DA9052_WATCHDOG
tristate "Dialog DA9052 Watchdog"
depends on PMIC_DA9052 || COMPILE_TEST
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index a0917ef28e07..1ce87a3b1172 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -204,6 +204,7 @@ obj-$(CONFIG_WATCHDOG_SUN4V)+= sun4v_wdt.o
 obj-$(CONFIG_XEN_WDT) += xen_wdt.o
 
 # Architecture Independent
+obj-$(CONFIG_BD70528_WATCHDOG) += bd70528_wdt.o
 obj-$(CONFIG_DA9052_WATCHDOG) += da9052_wdt.o
 obj-$(CONFIG_DA9055_WATCHDOG) += da9055_wdt.o
 obj-$(CONFIG_DA9062_WATCHDOG) += da9062_wdt.o
diff --git a/drivers/watchdog/bd70528_wdt.c b/drivers/watchdog/bd70528_wdt.c
new file mode 100644
index ..c24d4cce5e9c
--- /dev/null
+++ b/drivers/watchdog/bd70528_wdt.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 ROHM Semiconductors
+// ROHM BD70528MWV watchdog driver
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct wdtbd70528 {
+   struct device *dev;
+   struct regmap *regmap;
+   struct mutex *rtc_lock;
+   struct watchdog_device wdt;
+};
+
+static int bd70528_wdt_set_locked(struct wdtbd70528 *w, int enable)
+{
+   struct bd70528 *bd70528;
+
+   bd70528 = container_of(w->rtc_lock, struct bd70528, rtc_timer_lock);
+   return bd70528->wdt_set(bd70528, enable, NULL);
+}
+static int bd70528_wdt_set(struct wdtbd70528 *w, int enable)
+{
+   int ret;
+
+   mutex_lock(w->rtc_lock);
+   ret = bd70528_wdt_set_locked(w, enable);
+   mutex_unlock(w->rtc_lock);
+
+   return ret;
+}
+
+static int bd70528_wdt_start(struct watchdog_device *wdt)
+{
+   struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
+
+   dev_dbg(w->dev, "WDT ping...\n");
+   return bd70528_wdt_set(w, 1);
+}
+
+static int bd70528_wdt_stop(struct watchdog_device *wdt)
+{
+   struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
+
+   dev_dbg(w->dev, "WDT stopping...\n");
+   return bd70528_wdt_set(w, 0);
+}
+
+static int bd70528_wdt_set_timeout(struct watchdog_device *wdt,
+   unsigned int timeout)
+{
+   unsigned int hours;
+   unsigned int minutes;
+   unsigned int seconds;
+   int ret;
+   struct wdtbd70528 *w = watchdog_get_drvdata(wdt);
+
+   seconds = timeout;
+   hours = timeout / (60 * 60);
+   /* Maximum timeout is 1h 59m 59s => hours is 1 or 0 */
+   if (hours)
+   seconds -= (60 * 60);
+   minutes = seconds / 60;
+   seconds = seconds % 60;
+
+   mutex_lock(w->rtc_lock);
+
+   ret = bd70528_wdt_set_locked(w, 0);
+   if (ret)
+   goto out_unlock;
+
+   ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_HOUR,
+BD70528_MASK_WDT_HOUR, hours);
+   if (ret) {
+   dev_err(w->dev, "Failed to set WDT hours\n");
+   goto out_en_unlock;
+   }
+   ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_MINUTE,
+BD70528_MASK_WDT_MINUTE, bin2bcd(minutes));
+   if (ret) {
+   dev_err(w->dev, "Failed to set WDT minutes\n");
+   goto out_en_unlock;
+   }
+   ret = regmap_update_bits(w->regmap, BD70528_REG_WDT_SEC,
+BD70528_MASK_WDT_SEC, bin2bcd(seconds));
+   if (ret)
+   dev_err(w->dev, "Failed to set WDT seconds\n");
+   else
+   dev_dbg(w->dev, "WDT tmo set to %u\n", timeout);
+
+out_en_unlock:
+   ret = bd70528_wdt_set_locked(w, 1);
+out_unlock:
+   mutex_unlock(w->rtc_lock);
+
+   return ret;
+}
+
+static const struct watchdog_info