cregit-Linux how code gets into the kernel

Release 4.7 drivers/watchdog/pnx4008_wdt.c

Directory: drivers/watchdog
/*
 * drivers/char/watchdog/pnx4008_wdt.c
 *
 * Watchdog driver for PNX4008 board
 *
 * Authors: Dmitry Chigirev <source@mvista.com>,
 *          Vitaly Wool <vitalywool@gmail.com>
 * Based on sa1100 driver,
 * Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
 *
 * 2005-2006 (c) MontaVista Software, Inc.
 *
 * (C) 2012 Wolfram Sang, Pengutronix
 *
 * 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.
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/watchdog.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <mach/hardware.h>

/* WatchDog Timer - Chapter 23 Page 207 */


#define DEFAULT_HEARTBEAT 19

#define MAX_HEARTBEAT     60

/* Watchdog timer register set definition */

#define WDTIM_INT(p)     ((p) + 0x0)

#define WDTIM_CTRL(p)    ((p) + 0x4)

#define WDTIM_COUNTER(p) ((p) + 0x8)

#define WDTIM_MCTRL(p)   ((p) + 0xC)

#define WDTIM_MATCH0(p)  ((p) + 0x10)

#define WDTIM_EMR(p)     ((p) + 0x14)

#define WDTIM_PULSE(p)   ((p) + 0x18)

#define WDTIM_RES(p)     ((p) + 0x1C)

/* WDTIM_INT bit definitions */

#define MATCH_INT      1

/* WDTIM_CTRL bit definitions */

#define COUNT_ENAB     1

#define RESET_COUNT    (1 << 1)

#define DEBUG_EN       (1 << 2)

/* WDTIM_MCTRL bit definitions */

#define MR0_INT        1

#undef  RESET_COUNT0

#define RESET_COUNT0   (1 << 2)

#define STOP_COUNT0    (1 << 2)

#define M_RES1         (1 << 3)

#define M_RES2         (1 << 4)

#define RESFRC1        (1 << 5)

#define RESFRC2        (1 << 6)

/* WDTIM_EMR bit definitions */

#define EXT_MATCH0      1

#define MATCH_OUTPUT_HIGH (2 << 4)	
/*a MATCH_CTRL setting */

/* WDTIM_RES bit definitions */

#define WDOG_RESET      1	
/* read only */


#define WDOG_COUNTER_RATE 13000000	
/*the counter clock is 13 MHz fixed */


static bool nowayout = WATCHDOG_NOWAYOUT;

static unsigned int heartbeat = DEFAULT_HEARTBEAT;

static DEFINE_SPINLOCK(io_lock);

static void __iomem	*wdt_base;

static struct clk	*wdt_clk;


static int pnx4008_wdt_start(struct watchdog_device *wdd) { spin_lock(&io_lock); /* stop counter, initiate counter reset */ writel(RESET_COUNT, WDTIM_CTRL(wdt_base)); /*wait for reset to complete. 100% guarantee event */ while (readl(WDTIM_COUNTER(wdt_base))) cpu_relax(); /* internal and external reset, stop after that */ writel(M_RES2 | STOP_COUNT0 | RESET_COUNT0, WDTIM_MCTRL(wdt_base)); /* configure match output */ writel(MATCH_OUTPUT_HIGH, WDTIM_EMR(wdt_base)); /* clear interrupt, just in case */ writel(MATCH_INT, WDTIM_INT(wdt_base)); /* the longest pulse period 65541/(13*10^6) seconds ~ 5 ms. */ writel(0xFFFF, WDTIM_PULSE(wdt_base)); writel(wdd->timeout * WDOG_COUNTER_RATE, WDTIM_MATCH0(wdt_base)); /*enable counter, stop when debugger active */ writel(COUNT_ENAB | DEBUG_EN, WDTIM_CTRL(wdt_base)); spin_unlock(&io_lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
vitaly woolvitaly wool9474.60%240.00%
wolfram sangwolfram sang2015.87%240.00%
wim van sebroeckwim van sebroeck129.52%120.00%
Total126100.00%5100.00%


static int pnx4008_wdt_stop(struct watchdog_device *wdd) { spin_lock(&io_lock); writel(0, WDTIM_CTRL(wdt_base)); /*stop counter */ spin_unlock(&io_lock); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
vitaly woolvitaly wool1745.95%125.00%
wim van sebroeckwim van sebroeck1232.43%125.00%
wolfram sangwolfram sang821.62%250.00%
Total37100.00%4100.00%


static int pnx4008_wdt_set_timeout(struct watchdog_device *wdd, unsigned int new_timeout) { wdd->timeout = new_timeout; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
vitaly woolvitaly wool1041.67%133.33%
wolfram sangwolfram sang833.33%133.33%
wim van sebroeckwim van sebroeck625.00%133.33%
Total24100.00%3100.00%


static int pnx4008_restart_handler(struct watchdog_device *wdd, unsigned long mode, void *cmd) { const char *boot_cmd = cmd; /* * Verify if a "cmd" passed from the userspace program rebooting * the system; if available, handle it. * - For details, see the 'reboot' syscall in kernel/reboot.c * - If the received "cmd" is not supported, use the default mode. */ if (boot_cmd) { if (boot_cmd[0] == 'h') mode = REBOOT_HARD; else if (boot_cmd[0] == 's') mode = REBOOT_SOFT; } if (mode == REBOOT_SOFT) { /* Force match output active */ writel(EXT_MATCH0, WDTIM_EMR(wdt_base)); /* Internal reset on match output (RESOUT_N not asserted) */ writel(M_RES1, WDTIM_MCTRL(wdt_base)); } else { /* Instant assert of RESETOUT_N with pulse length 1mS */ writel(13000, WDTIM_PULSE(wdt_base)); writel(M_RES2 | RESFRC1 | RESFRC2, WDTIM_MCTRL(wdt_base)); } /* Wait for watchdog to reset system */ mdelay(1000); return NOTIFY_DONE; }

Contributors

PersonTokensPropCommitsCommitProp
sylvain lemieuxsylvain lemieux127100.00%3100.00%
Total127100.00%3100.00%

static const struct watchdog_info pnx4008_wdt_ident = { .options = WDIOF_CARDRESET | WDIOF_MAGICCLOSE | WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, .identity = "PNX4008 Watchdog", }; static const struct watchdog_ops pnx4008_wdt_ops = { .owner = THIS_MODULE, .start = pnx4008_wdt_start, .stop = pnx4008_wdt_stop, .set_timeout = pnx4008_wdt_set_timeout, .restart = pnx4008_restart_handler, }; static struct watchdog_device pnx4008_wdd = { .info = &pnx4008_wdt_ident, .ops = &pnx4008_wdt_ops, .timeout = DEFAULT_HEARTBEAT, .min_timeout = 1, .max_timeout = MAX_HEARTBEAT, };
static int pnx4008_wdt_probe(struct platform_device *pdev) { struct resource *r; int ret = 0; watchdog_init_timeout(&pnx4008_wdd, heartbeat, &pdev->dev); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); wdt_base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(wdt_base)) return PTR_ERR(wdt_base); wdt_clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(wdt_clk)) return PTR_ERR(wdt_clk); ret = clk_prepare_enable(wdt_clk); if (ret) return ret; pnx4008_wdd.bootstatus = (readl(WDTIM_RES(wdt_base)) & WDOG_RESET) ? WDIOF_CARDRESET : 0; pnx4008_wdd.parent = &pdev->dev; watchdog_set_nowayout(&pnx4008_wdd, nowayout); watchdog_set_restart_priority(&pnx4008_wdd, 128); pnx4008_wdt_stop(&pnx4008_wdd); /* disable for now */ ret = watchdog_register_device(&pnx4008_wdd); if (ret < 0) { dev_err(&pdev->dev, "cannot register watchdog device\n"); goto disable_clk; } dev_info(&pdev->dev, "heartbeat %d sec\n", pnx4008_wdd.timeout); return 0; disable_clk: clk_disable_unprepare(wdt_clk); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
vitaly woolvitaly wool7635.02%16.25%
wolfram sangwolfram sang7434.10%318.75%
fabio porceddafabio porcedda146.45%16.25%
russell kingrussell king104.61%212.50%
sylvain lemieuxsylvain lemieux94.15%212.50%
pratyush anandpratyush anand94.15%16.25%
thierry redingthierry reding83.69%16.25%
akinobu mitaakinobu mita73.23%16.25%
jingoo hanjingoo han41.84%16.25%
julia lawalljulia lawall20.92%16.25%
h hartley sweetenh hartley sweeten20.92%16.25%
vladimir zapolskiyvladimir zapolskiy20.92%16.25%
Total217100.00%16100.00%


static int pnx4008_wdt_remove(struct platform_device *pdev) { watchdog_unregister_device(&pnx4008_wdd); clk_disable_unprepare(wdt_clk); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
vitaly woolvitaly wool2184.00%125.00%
wolfram sangwolfram sang28.00%125.00%
wim van sebroeckwim van sebroeck14.00%125.00%
vladimir zapolskiyvladimir zapolskiy14.00%125.00%
Total25100.00%4100.00%

#ifdef CONFIG_OF static const struct of_device_id pnx4008_wdt_match[] = { { .compatible = "nxp,pnx4008-wdt" }, { } }; MODULE_DEVICE_TABLE(of, pnx4008_wdt_match); #endif static struct platform_driver platform_wdt_driver = { .driver = { .name = "pnx4008-watchdog", .of_match_table = of_match_ptr(pnx4008_wdt_match), }, .probe = pnx4008_wdt_probe, .remove = pnx4008_wdt_remove, }; module_platform_driver(platform_wdt_driver); MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>"); MODULE_AUTHOR("Wolfram Sang <kernel@pengutronix.de>"); MODULE_DESCRIPTION("PNX4008 Watchdog Driver"); module_param(heartbeat, uint, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat period in seconds from 1 to " __MODULE_STRING(MAX_HEARTBEAT) ", default " __MODULE_STRING(DEFAULT_HEARTBEAT)); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Set to 1 to keep watchdog running after device release"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:pnx4008-watchdog");

Overall Contributors

PersonTokensPropCommitsCommitProp
vitaly woolvitaly wool53252.99%25.41%
wolfram sangwolfram sang14714.64%410.81%
sylvain lemieuxsylvain lemieux14714.64%410.81%
wim van sebroeckwim van sebroeck484.78%616.22%
roland stiggeroland stigge393.88%12.70%
fabio porceddafabio porcedda191.89%12.70%
russell kingrussell king131.29%410.81%
pratyush anandpratyush anand90.90%12.70%
thierry redingthierry reding80.80%12.70%
joe perchesjoe perches70.70%12.70%
akinobu mitaakinobu mita70.70%12.70%
kay sieverskay sievers60.60%12.70%
jingoo hanjingoo han40.40%12.70%
alexey dobriyanalexey dobriyan40.40%12.70%
vladimir zapolskiyvladimir zapolskiy40.40%25.41%
tejun heotejun heo20.20%12.70%
julia lawalljulia lawall20.20%12.70%
h hartley sweetenh hartley sweeten20.20%12.70%
axel linaxel lin20.20%12.70%
alan coxalan cox10.10%12.70%
arjan van de venarjan van de ven10.10%12.70%
Total1004100.00%37100.00%
Directory: drivers/watchdog
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}