From: Guenter Roeck <linux@roeck-us.net>
To: Sergey Ryazanov <ryazanov.s.a@gmail.com>
Cc: Ralf Baechle <ralf@linux-mips.org>,
Linux MIPS <linux-mips@linux-mips.org>,
Wim Van Sebroeck <wim@iguana.be>,
linux-watchdog@vger.kernel.org
Subject: Re: [PATCH 12/16] watchdog: add Atheros AR2315 watchdog driver
Date: Mon, 29 Sep 2014 13:46:19 -0700 [thread overview]
Message-ID: <20140929204619.GA32273@roeck-us.net> (raw)
In-Reply-To: <CAHNKnsRCsz=m1bJX+LmAOh8CLUuuAvGmva8NpYvQSa4VK1L=PA@mail.gmail.com>
On Tue, Sep 30, 2014 at 12:14:58AM +0400, Sergey Ryazanov wrote:
> 2014-09-29 1:35 GMT+04:00 Guenter Roeck <linux@roeck-us.net>:
> > On 09/28/2014 11:33 AM, Sergey Ryazanov wrote:
> >>
> >> Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
> >> Cc: Wim Van Sebroeck <wim@iguana.be>
> >> Cc: linux-watchdog@vger.kernel.org
> >> ---
> >>
> >> Changes since RFC:
> >> - use watchdog infrastructure
> >> - remove deprecated IRQF_DISABLED flag
> >> - move device registration to separate patch
> >>
> >> drivers/watchdog/Kconfig | 8 ++
> >> drivers/watchdog/Makefile | 1 +
> >> drivers/watchdog/ar2315-wtd.c | 167
> >> ++++++++++++++++++++++++++++++++++++++++++
> >> 3 files changed, 176 insertions(+)
> >> create mode 100644 drivers/watchdog/ar2315-wtd.c
> >>
> >> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> >> index f57312f..dbace99 100644
> >> --- a/drivers/watchdog/Kconfig
> >> +++ b/drivers/watchdog/Kconfig
> >> @@ -1186,6 +1186,14 @@ config RALINK_WDT
> >> help
> >> Hardware driver for the Ralink SoC Watchdog Timer.
> >>
> >> +config AR2315_WDT
> >> + tristate "Atheros AR2315+ WiSoCs Watchdog Timer"
> >> + select WATCHDOG_CORE
> >> + depends on SOC_AR2315
> >> + help
> >> + Hardware driver for the built-in watchdog timer on the Atheros
> >> + AR2315/AR2316 WiSoCs.
> >> +
> >> # PARISC Architecture
> >>
> >> # POWERPC Architecture
> >> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> >> index 468c320..ef7f83b 100644
> >> --- a/drivers/watchdog/Makefile
> >> +++ b/drivers/watchdog/Makefile
> >> @@ -133,6 +133,7 @@ obj-$(CONFIG_WDT_MTX1) += mtx-1_wdt.o
> >> obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o
> >> obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
> >> obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
> >> +obj-$(CONFIG_AR2315_WDT) += ar2315-wtd.o
> >> obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
> >> obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
> >> octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
> >> diff --git a/drivers/watchdog/ar2315-wtd.c b/drivers/watchdog/ar2315-wtd.c
> >> new file mode 100644
> >> index 0000000..4fd34d2
> >> --- /dev/null
> >> +++ b/drivers/watchdog/ar2315-wtd.c
> >> @@ -0,0 +1,167 @@
> >> +/*
> >> + * 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.
> >> + *
> >> + * This program is distributed in the hope that it will be useful,
> >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> >> + * GNU General Public License for more details.
> >> + *
> >> + * You should have received a copy of the GNU General Public License
> >> + * along with this program; if not, see <http://www.gnu.org/licenses/>.
> >> + *
> >> + * Copyright (C) 2008 John Crispin <blogic@openwrt.org>
> >> + * Based on EP93xx and ifxmips wdt driver
> >> + */
> >> +
> >> +#include <linux/interrupt.h>
> >> +#include <linux/module.h>
> >> +#include <linux/watchdog.h>
> >> +#include <linux/reboot.h>
> >> +#include <linux/init.h>
> >> +#include <linux/platform_device.h>
> >> +#include <linux/io.h>
> >> +
> >> +#define DRIVER_NAME "ar2315-wdt"
> >> +
> >> +#define CLOCK_RATE 40000000
> >> +
> >> +#define WDT_REG_TIMER 0x00
> >> +#define WDT_REG_CTRL 0x04
> >> +
> >> +#define WDT_CTRL_ACT_NONE 0x00000000 /* No action */
> >> +#define WDT_CTRL_ACT_NMI 0x00000001 /* NMI on watchdog */
> >> +#define WDT_CTRL_ACT_RESET 0x00000002 /* reset on watchdog */
> >> +
> >
> > What are those defines for ? They don't seem to be used.
> >
> This defines for reference. There no documentation for this chips, so
> I left this defines as some kind of documentation.
>
If they are not used, please drop those defines. They only create unnecessary
confusion if unused.
> > If the watchdog can result in an immediate restart, as
> > this define suggests, why don't you use it but rely on
> > the interrupt handler instead ?
> >
> AFAIK some of chips have a HW bug in restarting unit, so chip specific
> restart routine (in arch code) use a lot of hacks to reset chip. So we
> use interrupt to call reset function, which should reliably reset
> chip.
>
> > This means the watchdog won't really fire if it times out, but depend
> > on the interrupt handler to work. Which it won't if there is a real
> > problem and interrupts are disabled (or if the system hangs entirely).
> >
> Sure. But without reset function call from the interrupt handler we
> can not reliable reset chip (see above).
>
> >> +static int started;
> >> +static void __iomem *wdt_base;
> >> +
> >> +static inline void ar2315_wdt_wr(unsigned reg, u32 val)
> >> +{
> >> + iowrite32(val, wdt_base + reg);
> >> +}
> >> +
> >> +static void ar2315_wdt_enable(struct watchdog_device *wdd)
> >> +{
> >> + ar2315_wdt_wr(WDT_REG_TIMER, wdd->timeout * CLOCK_RATE);
> >> +}
> >> +
> >> +static int ar2315_wdt_start(struct watchdog_device *wdd)
> >> +{
> >> + ar2315_wdt_enable(wdd);
> >> + started = 1;
> >
> >
> > I don't really see why you would need this variable.
> >
> To protect against spurious interrupts, since the watchdog timer could
> be started by bootloader.
>
Then it would be appropriate to stop it in the probe function.
> >
> >> + return 0;
> >> +}
> >> +
> >> +static int ar2315_wdt_stop(struct watchdog_device *wdd)
> >> +{
> >> + return 0;
> >> +}
> >> +
> >> +static int ar2315_wdt_ping(struct watchdog_device *wdd)
> >> +{
> >> + ar2315_wdt_enable(wdd);
> >> + return 0;
> >> +}
> >> +
> >> +static int ar2315_wdt_set_timeout(struct watchdog_device *wdd, unsigned
> >> val)
> >> +{
> >> + wdd->timeout = val;
> >> + return 0;
> >> +}
> >> +
> >> +static irqreturn_t ar2315_wdt_interrupt(int irq, void *dev)
> >> +{
> >> + struct platform_device *pdev = (struct platform_device *)dev;
> >> +
> >> + if (started) {
> >> + dev_crit(&pdev->dev, "watchdog expired, rebooting
> >> system\n");
> >> + emergency_restart();
> >> + } else {
> >> + ar2315_wdt_wr(WDT_REG_CTRL, 0);
> >> + ar2315_wdt_wr(WDT_REG_TIMER, 0);
> >> + }
> >
> >
> > This is quite unusual.
> > Why not stop the watchdog in the stop function ? Quite apparently
> > it can be stopped, or at least this is what it looks like.
> >
> The started variable is set to true inside the watchdog start routine,
> but it never reset to false. This code only disable the watchdog when
> it was started by bootloader.
>
> > When do you expect this function to be called in the first place
> > with started == 1 ?
> >
> > If the idea is to stop the watchdog if it was already enabled
> > when probing the driver, why don't you stop it there ?
> >
> Sure, I will try to do that.
>
> >> + return IRQ_HANDLED;
> >> +}
> >> +
> >> +static const struct watchdog_info ar2315_wdt_info = {
> >> + .identity = "ar2315 Watchdog",
> >> + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
> >> +};
> >> +
> >> +static const struct watchdog_ops ar2315_wdt_ops = {
> >> + .owner = THIS_MODULE,
> >> + .start = ar2315_wdt_start,
> >> + .stop = ar2315_wdt_stop,
> >> + .ping = ar2315_wdt_ping,
> >> + .set_timeout = ar2315_wdt_set_timeout,
> >> +};
> >> +
> >> +static struct watchdog_device ar2315_wdt_dev = {
> >> + .info = &ar2315_wdt_info,
> >> + .ops = &ar2315_wdt_ops,
> >> + .min_timeout = 1,
> >> + .max_timeout = 90,
> >> + .timeout = 20,
> >> +};
> >> +
> >> +static int ar2315_wdt_probe(struct platform_device *pdev)
> >> +{
> >> + struct device *dev = &pdev->dev;
> >> + struct resource *res;
> >> + int ret = 0;
> >> +
> >> + if (wdt_base)
> >> + return -EBUSY;
> >> +
> >> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >> + wdt_base = devm_ioremap_resource(dev, res);
> >> + if (IS_ERR(wdt_base))
> >> + return PTR_ERR(wdt_base);
> >> +
> >> + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> >> + if (!res) {
> >> + dev_err(dev, "no IRQ resource\n");
> >> + return -ENOENT;
> >> + }
> >> +
> >> + ret = devm_request_irq(dev, res->start, ar2315_wdt_interrupt, 0,
> >> + DRIVER_NAME, pdev);
> >> + if (ret) {
> >> + dev_err(dev, "failed to register inetrrupt\n");
> >> + return ret;
> >> + }
> >> +
> >> + ar2315_wdt_dev.parent = dev;
> >> + ret = watchdog_register_device(&ar2315_wdt_dev);
> >> + if (ret) {
> >> + dev_err(dev, "failed to register watchdog device\n");
> >> + return ret;
> >> + }
> >> +
> >> + return 0;
> >> +}
> >> +
> >> +static int ar2315_wdt_remove(struct platform_device *pdev)
> >> +{
> >> + watchdog_unregister_device(&ar2315_wdt_dev);
> >
> >
> > Why don't you stop the watchdog on remove ?
> >
> While the watchdog is running, the watchdog core prevents the module
> unloading, so this routine could not be called while the watchdog is
> running. Isn't it?
>
Only you never stop the watchdog nor disable the chip interrupt,
even on close (the stop function above does nothing).
Guenter
next prev parent reply other threads:[~2014-09-29 20:46 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-28 18:32 [PATCH 00/16] MIPS: support for the Atheros AR231X SoCs Sergey Ryazanov
2014-09-28 18:33 ` [PATCH 01/16] MIPS: ar231x: add common parts Sergey Ryazanov
2014-09-29 9:30 ` Jonas Gorski
2014-09-29 20:57 ` Sergey Ryazanov
2014-09-28 18:33 ` [PATCH 02/16] MIPS: ar231x: add basic AR5312 SoC support Sergey Ryazanov
2014-09-29 9:35 ` Jonas Gorski
2014-09-29 21:05 ` Sergey Ryazanov
2014-09-28 18:33 ` [PATCH 03/16] MIPS: ar231x: add basic AR2315 " Sergey Ryazanov
2014-09-29 9:50 ` Jonas Gorski
2014-09-28 18:33 ` [PATCH 04/16] MIPS: ar231x: add interrupts handling routines Sergey Ryazanov
2014-09-28 18:33 ` [PATCH 05/16] MIPS: ar231x: add early printk support Sergey Ryazanov
2014-09-29 12:47 ` Jonas Gorski
2014-09-29 19:36 ` Sergey Ryazanov
2014-09-28 18:33 ` [PATCH 06/16] MIPS: ar231x: add UART support Sergey Ryazanov
2014-09-28 18:33 ` [PATCH 07/16] MIPS: ar231x: add board configuration detection Sergey Ryazanov
2014-09-28 18:33 ` [PATCH 08/16] MIPS: ar231x: add SoC type detection Sergey Ryazanov
2014-09-28 18:33 ` [PATCH 09/16] gpio: add driver for Atheros AR5312 SoC GPIO controller Sergey Ryazanov
2014-10-15 7:33 ` Linus Walleij
2014-09-28 18:33 ` [PATCH 10/16] gpio: add driver for Atheros AR2315 " Sergey Ryazanov
2014-10-15 8:58 ` Linus Walleij
2014-10-15 11:12 ` Sergey Ryazanov
2014-10-28 14:37 ` Linus Walleij
2014-10-28 21:08 ` Sergey Ryazanov
2014-09-28 18:33 ` [PATCH 11/16] mtd: add Atheros AR2315 SPI Flash driver Sergey Ryazanov
2014-09-28 18:33 ` [PATCH 12/16] watchdog: add Atheros AR2315 watchdog driver Sergey Ryazanov
2014-09-28 21:35 ` Guenter Roeck
2014-09-29 20:14 ` Sergey Ryazanov
2014-09-29 20:46 ` Guenter Roeck [this message]
2014-09-29 21:01 ` Sergey Ryazanov
2014-09-28 18:33 ` [PATCH 13/16] MIPS: ar231x: register various chip devices Sergey Ryazanov
2014-09-28 18:33 ` [PATCH 14/16] MIPS: ar231x: add AR2315 PCI host controller driver Sergey Ryazanov
2014-09-28 18:33 ` [PATCH 15/16] ath5k: update dependencies Sergey Ryazanov
2014-09-30 17:20 ` John W. Linville
2014-10-01 14:41 ` Sergey Ryazanov
2014-10-02 17:37 ` John W. Linville
2014-09-28 18:33 ` [PATCH 16/16] MIPS: ar231x: add Wireless device support Sergey Ryazanov
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=20140929204619.GA32273@roeck-us.net \
--to=linux@roeck-us.net \
--cc=linux-mips@linux-mips.org \
--cc=linux-watchdog@vger.kernel.org \
--cc=ralf@linux-mips.org \
--cc=ryazanov.s.a@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox