From patchwork Mon Jan 23 19:33:04 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 137460 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail-we0-f184.google.com (mail-we0-f184.google.com [74.125.82.184]) (using TLSv1 with cipher RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority" (not verified)) by ozlabs.org (Postfix) with ESMTPS id F155C1007D7 for ; Tue, 24 Jan 2012 06:35:29 +1100 (EST) Received: by werb14 with SMTP id b14sf5070817wer.11 for ; Mon, 23 Jan 2012 11:35:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=beta; h=mime-version:x-beenthere:received-spf:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references:x-sa-exim-connect-ip :x-sa-exim-mail-from:x-sa-exim-scanned:x-ptx-original-recipient :x-original-sender:x-original-authentication-results:reply-to :precedence:mailing-list:list-id:x-google-group-id:list-post :list-help:list-archive:sender:list-subscribe:list-unsubscribe :content-type; bh=j4iW+oCacL11GHMff/ZWvMUqJxFhVc8bMRNm92xEa9c=; b=CJxp0Otz41o6Ycl7kalvrC0e+8DjQblsiZ5duWke36VuHIo9XbPkDHe8WjtwdESFh2 KBgVrDku3yz24yCLCvx+0X6yE6BgJtzYp/ys6qbZCfw7IGI8JHeB1ygWTo82vyH3k+pP knSaeaJNNITi0/nqo7FLJTgPqwKRXu6P1X8p0= Received: by 10.216.133.11 with SMTP id p11mr462241wei.37.1327347325280; Mon, 23 Jan 2012 11:35:25 -0800 (PST) MIME-Version: 1.0 X-BeenThere: rtc-linux@googlegroups.com Received: by 10.14.101.141 with SMTP id b13ls1793057eeg.0.canary; Mon, 23 Jan 2012 11:35:24 -0800 (PST) Received: by 10.213.33.146 with SMTP id h18mr723186ebd.0.1327347324469; Mon, 23 Jan 2012 11:35:24 -0800 (PST) Received: by 10.213.33.146 with SMTP id h18mr723185ebd.0.1327347324441; Mon, 23 Jan 2012 11:35:24 -0800 (PST) Received: from metis.ext.pengutronix.de (metis.ext.pengutronix.de. [92.198.50.35]) by gmr-mx.google.com with ESMTPS id u2si9673948eeb.2.2012.01.23.11.35.24 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 23 Jan 2012 11:35:24 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of w.sang@pengutronix.de designates 92.198.50.35 as permitted sender) client-ip=92.198.50.35; Received: from gallifrey.ext.pengutronix.de ([2001:6f8:1178:4:5054:ff:fe8d:eefb] helo=localhost) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1RpPfn-0003pq-JJ; Mon, 23 Jan 2012 20:35:23 +0100 From: Wolfram Sang To: linux-watchdog@vger.kernel.org Cc: rtc-linux@googlegroups.com, Wim Van Sebroeck , Andrew Morton , Wolfram Sang Subject: [rtc-linux] [PATCH 2/3] watchdog: add new driver for STMP3xxx and i.MX23/28 Date: Mon, 23 Jan 2012 20:33:04 +0100 Message-Id: <1327347185-620-3-git-send-email-w.sang@pengutronix.de> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1327347185-620-1-git-send-email-w.sang@pengutronix.de> References: <1327347185-620-1-git-send-email-w.sang@pengutronix.de> X-SA-Exim-Connect-IP: 2001:6f8:1178:4:5054:ff:fe8d:eefb X-SA-Exim-Mail-From: w.sang@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: rtc-linux@googlegroups.com X-Original-Sender: w.sang@pengutronix.de X-Original-Authentication-Results: gmr-mx.google.com; spf=pass (google.com: best guess record for domain of w.sang@pengutronix.de designates 92.198.50.35 as permitted sender) smtp.mail=w.sang@pengutronix.de Reply-To: rtc-linux@googlegroups.com Precedence: list Mailing-list: list rtc-linux@googlegroups.com; contact rtc-linux+owners@googlegroups.com List-ID: X-Google-Group-Id: 712029733259 List-Post: , List-Help: , List-Archive: Sender: rtc-linux@googlegroups.com List-Subscribe: , List-Unsubscribe: , Replace the existing STMP3xxx driver because it has enough drawbacks that a rewrite is apropriate. The new driver is designed to use the watchdog framework which makes it a lot smaller. It now uses an exported function from the RTC driver to set up its registers (the old driver silently reused the hopefully already remapped RTC registers). Also, this driver is mach independent, while the old one still depends on a removed mach. Signed-off-by: Wolfram Sang --- drivers/watchdog/Kconfig | 10 +++ drivers/watchdog/Makefile | 1 + drivers/watchdog/stmp3xxx_rtc_wdt.c | 139 +++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 0 deletions(-) create mode 100644 drivers/watchdog/stmp3xxx_rtc_wdt.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 877b107..2c89da6 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -305,6 +305,16 @@ config STMP3XXX_WATCHDOG To compile this driver as a module, choose M here: the module will be called stmp3xxx_wdt. +config STMP3XXX_RTC_WATCHDOG + tristate "Freescale STMP3XXX & i.MX23/28 watchdog" + depends on RTC_DRV_STMP + select WATCHDOG_CORE + help + Say Y here to include support for the watchdog timer inside + the RTC for the STMP37XX/378X or i.MX23/28 SoC. + To compile this driver as a module, choose M here: the + module will be called stmp3xxx_rtc_wdt. + config NUC900_WATCHDOG tristate "Nuvoton NUC900 watchdog" depends on ARCH_W90X900 diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index e8f479a..acaccd0 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -50,6 +50,7 @@ obj-$(CONFIG_DAVINCI_WATCHDOG) += davinci_wdt.o obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o +obj-$(CONFIG_STMP3XXX_RTC_WATCHDOG) += stmp3xxx_rtc_wdt.o obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c new file mode 100644 index 0000000..4351055 --- /dev/null +++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c @@ -0,0 +1,139 @@ +/* + * Watchdog driver for the RTC based watchdog in STMP3xxx and i.MX23/28 + * + * Author: Wolfram Sang + * + * Copyright (C) 2011 Pengutronix e.K. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include +#include + +#define WDOG_TICK_RATE 1000 /* 1 kHz clock */ +#define STMP3XXX_DEFAULT_TIMEOUT 60 +#define STMP3XXX_MAX_TIMEOUT (UINT_MAX / WDOG_TICK_RATE) + +static int timeout = STMP3XXX_DEFAULT_TIMEOUT; +module_param(timeout, uint, 0); +MODULE_PARM_DESC(timeout, "Watchdog timeout period in seconds from 1 to " + __MODULE_STRING(STMP3XXX_MAX_TIMEOUT) ", default " + __MODULE_STRING(STMP3XXX_DEFAULT_TIMEOUT)); + +static int wdt_start(struct watchdog_device *wdd) +{ + struct device *dev = watchdog_get_drvdata(wdd); + struct stmp3xxx_wdt_pdata *pdata = dev->platform_data; + + pdata->wdt_set_timeout(dev->parent, wdd->timeout * WDOG_TICK_RATE); + return 0; +} + +static int wdt_stop(struct watchdog_device *wdd) +{ + struct device *dev = watchdog_get_drvdata(wdd); + struct stmp3xxx_wdt_pdata *pdata = dev->platform_data; + + pdata->wdt_set_timeout(dev->parent, 0); + return 0; +} + +static int wdt_set_timeout(struct watchdog_device *wdd, unsigned new_timeout) +{ + struct device *dev = watchdog_get_drvdata(wdd); + struct stmp3xxx_wdt_pdata *pdata = dev->platform_data; + + pdata->wdt_set_timeout(dev->parent, new_timeout * WDOG_TICK_RATE); + return 0; +} + +static const struct watchdog_info stmp3xxx_wdt_ident = { + .options = WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, + .identity = "STMP3XXX RTC Watchdog", +}; + +static const struct watchdog_ops stmp3xxx_wdt_ops = { + .owner = THIS_MODULE, + .start = wdt_start, + .stop = wdt_stop, + .set_timeout = wdt_set_timeout, +}; + +static struct watchdog_device stmp3xxx_wdd = { + .info = &stmp3xxx_wdt_ident, + .ops = &stmp3xxx_wdt_ops, + .min_timeout = 1, + .max_timeout = STMP3XXX_MAX_TIMEOUT, + .status = WATCHDOG_NOWAYOUT_INIT_STATUS, +}; + +static int __devinit stmp3xxx_wdt_probe(struct platform_device *pdev) +{ + int ret; + + watchdog_set_drvdata(&stmp3xxx_wdd, &pdev->dev); + + stmp3xxx_wdd.timeout = clamp_t(unsigned, timeout, 1, STMP3XXX_MAX_TIMEOUT); + + ret = watchdog_register_device(&stmp3xxx_wdd); + if (ret < 0) { + dev_err(&pdev->dev, "cannot register watchdog device\n"); + return ret; + } + + dev_info(&pdev->dev, "initialized watchdog with timeout %ds\n", timeout); + return 0; +} + +static int __devexit stmp3xxx_wdt_remove(struct platform_device *pdev) +{ + watchdog_unregister_device(&stmp3xxx_wdd); + return 0; +} + +#ifdef CONFIG_PM +static int stmp3xxx_wdt_suspend(struct device *dev) +{ + if (stmp3xxx_wdd.status & WDOG_ACTIVE) + wdt_stop(&stmp3xxx_wdd); + + return 0; +} + +static int stmp3xxx_wdt_resume(struct device *dev) +{ + if (stmp3xxx_wdd.status & WDOG_ACTIVE) + wdt_start(&stmp3xxx_wdd); + + return 0; +} + +static const struct dev_pm_ops stmp3xxx_wdt_pm_ops = { + .suspend = stmp3xxx_wdt_suspend, + .resume = stmp3xxx_wdt_resume, +}; +#endif + +static struct platform_driver stmp3xxx_wdt_driver = { + .driver = { + .name = "stmp3xxx_rtc_wdt", +#ifdef CONFIG_PM + .pm = &stmp3xxx_wdt_pm_ops, +#endif + }, + .probe = stmp3xxx_wdt_probe, + .remove = __devexit_p(stmp3xxx_wdt_remove), +}; +module_platform_driver(stmp3xxx_wdt_driver); + +MODULE_DESCRIPTION("STMP3XXX RTC Watchdog Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Wolfram Sang "); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);