root/drivers/watchdog/wm8350_wdt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wm8350_wdt_set_timeout
  2. wm8350_wdt_start
  3. wm8350_wdt_stop
  4. wm8350_wdt_ping
  5. wm8350_wdt_probe
  6. wm8350_wdt_remove

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * Watchdog driver for the wm8350
   4  *
   5  * Copyright (C) 2007, 2008 Wolfson Microelectronics <linux@wolfsonmicro.com>
   6  */
   7 
   8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   9 
  10 #include <linux/module.h>
  11 #include <linux/moduleparam.h>
  12 #include <linux/types.h>
  13 #include <linux/kernel.h>
  14 #include <linux/platform_device.h>
  15 #include <linux/watchdog.h>
  16 #include <linux/uaccess.h>
  17 #include <linux/mfd/wm8350/core.h>
  18 
  19 static bool nowayout = WATCHDOG_NOWAYOUT;
  20 module_param(nowayout, bool, 0);
  21 MODULE_PARM_DESC(nowayout,
  22                  "Watchdog cannot be stopped once started (default="
  23                  __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
  24 
  25 static DEFINE_MUTEX(wdt_mutex);
  26 
  27 static struct {
  28         unsigned int time;  /* Seconds */
  29         u16 val;            /* To be set in WM8350_SYSTEM_CONTROL_2 */
  30 } wm8350_wdt_cfgs[] = {
  31         { 1, 0x02 },
  32         { 2, 0x04 },
  33         { 4, 0x05 },
  34 };
  35 
  36 static int wm8350_wdt_set_timeout(struct watchdog_device *wdt_dev,
  37                                   unsigned int timeout)
  38 {
  39         struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);
  40         int ret, i;
  41         u16 reg;
  42 
  43         for (i = 0; i < ARRAY_SIZE(wm8350_wdt_cfgs); i++)
  44                 if (wm8350_wdt_cfgs[i].time == timeout)
  45                         break;
  46         if (i == ARRAY_SIZE(wm8350_wdt_cfgs))
  47                 return -EINVAL;
  48 
  49         mutex_lock(&wdt_mutex);
  50         wm8350_reg_unlock(wm8350);
  51 
  52         reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);
  53         reg &= ~WM8350_WDOG_TO_MASK;
  54         reg |= wm8350_wdt_cfgs[i].val;
  55         ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);
  56 
  57         wm8350_reg_lock(wm8350);
  58         mutex_unlock(&wdt_mutex);
  59 
  60         wdt_dev->timeout = timeout;
  61         return ret;
  62 }
  63 
  64 static int wm8350_wdt_start(struct watchdog_device *wdt_dev)
  65 {
  66         struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);
  67         int ret;
  68         u16 reg;
  69 
  70         mutex_lock(&wdt_mutex);
  71         wm8350_reg_unlock(wm8350);
  72 
  73         reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);
  74         reg &= ~WM8350_WDOG_MODE_MASK;
  75         reg |= 0x20;
  76         ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);
  77 
  78         wm8350_reg_lock(wm8350);
  79         mutex_unlock(&wdt_mutex);
  80 
  81         return ret;
  82 }
  83 
  84 static int wm8350_wdt_stop(struct watchdog_device *wdt_dev)
  85 {
  86         struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);
  87         int ret;
  88         u16 reg;
  89 
  90         mutex_lock(&wdt_mutex);
  91         wm8350_reg_unlock(wm8350);
  92 
  93         reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);
  94         reg &= ~WM8350_WDOG_MODE_MASK;
  95         ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);
  96 
  97         wm8350_reg_lock(wm8350);
  98         mutex_unlock(&wdt_mutex);
  99 
 100         return ret;
 101 }
 102 
 103 static int wm8350_wdt_ping(struct watchdog_device *wdt_dev)
 104 {
 105         struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev);
 106         int ret;
 107         u16 reg;
 108 
 109         mutex_lock(&wdt_mutex);
 110 
 111         reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2);
 112         ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg);
 113 
 114         mutex_unlock(&wdt_mutex);
 115 
 116         return ret;
 117 }
 118 
 119 static const struct watchdog_info wm8350_wdt_info = {
 120         .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
 121         .identity = "WM8350 Watchdog",
 122 };
 123 
 124 static const struct watchdog_ops wm8350_wdt_ops = {
 125         .owner = THIS_MODULE,
 126         .start = wm8350_wdt_start,
 127         .stop = wm8350_wdt_stop,
 128         .ping = wm8350_wdt_ping,
 129         .set_timeout = wm8350_wdt_set_timeout,
 130 };
 131 
 132 static struct watchdog_device wm8350_wdt = {
 133         .info = &wm8350_wdt_info,
 134         .ops = &wm8350_wdt_ops,
 135         .timeout = 4,
 136         .min_timeout = 1,
 137         .max_timeout = 4,
 138 };
 139 
 140 static int wm8350_wdt_probe(struct platform_device *pdev)
 141 {
 142         struct wm8350 *wm8350 = platform_get_drvdata(pdev);
 143 
 144         if (!wm8350) {
 145                 pr_err("No driver data supplied\n");
 146                 return -ENODEV;
 147         }
 148 
 149         watchdog_set_nowayout(&wm8350_wdt, nowayout);
 150         watchdog_set_drvdata(&wm8350_wdt, wm8350);
 151         wm8350_wdt.parent = &pdev->dev;
 152 
 153         /* Default to 4s timeout */
 154         wm8350_wdt_set_timeout(&wm8350_wdt, 4);
 155 
 156         return watchdog_register_device(&wm8350_wdt);
 157 }
 158 
 159 static int wm8350_wdt_remove(struct platform_device *pdev)
 160 {
 161         watchdog_unregister_device(&wm8350_wdt);
 162         return 0;
 163 }
 164 
 165 static struct platform_driver wm8350_wdt_driver = {
 166         .probe = wm8350_wdt_probe,
 167         .remove = wm8350_wdt_remove,
 168         .driver = {
 169                 .name = "wm8350-wdt",
 170         },
 171 };
 172 
 173 module_platform_driver(wm8350_wdt_driver);
 174 
 175 MODULE_AUTHOR("Mark Brown");
 176 MODULE_DESCRIPTION("WM8350 Watchdog");
 177 MODULE_LICENSE("GPL");
 178 MODULE_ALIAS("platform:wm8350-wdt");

/* [<][>][^][v][top][bottom][index][help] */