root/drivers/watchdog/stpmic1_wdt.c

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

DEFINITIONS

This source file includes following definitions.
  1. pmic_wdt_start
  2. pmic_wdt_stop
  3. pmic_wdt_ping
  4. pmic_wdt_set_timeout
  5. pmic_wdt_probe

   1 // SPDX-License-Identifier: GPL-2.0
   2 // Copyright (C) STMicroelectronics 2018
   3 // Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
   4 
   5 #include <linux/kernel.h>
   6 #include <linux/mfd/stpmic1.h>
   7 #include <linux/module.h>
   8 #include <linux/platform_device.h>
   9 #include <linux/of.h>
  10 #include <linux/regmap.h>
  11 #include <linux/slab.h>
  12 #include <linux/watchdog.h>
  13 
  14 /* WATCHDOG CONTROL REGISTER bit */
  15 #define WDT_START               BIT(0)
  16 #define WDT_PING                BIT(1)
  17 #define WDT_START_MASK          BIT(0)
  18 #define WDT_PING_MASK           BIT(1)
  19 #define WDT_STOP                0
  20 
  21 #define PMIC_WDT_MIN_TIMEOUT 1
  22 #define PMIC_WDT_MAX_TIMEOUT 256
  23 #define PMIC_WDT_DEFAULT_TIMEOUT 30
  24 
  25 static bool nowayout = WATCHDOG_NOWAYOUT;
  26 module_param(nowayout, bool, 0);
  27 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
  28                  __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
  29 
  30 struct stpmic1_wdt {
  31         struct stpmic1 *pmic;
  32         struct watchdog_device wdtdev;
  33 };
  34 
  35 static int pmic_wdt_start(struct watchdog_device *wdd)
  36 {
  37         struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);
  38 
  39         return regmap_update_bits(wdt->pmic->regmap,
  40                                   WCHDG_CR, WDT_START_MASK, WDT_START);
  41 }
  42 
  43 static int pmic_wdt_stop(struct watchdog_device *wdd)
  44 {
  45         struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);
  46 
  47         return regmap_update_bits(wdt->pmic->regmap,
  48                                   WCHDG_CR, WDT_START_MASK, WDT_STOP);
  49 }
  50 
  51 static int pmic_wdt_ping(struct watchdog_device *wdd)
  52 {
  53         struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);
  54 
  55         return regmap_update_bits(wdt->pmic->regmap,
  56                                   WCHDG_CR, WDT_PING_MASK, WDT_PING);
  57 }
  58 
  59 static int pmic_wdt_set_timeout(struct watchdog_device *wdd,
  60                                 unsigned int timeout)
  61 {
  62         struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd);
  63 
  64         wdd->timeout = timeout;
  65         /* timeout is equal to register value + 1 */
  66         return regmap_write(wdt->pmic->regmap, WCHDG_TIMER_CR, timeout - 1);
  67 }
  68 
  69 static const struct watchdog_info pmic_watchdog_info = {
  70         .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
  71         .identity = "STPMIC1 PMIC Watchdog",
  72 };
  73 
  74 static const struct watchdog_ops pmic_watchdog_ops = {
  75         .owner = THIS_MODULE,
  76         .start = pmic_wdt_start,
  77         .stop = pmic_wdt_stop,
  78         .ping = pmic_wdt_ping,
  79         .set_timeout = pmic_wdt_set_timeout,
  80 };
  81 
  82 static int pmic_wdt_probe(struct platform_device *pdev)
  83 {
  84         struct device *dev = &pdev->dev;
  85         int ret;
  86         struct stpmic1 *pmic;
  87         struct stpmic1_wdt *wdt;
  88 
  89         if (!dev->parent)
  90                 return -EINVAL;
  91 
  92         pmic = dev_get_drvdata(dev->parent);
  93         if (!pmic)
  94                 return -EINVAL;
  95 
  96         wdt = devm_kzalloc(dev, sizeof(struct stpmic1_wdt), GFP_KERNEL);
  97         if (!wdt)
  98                 return -ENOMEM;
  99 
 100         wdt->pmic = pmic;
 101 
 102         wdt->wdtdev.info = &pmic_watchdog_info;
 103         wdt->wdtdev.ops = &pmic_watchdog_ops;
 104         wdt->wdtdev.min_timeout = PMIC_WDT_MIN_TIMEOUT;
 105         wdt->wdtdev.max_timeout = PMIC_WDT_MAX_TIMEOUT;
 106         wdt->wdtdev.parent = dev;
 107 
 108         wdt->wdtdev.timeout = PMIC_WDT_DEFAULT_TIMEOUT;
 109         watchdog_init_timeout(&wdt->wdtdev, 0, dev);
 110 
 111         watchdog_set_nowayout(&wdt->wdtdev, nowayout);
 112         watchdog_set_drvdata(&wdt->wdtdev, wdt);
 113 
 114         ret = devm_watchdog_register_device(dev, &wdt->wdtdev);
 115         if (ret)
 116                 return ret;
 117 
 118         dev_dbg(wdt->pmic->dev, "PMIC Watchdog driver probed\n");
 119         return 0;
 120 }
 121 
 122 static const struct of_device_id of_pmic_wdt_match[] = {
 123         { .compatible = "st,stpmic1-wdt" },
 124         { },
 125 };
 126 
 127 MODULE_DEVICE_TABLE(of, of_pmic_wdt_match);
 128 
 129 static struct platform_driver stpmic1_wdt_driver = {
 130         .probe = pmic_wdt_probe,
 131         .driver = {
 132                 .name = "stpmic1-wdt",
 133                 .of_match_table = of_pmic_wdt_match,
 134         },
 135 };
 136 module_platform_driver(stpmic1_wdt_driver);
 137 
 138 MODULE_DESCRIPTION("Watchdog driver for STPMIC1 device");
 139 MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
 140 MODULE_LICENSE("GPL v2");

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