All of lore.kernel.org
 help / color / mirror / Atom feed
From: Guenter Roeck <linux@roeck-us.net>
To: Damien Riegel <damien.riegel@savoirfairelinux.com>,
	linux-watchdog@vger.kernel.org
Cc: Wim Van Sebroeck <wim@iguana.be>,
	Vivien Didelot <vivien.didelot@savoirfairelinux.com>,
	kernel@savoirfairelinux.com
Subject: Re: [RFC PATCH 01/13] watchdog: core: add restart handler support
Date: Mon, 2 Nov 2015 18:25:07 -0800	[thread overview]
Message-ID: <56381B03.6030201@roeck-us.net> (raw)
In-Reply-To: <1446514586-31455-2-git-send-email-damien.riegel@savoirfairelinux.com>

On 11/02/2015 05:36 PM, Damien Riegel wrote:
> Many watchdog drivers implement the same code to register a restart
> handler. This patch provides a generic way to set such a function.
>
> The patch adds a new restart watchdog operation. If a restart priority
> greater than 0 is needed, the driver can call
> watchdog_set_restart_priority to set it.
>
> Signed-off-by: Damien Riegel <damien.riegel@savoirfairelinux.com>
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>

Makes sense, and good idea. Unless the patch was written by Vivien,
the second tag should probably be a Reviewed-by: or Acked-by:, though.

Couple of additional comments below.

> ---
>   Documentation/watchdog/watchdog-kernel-api.txt |  2 ++
>   drivers/watchdog/watchdog_core.c               | 35 ++++++++++++++++++++++++++
>   include/linux/watchdog.h                       |  5 ++++
>   3 files changed, 42 insertions(+)
>
> diff --git a/Documentation/watchdog/watchdog-kernel-api.txt b/Documentation/watchdog/watchdog-kernel-api.txt
> index d8b0d33..10e6132 100644
> --- a/Documentation/watchdog/watchdog-kernel-api.txt
> +++ b/Documentation/watchdog/watchdog-kernel-api.txt
> @@ -100,6 +100,7 @@ struct watchdog_ops {
>   	unsigned int (*status)(struct watchdog_device *);
>   	int (*set_timeout)(struct watchdog_device *, unsigned int);
>   	unsigned int (*get_timeleft)(struct watchdog_device *);
> +	int (*restart)(struct watchdog_device *);
>   	void (*ref)(struct watchdog_device *);
>   	void (*unref)(struct watchdog_device *);
>   	long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
> @@ -164,6 +165,7 @@ they are supported. These optional routines/operations are:
>     (Note: the WDIOF_SETTIMEOUT needs to be set in the options field of the
>     watchdog's info structure).
>   * get_timeleft: this routines returns the time that's left before a reset.
> +* restart: this routine restarts the machine.

Please describe the expected return values.
0 - ok, or a negative error value, presumably.

>   * ref: the operation that calls kref_get on the kref of a dynamically
>     allocated watchdog_device struct.
>   * unref: the operation that calls kref_put on the kref of a dynamically
> diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c
> index 873f139..9c8a8e8 100644
> --- a/drivers/watchdog/watchdog_core.c
> +++ b/drivers/watchdog/watchdog_core.c
> @@ -32,6 +32,7 @@
>   #include <linux/types.h>	/* For standard types */
>   #include <linux/errno.h>	/* For the -ENODEV/... values */
>   #include <linux/kernel.h>	/* For printk/panic/... */
> +#include <linux/reboot.h>	/* For restart handler */
>   #include <linux/watchdog.h>	/* For watchdog specific items */
>   #include <linux/init.h>		/* For __init/__exit/... */
>   #include <linux/idr.h>		/* For ida_* macros */
> @@ -137,6 +138,28 @@ int watchdog_init_timeout(struct watchdog_device *wdd,
>   }
>   EXPORT_SYMBOL_GPL(watchdog_init_timeout);
>
> +static int watchdog_restart_notifier(struct notifier_block *nb,
> +				     unsigned long action, void *data)
> +{
> +	struct watchdog_device *wdd = container_of(nb, struct watchdog_device,
> +						   restart_nb);
> +
> +	int ret;
> +
> +	ret = wdd->ops->restart(wdd);
> +	if (ret)
> +		return NOTIFY_BAD;
> +
> +	return NOTIFY_DONE;
> +}
> +
> +void watchdog_set_restart_priority(struct watchdog_device *wdd,
> +				   int priority)

Fits one line.

> +{
> +	wdd->restart_nb.priority = priority;
> +}
> +EXPORT_SYMBOL_GPL(watchdog_set_restart_priority);
> +
>   static int __watchdog_register_device(struct watchdog_device *wdd)
>   {
>   	int ret, id = -1, devno;
> @@ -202,6 +225,15 @@ static int __watchdog_register_device(struct watchdog_device *wdd)
>   		return ret;
>   	}
>
> +	if (wdd->ops->restart) {
> +		wdd->restart_nb.notifier_call = watchdog_restart_notifier;
> +
> +		ret = register_restart_handler(&wdd->restart_nb);
> +		if (ret)
> +			dev_err(wdd->dev, "Cannot register restart handler (%d)\n",
> +				ret);

dev_warn, please.

> +	}
> +
>   	return 0;
>   }
>
> @@ -238,6 +270,9 @@ static void __watchdog_unregister_device(struct watchdog_device *wdd)
>   	if (wdd == NULL)
>   		return;
>
> +	if (wdd->ops->restart)
> +		unregister_restart_handler(&wdd->restart_nb);
> +
>   	devno = wdd->cdev.dev;
>   	ret = watchdog_dev_unregister(wdd);
>   	if (ret)
> diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h
> index e90e3ea..e1a4dc4 100644
> --- a/include/linux/watchdog.h
> +++ b/include/linux/watchdog.h
> @@ -26,6 +26,7 @@ struct watchdog_device;
>    * @status:	The routine that shows the status of the watchdog device.
>    * @set_timeout:The routine for setting the watchdog devices timeout value.
>    * @get_timeleft:The routine that get's the time that's left before a reset.
> + * @restart:	The routine for restarting the machine.
>    * @ref:	The ref operation for dyn. allocated watchdog_device structs
>    * @unref:	The unref operation for dyn. allocated watchdog_device structs
>    * @ioctl:	The routines that handles extra ioctl calls.
> @@ -45,6 +46,7 @@ struct watchdog_ops {
>   	unsigned int (*status)(struct watchdog_device *);
>   	int (*set_timeout)(struct watchdog_device *, unsigned int);
>   	unsigned int (*get_timeleft)(struct watchdog_device *);
> +	int (*restart)(struct watchdog_device *);
>   	void (*ref)(struct watchdog_device *);
>   	void (*unref)(struct watchdog_device *);
>   	long (*ioctl)(struct watchdog_device *, unsigned int, unsigned long);
> @@ -88,6 +90,7 @@ struct watchdog_device {
>   	unsigned int timeout;
>   	unsigned int min_timeout;
>   	unsigned int max_timeout;
> +	struct notifier_block restart_nb;
>   	void *driver_data;
>   	struct mutex lock;
>   	unsigned long status;
> @@ -142,6 +145,8 @@ static inline void *watchdog_get_drvdata(struct watchdog_device *wdd)
>   }
>
>   /* drivers/watchdog/watchdog_core.c */
> +extern void watchdog_set_restart_priority(struct watchdog_device *wdd,
> +					  int priority);

extern is unnecessary (yes, we'll need to fix that for the other exported
functions, but no need to introduce new ones), and then it fits one line.

>   extern int watchdog_init_timeout(struct watchdog_device *wdd,
>   				  unsigned int timeout_parm, struct device *dev);
>   extern int watchdog_register_device(struct watchdog_device *);
>


  reply	other threads:[~2015-11-03  2:25 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-03  1:36 [RFC PATCH 00/13] watchdog: factorize restart handler registration Damien Riegel
2015-11-03  1:36 ` [RFC PATCH 01/13] watchdog: core: add restart handler support Damien Riegel
2015-11-03  2:25   ` Guenter Roeck [this message]
2015-11-03  2:51     ` Vivien Didelot
2015-11-03  3:14       ` Guenter Roeck
2015-11-03  1:36 ` [RFC PATCH 02/13] watchdog: bcm47xx_wdt: use core restart handler Damien Riegel
2015-11-03  2:26   ` Guenter Roeck
2015-11-03 14:21     ` Vivien Didelot
2015-11-03 14:46       ` Guenter Roeck
2015-11-03  1:36 ` [RFC PATCH 03/13] watchdog: da9063_wdt: " Damien Riegel
2015-11-03  2:26   ` Guenter Roeck
2015-11-03  1:36 ` [RFC PATCH 04/13] watchdog: digicolor_wdt: " Damien Riegel
2015-11-03  2:27   ` Guenter Roeck
2015-11-03  1:36 ` [RFC PATCH 05/13] watchdog: imgpdc_wdt: " Damien Riegel
2015-11-03  2:28   ` Guenter Roeck
2015-11-03  1:36 ` [RFC PATCH 06/13] watchdog: imx2_wdt: " Damien Riegel
2015-11-03  2:29   ` Guenter Roeck
2015-11-03  1:36 ` [RFC PATCH 07/13] watchdog: lpc18xx_wdt: " Damien Riegel
2015-11-03  2:30   ` Guenter Roeck
2015-11-03  1:36 ` [RFC PATCH 08/13] watchdog: meson_wdt: " Damien Riegel
2015-11-03  2:31   ` Guenter Roeck
2015-11-03  1:36 ` [RFC PATCH 09/13] watchdog: moxart_wdt: " Damien Riegel
2015-11-03  2:32   ` Guenter Roeck
2015-11-03  1:36 ` [RFC PATCH 10/13] watchdog: mtk_wdt: " Damien Riegel
2015-11-03  2:35   ` Guenter Roeck
2015-11-03  1:36 ` [RFC PATCH 11/13] watchdog: qcom-wdt: " Damien Riegel
2015-11-03  2:37   ` Guenter Roeck
2015-11-03  1:36 ` [RFC PATCH 12/13] watchdog: s3c2410_wdt: " Damien Riegel
2015-11-03  2:38   ` Guenter Roeck
2015-11-03  1:36 ` [RFC PATCH 13/13] watchdog: sunxi_wdt: " Damien Riegel
2015-11-03  2:41   ` Guenter Roeck

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=56381B03.6030201@roeck-us.net \
    --to=linux@roeck-us.net \
    --cc=damien.riegel@savoirfairelinux.com \
    --cc=kernel@savoirfairelinux.com \
    --cc=linux-watchdog@vger.kernel.org \
    --cc=vivien.didelot@savoirfairelinux.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.