cregit-Linux how code gets into the kernel

Release 4.11 drivers/watchdog/omap_wdt.c

Directory: drivers/watchdog
/*
 * omap_wdt.c
 *
 * Watchdog driver for the TI OMAP 16xx & 24xx/34xx 32KHz (non-secure) watchdog
 *
 * Author: MontaVista Software, Inc.
 *       <gdavis@mvista.com> or <source@mvista.com>
 *
 * 2003 (c) MontaVista Software, Inc. This file is licensed under the
 * terms of the GNU General Public License version 2. This program is
 * licensed "as is" without any warranty of any kind, whether express
 * or implied.
 *
 * History:
 *
 * 20030527: George G. Davis <gdavis@mvista.com>
 *      Initially based on linux-2.4.19-rmk7-pxa1/drivers/char/sa1100_wdt.c
 *      (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
 *      Based on SoftDog driver by Alan Cox <alan@lxorguk.ukuu.org.uk>
 *
 * Copyright (c) 2004 Texas Instruments.
 *      1. Modified to support OMAP1610 32-KHz watchdog timer
 *      2. Ported to 2.6 kernel
 *
 * Copyright (c) 2005 David Brownell
 *      Use the driver model and standard identifiers; handle bigger timeouts.
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/watchdog.h>
#include <linux/reboot.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/moduleparam.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/platform_data/omap-wd-timer.h>

#include "omap_wdt.h"


static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
	"(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");


static unsigned timer_margin;
module_param(timer_margin, uint, 0);
MODULE_PARM_DESC(timer_margin, "initial watchdog timeout (in seconds)");


#define to_omap_wdt_dev(_wdog)	container_of(_wdog, struct omap_wdt_dev, wdog)


static bool early_enable;
module_param(early_enable, bool, 0);
MODULE_PARM_DESC(early_enable,
	"Watchdog is started on module insertion (default=0)");


struct omap_wdt_dev {
	
struct watchdog_device wdog;
	
void __iomem    *base;          /* physical */
	
struct device   *dev;
	
bool		omap_wdt_users;
	
int		wdt_trgr_pattern;
	
struct mutex	lock;		/* to avoid races with PM */
};


static void omap_wdt_reload(struct omap_wdt_dev *wdev) { void __iomem *base = wdev->base; /* wait for posted write to complete */ while ((readl_relaxed(base + OMAP_WATCHDOG_WPS)) & 0x08) cpu_relax(); wdev->wdt_trgr_pattern = ~wdev->wdt_trgr_pattern; writel_relaxed(wdev->wdt_trgr_pattern, (base + OMAP_WATCHDOG_TGR)); /* wait for posted write to complete */ while ((readl_relaxed(base + OMAP_WATCHDOG_WPS)) & 0x08) cpu_relax(); /* reloaded WCRR from WLDR */ }

Contributors

PersonTokensPropCommitsCommitProp
Komal Shah4862.34%125.00%
Felipe Balbi1924.68%125.00%
Aaro Koskinen79.09%125.00%
Victor Kamensky33.90%125.00%
Total77100.00%4100.00%


static void omap_wdt_enable(struct omap_wdt_dev *wdev) { void __iomem *base = wdev->base; /* Sequence to enable the watchdog */ writel_relaxed(0xBBBB, base + OMAP_WATCHDOG_SPR); while ((readl_relaxed(base + OMAP_WATCHDOG_WPS)) & 0x10) cpu_relax(); writel_relaxed(0x4444, base + OMAP_WATCHDOG_SPR); while ((readl_relaxed(base + OMAP_WATCHDOG_WPS)) & 0x10) cpu_relax(); }

Contributors

PersonTokensPropCommitsCommitProp
Komal Shah4664.79%125.00%
Felipe Balbi2129.58%250.00%
Victor Kamensky45.63%125.00%
Total71100.00%4100.00%


static void omap_wdt_disable(struct omap_wdt_dev *wdev) { void __iomem *base = wdev->base; /* sequence required to disable watchdog */ writel_relaxed(0xAAAA, base + OMAP_WATCHDOG_SPR); /* TIMER_MODE */ while (readl_relaxed(base + OMAP_WATCHDOG_WPS) & 0x10) cpu_relax(); writel_relaxed(0x5555, base + OMAP_WATCHDOG_SPR); /* TIMER_MODE */ while (readl_relaxed(base + OMAP_WATCHDOG_WPS) & 0x10) cpu_relax(); }

Contributors

PersonTokensPropCommitsCommitProp
Komal Shah4463.77%125.00%
Felipe Balbi2130.43%250.00%
Victor Kamensky45.80%125.00%
Total69100.00%4100.00%


static void omap_wdt_set_timer(struct omap_wdt_dev *wdev, unsigned int timeout) { u32 pre_margin = GET_WLDR_VAL(timeout); void __iomem *base = wdev->base; /* just count up at 32 KHz */ while (readl_relaxed(base + OMAP_WATCHDOG_WPS) & 0x04) cpu_relax(); writel_relaxed(pre_margin, base + OMAP_WATCHDOG_LDR); while (readl_relaxed(base + OMAP_WATCHDOG_WPS) & 0x04) cpu_relax(); }

Contributors

PersonTokensPropCommitsCommitProp
Komal Shah4260.00%120.00%
Felipe Balbi1927.14%240.00%
Aaro Koskinen68.57%120.00%
Victor Kamensky34.29%120.00%
Total70100.00%5100.00%


static int omap_wdt_start(struct watchdog_device *wdog) { struct omap_wdt_dev *wdev = to_omap_wdt_dev(wdog); void __iomem *base = wdev->base; mutex_lock(&wdev->lock); wdev->omap_wdt_users = true; pm_runtime_get_sync(wdev->dev); /* * Make sure the watchdog is disabled. This is unfortunately required * because writing to various registers with the watchdog running has no * effect. */ omap_wdt_disable(wdev); /* initialize prescaler */ while (readl_relaxed(base + OMAP_WATCHDOG_WPS) & 0x01) cpu_relax(); writel_relaxed((1 << 5) | (PTV << 2), base + OMAP_WATCHDOG_CNTRL); while (readl_relaxed(base + OMAP_WATCHDOG_WPS) & 0x01) cpu_relax(); omap_wdt_set_timer(wdev, wdog->timeout); omap_wdt_reload(wdev); /* trigger loading of new timeout value */ omap_wdt_enable(wdev); mutex_unlock(&wdev->lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Komal Shah5741.91%110.00%
Felipe Balbi3324.26%220.00%
Aaro Koskinen2719.85%110.00%
Uwe Kleine-König75.15%220.00%
Ulrik Bech Hald53.68%110.00%
Victor Kamensky32.21%110.00%
Wim Van Sebroeck21.47%110.00%
Varadarajan, Charulatha21.47%110.00%
Total136100.00%10100.00%


static int omap_wdt_stop(struct watchdog_device *wdog) { struct omap_wdt_dev *wdev = to_omap_wdt_dev(wdog); mutex_lock(&wdev->lock); omap_wdt_disable(wdev); pm_runtime_put_sync(wdev->dev); wdev->omap_wdt_users = false; mutex_unlock(&wdev->lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Aaro Koskinen2339.66%116.67%
Komal Shah1932.76%116.67%
Felipe Balbi1322.41%233.33%
Varadarajan, Charulatha23.45%116.67%
Uwe Kleine-König11.72%116.67%
Total58100.00%6100.00%


static int omap_wdt_ping(struct watchdog_device *wdog) { struct omap_wdt_dev *wdev = to_omap_wdt_dev(wdog); mutex_lock(&wdev->lock); omap_wdt_reload(wdev); mutex_unlock(&wdev->lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Aaro Koskinen1737.78%116.67%
Komal Shah1022.22%116.67%
Felipe Balbi920.00%233.33%
Alan Cox817.78%116.67%
Uwe Kleine-König12.22%116.67%
Total45100.00%6100.00%


static int omap_wdt_set_timeout(struct watchdog_device *wdog, unsigned int timeout) { struct omap_wdt_dev *wdev = to_omap_wdt_dev(wdog); mutex_lock(&wdev->lock); omap_wdt_disable(wdev); omap_wdt_set_timer(wdev, timeout); omap_wdt_enable(wdev); omap_wdt_reload(wdev); wdog->timeout = timeout; mutex_unlock(&wdev->lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Aaro Koskinen2534.72%116.67%
Komal Shah1825.00%116.67%
Felipe Balbi1723.61%116.67%
Alan Cox912.50%116.67%
Wim Van Sebroeck22.78%116.67%
Uwe Kleine-König11.39%116.67%
Total72100.00%6100.00%


static unsigned int omap_wdt_get_timeleft(struct watchdog_device *wdog) { struct omap_wdt_dev *wdev = to_omap_wdt_dev(wdog); void __iomem *base = wdev->base; u32 value; value = readl_relaxed(base + OMAP_WATCHDOG_CRR); return GET_WCCR_SECS(value); }

Contributors

PersonTokensPropCommitsCommitProp
Lars Poeschel4897.96%150.00%
Peter Robinson12.04%150.00%
Total49100.00%2100.00%

static const struct watchdog_info omap_wdt_info = { .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, .identity = "OMAP Watchdog", }; static const struct watchdog_ops omap_wdt_ops = { .owner = THIS_MODULE, .start = omap_wdt_start, .stop = omap_wdt_stop, .ping = omap_wdt_ping, .set_timeout = omap_wdt_set_timeout, .get_timeleft = omap_wdt_get_timeleft, };
static int omap_wdt_probe(struct platform_device *pdev) { struct omap_wd_timer_platform_data *pdata = dev_get_platdata(&pdev->dev); struct resource *res; struct omap_wdt_dev *wdev; int ret; wdev = devm_kzalloc(&pdev->dev, sizeof(*wdev), GFP_KERNEL); if (!wdev) return -ENOMEM; wdev->omap_wdt_users = false; wdev->dev = &pdev->dev; wdev->wdt_trgr_pattern = 0x1234; mutex_init(&wdev->lock); /* reserve static register mappings */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdev->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(wdev->base)) return PTR_ERR(wdev->base); wdev->wdog.info = &omap_wdt_info; wdev->wdog.ops = &omap_wdt_ops; wdev->wdog.min_timeout = TIMER_MARGIN_MIN; wdev->wdog.max_timeout = TIMER_MARGIN_MAX; wdev->wdog.parent = &pdev->dev; if (watchdog_init_timeout(&wdev->wdog, timer_margin, &pdev->dev) < 0) wdev->wdog.timeout = TIMER_MARGIN_DEFAULT; watchdog_set_nowayout(&wdev->wdog, nowayout); platform_set_drvdata(pdev, wdev); pm_runtime_enable(wdev->dev); pm_runtime_get_sync(wdev->dev); if (pdata && pdata->read_reset_sources) { u32 rs = pdata->read_reset_sources(); if (rs & (1 << OMAP_MPU_WD_RST_SRC_ID_SHIFT)) wdev->wdog.bootstatus = WDIOF_CARDRESET; } if (!early_enable) omap_wdt_disable(wdev); ret = watchdog_register_device(&wdev->wdog); if (ret) { pm_runtime_disable(wdev->dev); return ret; } pr_info("OMAP Watchdog Timer Rev 0x%02x: initial timeout %d sec\n", readl_relaxed(wdev->base + OMAP_WATCHDOG_REV) & 0xFF, wdev->wdog.timeout); if (early_enable) omap_wdt_start(&wdev->wdog); pm_runtime_put(wdev->dev); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Aaro Koskinen11432.11%315.79%
Uwe Kleine-König6919.44%526.32%
Felipe Balbi6718.87%315.79%
Komal Shah4111.55%15.26%
Jingoo Han267.32%210.53%
Lars Poeschel123.38%15.26%
Pratyush Anand113.10%15.26%
Ulrik Bech Hald102.82%15.26%
Varadarajan, Charulatha41.13%15.26%
Victor Kamensky10.28%15.26%
Total355100.00%19100.00%


static void omap_wdt_shutdown(struct platform_device *pdev) { struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); mutex_lock(&wdev->lock); if (wdev->omap_wdt_users) { omap_wdt_disable(wdev); pm_runtime_put_sync(wdev->dev); } mutex_unlock(&wdev->lock); }

Contributors

PersonTokensPropCommitsCommitProp
Aaro Koskinen2340.35%120.00%
Komal Shah1322.81%120.00%
Felipe Balbi1017.54%120.00%
Paul Walmsley915.79%120.00%
Uwe Kleine-König23.51%120.00%
Total57100.00%5100.00%


static int omap_wdt_remove(struct platform_device *pdev) { struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); pm_runtime_disable(wdev->dev); watchdog_unregister_device(&wdev->wdog); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Komal Shah1846.15%125.00%
Aaro Koskinen923.08%125.00%
Shubhrajyoti Datta717.95%125.00%
Uwe Kleine-König512.82%125.00%
Total39100.00%4100.00%

#ifdef CONFIG_PM /* REVISIT ... not clear this is the best way to handle system suspend; and * it's very inappropriate for selective device suspend (e.g. suspending this * through sysfs rather than by stopping the watchdog daemon). Also, this * may not play well enough with NOWAYOUT... */
static int omap_wdt_suspend(struct platform_device *pdev, pm_message_t state) { struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); mutex_lock(&wdev->lock); if (wdev->omap_wdt_users) { omap_wdt_disable(wdev); pm_runtime_put_sync(wdev->dev); } mutex_unlock(&wdev->lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Aaro Koskinen2336.51%120.00%
Komal Shah2336.51%120.00%
Paul Walmsley914.29%120.00%
Felipe Balbi69.52%120.00%
Uwe Kleine-König23.17%120.00%
Total63100.00%5100.00%


static int omap_wdt_resume(struct platform_device *pdev) { struct omap_wdt_dev *wdev = platform_get_drvdata(pdev); mutex_lock(&wdev->lock); if (wdev->omap_wdt_users) { pm_runtime_get_sync(wdev->dev); omap_wdt_enable(wdev); omap_wdt_reload(wdev); } mutex_unlock(&wdev->lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Aaro Koskinen2436.92%120.00%
Komal Shah2335.38%120.00%
Felipe Balbi913.85%120.00%
Paul Walmsley710.77%120.00%
Uwe Kleine-König23.08%120.00%
Total65100.00%5100.00%

#else #define omap_wdt_suspend NULL #define omap_wdt_resume NULL #endif static const struct of_device_id omap_wdt_of_match[] = { { .compatible = "ti,omap3-wdt", }, {}, }; MODULE_DEVICE_TABLE(of, omap_wdt_of_match); static struct platform_driver omap_wdt_driver = { .probe = omap_wdt_probe, .remove = omap_wdt_remove, .shutdown = omap_wdt_shutdown, .suspend = omap_wdt_suspend, .resume = omap_wdt_resume, .driver = { .name = "omap_wdt", .of_match_table = omap_wdt_of_match, }, }; module_platform_driver(omap_wdt_driver); MODULE_AUTHOR("George G. Davis"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:omap_wdt");

Overall Contributors

PersonTokensPropCommitsCommitProp
Komal Shah54835.35%12.56%
Aaro Koskinen33421.55%37.69%
Felipe Balbi26316.97%37.69%
Uwe Kleine-König1016.52%615.38%
Lars Poeschel855.48%25.13%
Xiao Jiang301.94%12.56%
Pali Rohár281.81%12.56%
Jingoo Han261.68%25.13%
Paul Walmsley261.68%25.13%
Alan Cox191.23%25.13%
Victor Kamensky181.16%12.56%
Ulrik Bech Hald150.97%12.56%
Varadarajan, Charulatha110.71%12.56%
Pratyush Anand110.71%12.56%
Joe Perches70.45%12.56%
Shubhrajyoti Datta70.45%12.56%
Wim Van Sebroeck50.32%37.69%
Kay Sievers50.32%12.56%
Arnd Bergmann30.19%12.56%
Axel Lin20.13%12.56%
Tony Lindgren20.13%12.56%
Tejun Heo20.13%12.56%
Arjan van de Ven10.06%12.56%
Peter Robinson10.06%12.56%
Total1550100.00%39100.00%
Directory: drivers/watchdog
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.