Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Watchdog driver for DA9063 PMICs.
0004  *
0005  * Copyright(c) 2012 Dialog Semiconductor Ltd.
0006  *
0007  * Author: Mariusz Wojtasik <mariusz.wojtasik@diasemi.com>
0008  *
0009  */
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/watchdog.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/uaccess.h>
0016 #include <linux/slab.h>
0017 #include <linux/i2c.h>
0018 #include <linux/delay.h>
0019 #include <linux/mfd/da9063/registers.h>
0020 #include <linux/mfd/da9063/core.h>
0021 #include <linux/property.h>
0022 #include <linux/regmap.h>
0023 
0024 /*
0025  * Watchdog selector to timeout in seconds.
0026  *   0: WDT disabled;
0027  *   others: timeout = 2048 ms * 2^(TWDSCALE-1).
0028  */
0029 static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 };
0030 static bool use_sw_pm;
0031 
0032 #define DA9063_TWDSCALE_DISABLE     0
0033 #define DA9063_TWDSCALE_MIN     1
0034 #define DA9063_TWDSCALE_MAX     (ARRAY_SIZE(wdt_timeout) - 1)
0035 #define DA9063_WDT_MIN_TIMEOUT      wdt_timeout[DA9063_TWDSCALE_MIN]
0036 #define DA9063_WDT_MAX_TIMEOUT      wdt_timeout[DA9063_TWDSCALE_MAX]
0037 #define DA9063_WDG_TIMEOUT      wdt_timeout[3]
0038 #define DA9063_RESET_PROTECTION_MS  256
0039 
0040 static unsigned int da9063_wdt_timeout_to_sel(unsigned int secs)
0041 {
0042     unsigned int i;
0043 
0044     for (i = DA9063_TWDSCALE_MIN; i <= DA9063_TWDSCALE_MAX; i++) {
0045         if (wdt_timeout[i] >= secs)
0046             return i;
0047     }
0048 
0049     return DA9063_TWDSCALE_MAX;
0050 }
0051 
0052 /*
0053  * Read the currently active timeout.
0054  * Zero means the watchdog is disabled.
0055  */
0056 static unsigned int da9063_wdt_read_timeout(struct da9063 *da9063)
0057 {
0058     unsigned int val;
0059 
0060     regmap_read(da9063->regmap, DA9063_REG_CONTROL_D, &val);
0061 
0062     return wdt_timeout[val & DA9063_TWDSCALE_MASK];
0063 }
0064 
0065 static int da9063_wdt_disable_timer(struct da9063 *da9063)
0066 {
0067     return regmap_update_bits(da9063->regmap, DA9063_REG_CONTROL_D,
0068                   DA9063_TWDSCALE_MASK,
0069                   DA9063_TWDSCALE_DISABLE);
0070 }
0071 
0072 static int
0073 da9063_wdt_update_timeout(struct da9063 *da9063, unsigned int timeout)
0074 {
0075     unsigned int regval;
0076     int ret;
0077 
0078     /*
0079      * The watchdog triggers a reboot if a timeout value is already
0080      * programmed because the timeout value combines two functions
0081      * in one: indicating the counter limit and starting the watchdog.
0082      * The watchdog must be disabled to be able to change the timeout
0083      * value if the watchdog is already running. Then we can set the
0084      * new timeout value which enables the watchdog again.
0085      */
0086     ret = da9063_wdt_disable_timer(da9063);
0087     if (ret)
0088         return ret;
0089 
0090     usleep_range(150, 300);
0091     regval = da9063_wdt_timeout_to_sel(timeout);
0092 
0093     return regmap_update_bits(da9063->regmap, DA9063_REG_CONTROL_D,
0094                   DA9063_TWDSCALE_MASK, regval);
0095 }
0096 
0097 static int da9063_wdt_start(struct watchdog_device *wdd)
0098 {
0099     struct da9063 *da9063 = watchdog_get_drvdata(wdd);
0100     int ret;
0101 
0102     ret = da9063_wdt_update_timeout(da9063, wdd->timeout);
0103     if (ret)
0104         dev_err(da9063->dev, "Watchdog failed to start (err = %d)\n",
0105             ret);
0106 
0107     return ret;
0108 }
0109 
0110 static int da9063_wdt_stop(struct watchdog_device *wdd)
0111 {
0112     struct da9063 *da9063 = watchdog_get_drvdata(wdd);
0113     int ret;
0114 
0115     ret = da9063_wdt_disable_timer(da9063);
0116     if (ret)
0117         dev_alert(da9063->dev, "Watchdog failed to stop (err = %d)\n",
0118               ret);
0119 
0120     return ret;
0121 }
0122 
0123 static int da9063_wdt_ping(struct watchdog_device *wdd)
0124 {
0125     struct da9063 *da9063 = watchdog_get_drvdata(wdd);
0126     int ret;
0127 
0128     /*
0129      * Prevent pings from occurring late in system poweroff/reboot sequence
0130      * and possibly locking out restart handler from accessing i2c bus.
0131      */
0132     if (system_state > SYSTEM_RUNNING)
0133         return 0;
0134 
0135     ret = regmap_write(da9063->regmap, DA9063_REG_CONTROL_F,
0136                DA9063_WATCHDOG);
0137     if (ret)
0138         dev_alert(da9063->dev, "Failed to ping the watchdog (err = %d)\n",
0139               ret);
0140 
0141     return ret;
0142 }
0143 
0144 static int da9063_wdt_set_timeout(struct watchdog_device *wdd,
0145                   unsigned int timeout)
0146 {
0147     struct da9063 *da9063 = watchdog_get_drvdata(wdd);
0148     int ret = 0;
0149 
0150     /*
0151      * There are two cases when a set_timeout() will be called:
0152      * 1. The watchdog is off and someone wants to set the timeout for the
0153      *    further use.
0154      * 2. The watchdog is already running and a new timeout value should be
0155      *    set.
0156      *
0157      * The watchdog can't store a timeout value not equal zero without
0158      * enabling the watchdog, so the timeout must be buffered by the driver.
0159      */
0160     if (watchdog_active(wdd))
0161         ret = da9063_wdt_update_timeout(da9063, timeout);
0162 
0163     if (ret)
0164         dev_err(da9063->dev, "Failed to set watchdog timeout (err = %d)\n",
0165             ret);
0166     else
0167         wdd->timeout = wdt_timeout[da9063_wdt_timeout_to_sel(timeout)];
0168 
0169     return ret;
0170 }
0171 
0172 static int da9063_wdt_restart(struct watchdog_device *wdd, unsigned long action,
0173                   void *data)
0174 {
0175     struct da9063 *da9063 = watchdog_get_drvdata(wdd);
0176     struct i2c_client *client = to_i2c_client(da9063->dev);
0177     int ret;
0178 
0179     /* Don't use regmap because it is not atomic safe */
0180     ret = i2c_smbus_write_byte_data(client, DA9063_REG_CONTROL_F,
0181                     DA9063_SHUTDOWN);
0182     if (ret < 0)
0183         dev_alert(da9063->dev, "Failed to shutdown (err = %d)\n",
0184               ret);
0185 
0186     /* wait for reset to assert... */
0187     mdelay(500);
0188 
0189     return ret;
0190 }
0191 
0192 static const struct watchdog_info da9063_watchdog_info = {
0193     .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
0194     .identity = "DA9063 Watchdog",
0195 };
0196 
0197 static const struct watchdog_ops da9063_watchdog_ops = {
0198     .owner = THIS_MODULE,
0199     .start = da9063_wdt_start,
0200     .stop = da9063_wdt_stop,
0201     .ping = da9063_wdt_ping,
0202     .set_timeout = da9063_wdt_set_timeout,
0203     .restart = da9063_wdt_restart,
0204 };
0205 
0206 static int da9063_wdt_probe(struct platform_device *pdev)
0207 {
0208     struct device *dev = &pdev->dev;
0209     struct da9063 *da9063;
0210     struct watchdog_device *wdd;
0211     unsigned int timeout;
0212 
0213     if (!dev->parent)
0214         return -EINVAL;
0215 
0216     da9063 = dev_get_drvdata(dev->parent);
0217     if (!da9063)
0218         return -EINVAL;
0219 
0220     wdd = devm_kzalloc(dev, sizeof(*wdd), GFP_KERNEL);
0221     if (!wdd)
0222         return -ENOMEM;
0223 
0224     use_sw_pm = device_property_present(dev, "dlg,use-sw-pm");
0225 
0226     wdd->info = &da9063_watchdog_info;
0227     wdd->ops = &da9063_watchdog_ops;
0228     wdd->min_timeout = DA9063_WDT_MIN_TIMEOUT;
0229     wdd->max_timeout = DA9063_WDT_MAX_TIMEOUT;
0230     wdd->min_hw_heartbeat_ms = DA9063_RESET_PROTECTION_MS;
0231     wdd->parent = dev;
0232     wdd->status = WATCHDOG_NOWAYOUT_INIT_STATUS;
0233 
0234     watchdog_set_restart_priority(wdd, 128);
0235     watchdog_set_drvdata(wdd, da9063);
0236     dev_set_drvdata(dev, wdd);
0237 
0238     wdd->timeout = DA9063_WDG_TIMEOUT;
0239 
0240     /* Use pre-configured timeout if watchdog is already running. */
0241     timeout = da9063_wdt_read_timeout(da9063);
0242     if (timeout)
0243         wdd->timeout = timeout;
0244 
0245     /* Set timeout, maybe override it with DT value, scale it */
0246     watchdog_init_timeout(wdd, 0, dev);
0247     da9063_wdt_set_timeout(wdd, wdd->timeout);
0248 
0249     /* Update timeout if the watchdog is already running. */
0250     if (timeout) {
0251         da9063_wdt_update_timeout(da9063, wdd->timeout);
0252         set_bit(WDOG_HW_RUNNING, &wdd->status);
0253     }
0254 
0255     return devm_watchdog_register_device(dev, wdd);
0256 }
0257 
0258 static int __maybe_unused da9063_wdt_suspend(struct device *dev)
0259 {
0260     struct watchdog_device *wdd = dev_get_drvdata(dev);
0261 
0262     if (!use_sw_pm)
0263         return 0;
0264 
0265     if (watchdog_active(wdd))
0266         return da9063_wdt_stop(wdd);
0267 
0268     return 0;
0269 }
0270 
0271 static int __maybe_unused da9063_wdt_resume(struct device *dev)
0272 {
0273     struct watchdog_device *wdd = dev_get_drvdata(dev);
0274 
0275     if (!use_sw_pm)
0276         return 0;
0277 
0278     if (watchdog_active(wdd))
0279         return da9063_wdt_start(wdd);
0280 
0281     return 0;
0282 }
0283 
0284 static SIMPLE_DEV_PM_OPS(da9063_wdt_pm_ops,
0285             da9063_wdt_suspend, da9063_wdt_resume);
0286 
0287 static struct platform_driver da9063_wdt_driver = {
0288     .probe = da9063_wdt_probe,
0289     .driver = {
0290         .name = DA9063_DRVNAME_WATCHDOG,
0291         .pm = &da9063_wdt_pm_ops,
0292     },
0293 };
0294 module_platform_driver(da9063_wdt_driver);
0295 
0296 MODULE_AUTHOR("Mariusz Wojtasik <mariusz.wojtasik@diasemi.com>");
0297 MODULE_DESCRIPTION("Watchdog driver for Dialog DA9063");
0298 MODULE_LICENSE("GPL");
0299 MODULE_ALIAS("platform:" DA9063_DRVNAME_WATCHDOG);