All of lore.kernel.org
 help / color / mirror / Atom feed
From: Guenter Roeck <linux@roeck-us.net>
To: Luca Ceresoli <luca@lucaceresoli.net>, linux-kernel@vger.kernel.org
Cc: Lee Jones <lee.jones@linaro.org>,
	Rob Herring <robh+dt@kernel.org>,
	Alessandro Zummo <a.zummo@towertech.it>,
	Alexandre Belloni <alexandre.belloni@bootlin.com>,
	Chanwoo Choi <cw00.choi@samsung.com>,
	Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>,
	Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
	Wim Van Sebroeck <wim@linux-watchdog.org>,
	devicetree@vger.kernel.org, linux-rtc@vger.kernel.org,
	linux-watchdog@vger.kernel.org,
	Chiwoong Byun <woong.byun@samsung.com>,
	Laxman Dewangan <ldewangan@nvidia.com>,
	Randy Dunlap <rdunlap@infradead.org>
Subject: Re: [PATCH v2 8/9] watchdog: max77714: add driver for the watchdog in the MAX77714 PMIC
Date: Tue, 19 Oct 2021 08:10:13 -0700	[thread overview]
Message-ID: <f14e0a94-f283-7be4-761c-9dc725a1add0@roeck-us.net> (raw)
In-Reply-To: <20211019145919.7327-9-luca@lucaceresoli.net>

On 10/19/21 7:59 AM, Luca Ceresoli wrote:
> Add a simple driver to support the watchdog embedded in the Maxim MAX77714
> PMIC.
> 
> Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net>

Acked-by: Guenter Roeck <linux@roeck-us.net>

The driver needs the include file introduced with the mfd driver,
so I assume it will be submitted through the mfd branch.

Thanks,
Guenter

> 
> ---
> 
> Changes in v2:
>   - fix Kconfig help indentation (Randy Dunlap)
>   - make max77714_margin_value static const (Guenter Roeck)
>   - fix platform module instantiation
> ---
>   MAINTAINERS                     |   1 +
>   drivers/watchdog/Kconfig        |   9 ++
>   drivers/watchdog/Makefile       |   1 +
>   drivers/watchdog/max77714_wdt.c | 179 ++++++++++++++++++++++++++++++++
>   4 files changed, 190 insertions(+)
>   create mode 100644 drivers/watchdog/max77714_wdt.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index abd9de8a9d99..71c3d8513ba0 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11391,6 +11391,7 @@ M:	Luca Ceresoli <luca@lucaceresoli.net>
>   S:	Maintained
>   F:	Documentation/devicetree/bindings/mfd/maxim,max77714.yaml
>   F:	drivers/mfd/max77714.c
> +F:	drivers/watchdog/max77714_wdt.c
>   F:	include/linux/mfd/max77714.h
>   
>   MAXIM MAX77802 PMIC REGULATOR DEVICE DRIVER
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index a24385099a91..b9b575acd690 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -699,6 +699,15 @@ config MAX77620_WATCHDOG
>   	  MAX77620 chips. To compile this driver as a module,
>   	  choose M here: the module will be called max77620_wdt.
>   
> +config MAX77714_WATCHDOG
> +	tristate "Maxim MAX77714 Watchdog Timer"
> +	depends on MFD_MAX77714 || COMPILE_TEST
> +	help
> +	  This is the driver for watchdog timer in the MAX77714 PMIC.
> +	  Say 'Y' here to enable the watchdog timer support for MAX77714
> +	  chips. To compile this driver as a module, choose M here: the
> +	  module will be called max77714_wdt.
> +
>   config IMX2_WDT
>   	tristate "IMX2+ Watchdog"
>   	depends on ARCH_MXC || ARCH_LAYERSCAPE || COMPILE_TEST
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index 1bd2d6f37c53..268a942311a0 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -215,6 +215,7 @@ obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o
>   obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o
>   obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o
>   obj-$(CONFIG_MAX77620_WATCHDOG) += max77620_wdt.o
> +obj-$(CONFIG_MAX77714_WATCHDOG) += max77714_wdt.o
>   obj-$(CONFIG_ZIIRAVE_WATCHDOG) += ziirave_wdt.o
>   obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
>   obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wdt.o
> diff --git a/drivers/watchdog/max77714_wdt.c b/drivers/watchdog/max77714_wdt.c
> new file mode 100644
> index 000000000000..cce6c13d76eb
> --- /dev/null
> +++ b/drivers/watchdog/max77714_wdt.c
> @@ -0,0 +1,179 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Maxim MAX77714 Watchdog Driver
> + *
> + * Copyright (C) 2021 Luca Ceresoli
> + * Author: Luca Ceresoli <luca@lucaceresoli.net>
> + */
> +
> +#include <linux/err.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/max77714.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/watchdog.h>
> +
> +struct max77714_wdt {
> +	struct device		*dev;
> +	struct regmap		*rmap;
> +	struct watchdog_device	wd_dev;
> +};
> +
> +/* Timeout in seconds, indexed by TWD bits of CNFG_GLBL2 register */
> +static const unsigned int max77714_margin_value[] = { 2, 16, 64, 128 };
> +
> +static int max77714_wdt_start(struct watchdog_device *wd_dev)
> +{
> +	struct max77714_wdt *wdt = watchdog_get_drvdata(wd_dev);
> +
> +	return regmap_update_bits(wdt->rmap, MAX77714_CNFG_GLBL2,
> +				  MAX77714_WDTEN, MAX77714_WDTEN);
> +}
> +
> +static int max77714_wdt_stop(struct watchdog_device *wd_dev)
> +{
> +	struct max77714_wdt *wdt = watchdog_get_drvdata(wd_dev);
> +
> +	return regmap_update_bits(wdt->rmap, MAX77714_CNFG_GLBL2,
> +				  MAX77714_WDTEN, 0);
> +}
> +
> +static int max77714_wdt_ping(struct watchdog_device *wd_dev)
> +{
> +	struct max77714_wdt *wdt = watchdog_get_drvdata(wd_dev);
> +
> +	return regmap_update_bits(wdt->rmap, MAX77714_CNFG_GLBL3,
> +				  MAX77714_WDTC, 1);
> +}
> +
> +static int max77714_wdt_set_timeout(struct watchdog_device *wd_dev,
> +				    unsigned int timeout)
> +{
> +	struct max77714_wdt *wdt = watchdog_get_drvdata(wd_dev);
> +	unsigned int new_timeout, new_twd;
> +	int err;
> +
> +	for (new_twd = 0; new_twd < ARRAY_SIZE(max77714_margin_value) - 1; new_twd++)
> +		if (timeout <= max77714_margin_value[new_twd])
> +			break;
> +
> +	/* new_wdt is not out of bounds here due to the "- 1" in the for loop */
> +	new_timeout = max77714_margin_value[new_twd];
> +
> +	/*
> +	 * "If the value of TWD needs to be changed, clear the system
> +	 * watchdog timer first [...], then change the value of TWD."
> +	 * (MAX77714 datasheet)
> +	 */
> +	err = regmap_update_bits(wdt->rmap, MAX77714_CNFG_GLBL3,
> +				 MAX77714_WDTC, 1);
> +	if (err)
> +		return err;
> +
> +	err = regmap_update_bits(wdt->rmap, MAX77714_CNFG_GLBL2,
> +				 MAX77714_TWD_MASK, new_twd);
> +	if (err)
> +		return err;
> +
> +	wd_dev->timeout = new_timeout;
> +
> +	dev_dbg(wdt->dev, "New timeout = %u s (WDT = 0x%x)", new_timeout, new_twd);
> +
> +	return 0;
> +}
> +
> +static const struct watchdog_info max77714_wdt_info = {
> +	.identity = "max77714-watchdog",
> +	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
> +};
> +
> +static const struct watchdog_ops max77714_wdt_ops = {
> +	.start		= max77714_wdt_start,
> +	.stop		= max77714_wdt_stop,
> +	.ping		= max77714_wdt_ping,
> +	.set_timeout	= max77714_wdt_set_timeout,
> +};
> +
> +static int max77714_wdt_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct max77714_wdt *wdt;
> +	struct watchdog_device *wd_dev;
> +	unsigned int regval;
> +	int err;
> +
> +	wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
> +	if (!wdt)
> +		return -ENOMEM;
> +
> +	wdt->dev = dev;
> +
> +	wd_dev = &wdt->wd_dev;
> +	wd_dev->info = &max77714_wdt_info;
> +	wd_dev->ops = &max77714_wdt_ops;
> +	wd_dev->min_timeout = 2;
> +	wd_dev->max_timeout = 128;
> +
> +	platform_set_drvdata(pdev, wdt);
> +	watchdog_set_drvdata(wd_dev, wdt);
> +
> +	wdt->rmap = dev_get_regmap(dev->parent, NULL);
> +	if (!wdt->rmap)
> +		return dev_err_probe(wdt->dev, -ENODEV, "Failed to get parent regmap\n");
> +
> +	/* WD_RST_WK: if 1 wdog restarts; if 0 wdog shuts down */
> +	err = regmap_update_bits(wdt->rmap, MAX77714_CNFG2_ONOFF,
> +				 MAX77714_WD_RST_WK, MAX77714_WD_RST_WK);
> +	if (err)
> +		return dev_err_probe(wdt->dev, err, "Error updating CNFG2_ONOFF\n");
> +
> +	err = regmap_read(wdt->rmap, MAX77714_CNFG_GLBL2, &regval);
> +	if (err)
> +		return dev_err_probe(wdt->dev, err, "Error reading CNFG_GLBL2\n");
> +
> +	/* enable watchdog | enable auto-clear in sleep state */
> +	regval |= (MAX77714_WDTEN | MAX77714_WDTSLPC);
> +
> +	err = regmap_write(wdt->rmap, MAX77714_CNFG_GLBL2, regval);
> +	if (err)
> +		return dev_err_probe(wdt->dev, err, "Error writing CNFG_GLBL2\n");
> +
> +	wd_dev->timeout = max77714_margin_value[regval & MAX77714_TWD_MASK];
> +
> +	dev_dbg(wdt->dev, "Timeout = %u s (WDT = 0x%x)",
> +		wd_dev->timeout, regval & MAX77714_TWD_MASK);
> +
> +	set_bit(WDOG_HW_RUNNING, &wd_dev->status);
> +
> +	watchdog_stop_on_unregister(wd_dev);
> +
> +	err = devm_watchdog_register_device(dev, wd_dev);
> +	if (err)
> +		return dev_err_probe(dev, err, "Cannot register watchdog device\n");
> +
> +	dev_info(dev, "registered as /dev/watchdog%d\n", wd_dev->id);
> +
> +	return 0;
> +}
> +
> +static const struct platform_device_id max77714_wdt_platform_id[] = {
> +	{ .name = "max77714-watchdog", },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(platform, max77714_wdt_platform_id);
> +
> +static struct platform_driver max77714_wdt_driver = {
> +	.driver	= {
> +		.name	= "max77714-watchdog",
> +	},
> +	.probe	= max77714_wdt_probe,
> +	.id_table = max77714_wdt_platform_id,
> +};
> +
> +module_platform_driver(max77714_wdt_driver);
> +
> +MODULE_DESCRIPTION("MAX77714 watchdog timer driver");
> +MODULE_AUTHOR("Luca Ceresoli <luca@lucaceresoli.net>");
> +MODULE_LICENSE("GPL v2");
> 


  reply	other threads:[~2021-10-19 15:10 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-19 14:59 [PATCH v2 0/9] Add MAX77714 PMIC minimal driver (RTC and watchdog only) Luca Ceresoli
2021-10-19 14:59 ` [PATCH v2 1/9] mfd: max77686: Correct tab-based alignment of register addresses Luca Ceresoli
2021-10-21 15:53   ` Lee Jones
2021-10-19 14:59 ` [PATCH v2 2/9] rtc: max77686: convert comments to kernel-doc format Luca Ceresoli
2021-10-19 14:59 ` [PATCH v2 3/9] rtc: max77686: rename day-of-month defines Luca Ceresoli
2021-10-21  9:42   ` Alexandre Belloni
2021-10-19 14:59 ` [PATCH v2 4/9] rtc: max77686: remove unused code to read in 12-hour mode Luca Ceresoli
2021-10-21  9:43   ` Alexandre Belloni
2021-10-19 14:59 ` [PATCH v2 5/9] dt-bindings: mfd: add Maxim MAX77714 PMIC Luca Ceresoli
2021-10-27  3:17   ` Rob Herring
2021-10-29 15:50     ` Luca Ceresoli
2021-10-19 14:59 ` [PATCH v2 6/9] mfd: max77714: Add driver for " Luca Ceresoli
2021-10-20  7:00   ` Krzysztof Kozlowski
2021-10-21 18:43   ` Lee Jones
2021-10-27 10:32     ` Luca Ceresoli
2021-10-27 13:44       ` Lee Jones
2021-10-27 14:23         ` Luca Ceresoli
2021-10-19 14:59 ` [PATCH v2 7/9] watchdog: Kconfig: fix help text indentation Luca Ceresoli
2021-10-19 15:06   ` Guenter Roeck
2021-10-21 16:28     ` Luca Ceresoli
2021-10-19 14:59 ` [PATCH v2 8/9] watchdog: max77714: add driver for the watchdog in the MAX77714 PMIC Luca Ceresoli
2021-10-19 15:10   ` Guenter Roeck [this message]
2021-10-19 14:59 ` [PATCH v2 9/9] rtc: max77686: add MAX77714 support Luca Ceresoli

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=f14e0a94-f283-7be4-761c-9dc725a1add0@roeck-us.net \
    --to=linux@roeck-us.net \
    --cc=a.zummo@towertech.it \
    --cc=alexandre.belloni@bootlin.com \
    --cc=b.zolnierkie@samsung.com \
    --cc=cw00.choi@samsung.com \
    --cc=devicetree@vger.kernel.org \
    --cc=krzysztof.kozlowski@canonical.com \
    --cc=ldewangan@nvidia.com \
    --cc=lee.jones@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rtc@vger.kernel.org \
    --cc=linux-watchdog@vger.kernel.org \
    --cc=luca@lucaceresoli.net \
    --cc=rdunlap@infradead.org \
    --cc=robh+dt@kernel.org \
    --cc=wim@linux-watchdog.org \
    --cc=woong.byun@samsung.com \
    /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.