diff mbox

[v4,5/7] watchdog: moxart: Register restart handler with restart notifier

Message ID 1405265431-4561-6-git-send-email-linux@roeck-us.net (mailing list archive)
State New, archived
Headers show

Commit Message

Guenter Roeck July 13, 2014, 3:30 p.m. UTC
The kernel now provides an API to trigger a system restart.
Register with it instead of setting arm_pm_restart.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
v4: Set notifier priority to 128.
v3: Move struct notifier_block into struct moxart_wdt_dev.
    Drop static variable previously needed to access struct moxart_wdt_dev
    from notifier function; use container_of instead.
v2: No change.

 drivers/watchdog/moxart_wdt.c | 32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

Comments

Catalin Marinas July 14, 2014, 2:19 p.m. UTC | #1
On Sun, Jul 13, 2014 at 04:30:29PM +0100, Guenter Roeck wrote:
> diff --git a/drivers/watchdog/moxart_wdt.c b/drivers/watchdog/moxart_wdt.c
> index 4aa3a8a..5080b50 100644
> --- a/drivers/watchdog/moxart_wdt.c
> +++ b/drivers/watchdog/moxart_wdt.c
[...]
> -static void moxart_wdt_restart(enum reboot_mode reboot_mode, const char *cmd)
> +static int moxart_restart_notify(struct notifier_block *this,
> +				 unsigned long mode, void *cmd)
>  {
> -	writel(1, moxart_restart_ctx->base + REG_COUNT);
> -	writel(0x5ab9, moxart_restart_ctx->base + REG_MODE);
> -	writel(0x03, moxart_restart_ctx->base + REG_ENABLE);
> +	struct moxart_wdt_dev *moxart_wdt = container_of(this,
> +							 struct moxart_wdt_dev,
> +							 restart_notifier);
> +	writel(1, moxart_wdt->base + REG_COUNT);
> +	writel(0x5ab9, moxart_wdt->base + REG_MODE);
> +	writel(0x03, moxart_wdt->base + REG_ENABLE);
> +
> +	return NOTIFY_DONE;
>  }

Wondering whether NOTIFY_OK or even NOTIFY_STOP_MASK is better here.
Guenter Roeck July 14, 2014, 2:41 p.m. UTC | #2
On 07/14/2014 07:19 AM, Catalin Marinas wrote:
> On Sun, Jul 13, 2014 at 04:30:29PM +0100, Guenter Roeck wrote:
>> diff --git a/drivers/watchdog/moxart_wdt.c b/drivers/watchdog/moxart_wdt.c
>> index 4aa3a8a..5080b50 100644
>> --- a/drivers/watchdog/moxart_wdt.c
>> +++ b/drivers/watchdog/moxart_wdt.c
> [...]
>> -static void moxart_wdt_restart(enum reboot_mode reboot_mode, const char *cmd)
>> +static int moxart_restart_notify(struct notifier_block *this,
>> +				 unsigned long mode, void *cmd)
>>   {
>> -	writel(1, moxart_restart_ctx->base + REG_COUNT);
>> -	writel(0x5ab9, moxart_restart_ctx->base + REG_MODE);
>> -	writel(0x03, moxart_restart_ctx->base + REG_ENABLE);
>> +	struct moxart_wdt_dev *moxart_wdt = container_of(this,
>> +							 struct moxart_wdt_dev,
>> +							 restart_notifier);
>> +	writel(1, moxart_wdt->base + REG_COUNT);
>> +	writel(0x5ab9, moxart_wdt->base + REG_MODE);
>> +	writel(0x03, moxart_wdt->base + REG_ENABLE);
>> +
>> +	return NOTIFY_DONE;
>>   }
>
> Wondering whether NOTIFY_OK or even NOTIFY_STOP_MASK is better here.
>

Personally I would rather call all of them if more than one notifier is
registered to ensure that (at least) one does what it is intended to do,
but I am open to suggestions.

Guenter
Catalin Marinas July 14, 2014, 3:11 p.m. UTC | #3
On Mon, Jul 14, 2014 at 03:41:15PM +0100, Guenter Roeck wrote:
> On 07/14/2014 07:19 AM, Catalin Marinas wrote:
> > On Sun, Jul 13, 2014 at 04:30:29PM +0100, Guenter Roeck wrote:
> >> diff --git a/drivers/watchdog/moxart_wdt.c b/drivers/watchdog/moxart_wdt.c
> >> index 4aa3a8a..5080b50 100644
> >> --- a/drivers/watchdog/moxart_wdt.c
> >> +++ b/drivers/watchdog/moxart_wdt.c
> > [...]
> >> -static void moxart_wdt_restart(enum reboot_mode reboot_mode, const char *cmd)
> >> +static int moxart_restart_notify(struct notifier_block *this,
> >> +				 unsigned long mode, void *cmd)
> >>   {
> >> -	writel(1, moxart_restart_ctx->base + REG_COUNT);
> >> -	writel(0x5ab9, moxart_restart_ctx->base + REG_MODE);
> >> -	writel(0x03, moxart_restart_ctx->base + REG_ENABLE);
> >> +	struct moxart_wdt_dev *moxart_wdt = container_of(this,
> >> +							 struct moxart_wdt_dev,
> >> +							 restart_notifier);
> >> +	writel(1, moxart_wdt->base + REG_COUNT);
> >> +	writel(0x5ab9, moxart_wdt->base + REG_MODE);
> >> +	writel(0x03, moxart_wdt->base + REG_ENABLE);
> >> +
> >> +	return NOTIFY_DONE;
> >>   }
> >
> > Wondering whether NOTIFY_OK or even NOTIFY_STOP_MASK is better here.
> 
> Personally I would rather call all of them if more than one notifier is
> registered to ensure that (at least) one does what it is intended to do,
> but I am open to suggestions.

Probably fine. I guess there won't be more than one handler registered
in most cases anyway.
diff mbox

Patch

diff --git a/drivers/watchdog/moxart_wdt.c b/drivers/watchdog/moxart_wdt.c
index 4aa3a8a..5080b50 100644
--- a/drivers/watchdog/moxart_wdt.c
+++ b/drivers/watchdog/moxart_wdt.c
@@ -15,12 +15,12 @@ 
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
+#include <linux/notifier.h>
 #include <linux/platform_device.h>
+#include <linux/reboot.h>
 #include <linux/watchdog.h>
 #include <linux/moduleparam.h>
 
-#include <asm/system_misc.h>
-
 #define REG_COUNT			0x4
 #define REG_MODE			0x8
 #define REG_ENABLE			0xC
@@ -29,17 +29,22 @@  struct moxart_wdt_dev {
 	struct watchdog_device dev;
 	void __iomem *base;
 	unsigned int clock_frequency;
+	struct notifier_block restart_notifier;
 };
 
-static struct moxart_wdt_dev *moxart_restart_ctx;
-
 static int heartbeat;
 
-static void moxart_wdt_restart(enum reboot_mode reboot_mode, const char *cmd)
+static int moxart_restart_notify(struct notifier_block *this,
+				 unsigned long mode, void *cmd)
 {
-	writel(1, moxart_restart_ctx->base + REG_COUNT);
-	writel(0x5ab9, moxart_restart_ctx->base + REG_MODE);
-	writel(0x03, moxart_restart_ctx->base + REG_ENABLE);
+	struct moxart_wdt_dev *moxart_wdt = container_of(this,
+							 struct moxart_wdt_dev,
+							 restart_notifier);
+	writel(1, moxart_wdt->base + REG_COUNT);
+	writel(0x5ab9, moxart_wdt->base + REG_MODE);
+	writel(0x03, moxart_wdt->base + REG_ENABLE);
+
+	return NOTIFY_DONE;
 }
 
 static int moxart_wdt_stop(struct watchdog_device *wdt_dev)
@@ -136,8 +141,12 @@  static int moxart_wdt_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
-	moxart_restart_ctx = moxart_wdt;
-	arm_pm_restart = moxart_wdt_restart;
+	moxart_wdt->restart_notifier.notifier_call = moxart_restart_notify;
+	moxart_wdt->restart_notifier.priority = 128;
+	err = register_restart_notifier(&moxart_wdt->restart_notifier);
+	if (err)
+		dev_err(dev, "cannot register restart notifier (err=%d)\n",
+			err);
 
 	dev_dbg(dev, "Watchdog enabled (heartbeat=%d sec, nowayout=%d)\n",
 		moxart_wdt->dev.timeout, nowayout);
@@ -149,9 +158,8 @@  static int moxart_wdt_remove(struct platform_device *pdev)
 {
 	struct moxart_wdt_dev *moxart_wdt = platform_get_drvdata(pdev);
 
-	arm_pm_restart = NULL;
+	unregister_restart_notifier(&moxart_wdt->restart_notifier);
 	moxart_wdt_stop(&moxart_wdt->dev);
-	watchdog_unregister_device(&moxart_wdt->dev);
 
 	return 0;
 }