Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright 2010-2011 Picochip Ltd., Jamie Iles
0004  * https://www.picochip.com
0005  *
0006  * This file implements a driver for the Synopsys DesignWare watchdog device
0007  * in the many subsystems. The watchdog has 16 different timeout periods
0008  * and these are a function of the input clock frequency.
0009  *
0010  * The DesignWare watchdog cannot be stopped once it has been started so we
0011  * do not implement a stop function. The watchdog core will continue to send
0012  * heartbeat requests after the watchdog device has been closed.
0013  */
0014 
0015 #include <linux/bitops.h>
0016 #include <linux/clk.h>
0017 #include <linux/debugfs.h>
0018 #include <linux/delay.h>
0019 #include <linux/err.h>
0020 #include <linux/interrupt.h>
0021 #include <linux/io.h>
0022 #include <linux/kernel.h>
0023 #include <linux/limits.h>
0024 #include <linux/module.h>
0025 #include <linux/moduleparam.h>
0026 #include <linux/of.h>
0027 #include <linux/platform_device.h>
0028 #include <linux/pm.h>
0029 #include <linux/reset.h>
0030 #include <linux/watchdog.h>
0031 
0032 #define WDOG_CONTROL_REG_OFFSET         0x00
0033 #define WDOG_CONTROL_REG_WDT_EN_MASK        0x01
0034 #define WDOG_CONTROL_REG_RESP_MODE_MASK     0x02
0035 #define WDOG_TIMEOUT_RANGE_REG_OFFSET       0x04
0036 #define WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT    4
0037 #define WDOG_CURRENT_COUNT_REG_OFFSET       0x08
0038 #define WDOG_COUNTER_RESTART_REG_OFFSET     0x0c
0039 #define WDOG_COUNTER_RESTART_KICK_VALUE     0x76
0040 #define WDOG_INTERRUPT_STATUS_REG_OFFSET    0x10
0041 #define WDOG_INTERRUPT_CLEAR_REG_OFFSET     0x14
0042 #define WDOG_COMP_PARAMS_5_REG_OFFSET       0xe4
0043 #define WDOG_COMP_PARAMS_4_REG_OFFSET       0xe8
0044 #define WDOG_COMP_PARAMS_3_REG_OFFSET       0xec
0045 #define WDOG_COMP_PARAMS_2_REG_OFFSET       0xf0
0046 #define WDOG_COMP_PARAMS_1_REG_OFFSET       0xf4
0047 #define WDOG_COMP_PARAMS_1_USE_FIX_TOP      BIT(6)
0048 #define WDOG_COMP_VERSION_REG_OFFSET        0xf8
0049 #define WDOG_COMP_TYPE_REG_OFFSET           0xfc
0050 
0051 /* There are sixteen TOPs (timeout periods) that can be set in the watchdog. */
0052 #define DW_WDT_NUM_TOPS     16
0053 #define DW_WDT_FIX_TOP(_idx)    (1U << (16 + _idx))
0054 
0055 #define DW_WDT_DEFAULT_SECONDS  30
0056 
0057 static const u32 dw_wdt_fix_tops[DW_WDT_NUM_TOPS] = {
0058     DW_WDT_FIX_TOP(0), DW_WDT_FIX_TOP(1), DW_WDT_FIX_TOP(2),
0059     DW_WDT_FIX_TOP(3), DW_WDT_FIX_TOP(4), DW_WDT_FIX_TOP(5),
0060     DW_WDT_FIX_TOP(6), DW_WDT_FIX_TOP(7), DW_WDT_FIX_TOP(8),
0061     DW_WDT_FIX_TOP(9), DW_WDT_FIX_TOP(10), DW_WDT_FIX_TOP(11),
0062     DW_WDT_FIX_TOP(12), DW_WDT_FIX_TOP(13), DW_WDT_FIX_TOP(14),
0063     DW_WDT_FIX_TOP(15)
0064 };
0065 
0066 static bool nowayout = WATCHDOG_NOWAYOUT;
0067 module_param(nowayout, bool, 0);
0068 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
0069          "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
0070 
0071 enum dw_wdt_rmod {
0072     DW_WDT_RMOD_RESET = 1,
0073     DW_WDT_RMOD_IRQ = 2
0074 };
0075 
0076 struct dw_wdt_timeout {
0077     u32 top_val;
0078     unsigned int sec;
0079     unsigned int msec;
0080 };
0081 
0082 struct dw_wdt {
0083     void __iomem        *regs;
0084     struct clk      *clk;
0085     struct clk      *pclk;
0086     unsigned long       rate;
0087     enum dw_wdt_rmod    rmod;
0088     struct dw_wdt_timeout   timeouts[DW_WDT_NUM_TOPS];
0089     struct watchdog_device  wdd;
0090     struct reset_control    *rst;
0091     /* Save/restore */
0092     u32         control;
0093     u32         timeout;
0094 
0095 #ifdef CONFIG_DEBUG_FS
0096     struct dentry       *dbgfs_dir;
0097 #endif
0098 };
0099 
0100 #define to_dw_wdt(wdd)  container_of(wdd, struct dw_wdt, wdd)
0101 
0102 static inline int dw_wdt_is_enabled(struct dw_wdt *dw_wdt)
0103 {
0104     return readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET) &
0105         WDOG_CONTROL_REG_WDT_EN_MASK;
0106 }
0107 
0108 static void dw_wdt_update_mode(struct dw_wdt *dw_wdt, enum dw_wdt_rmod rmod)
0109 {
0110     u32 val;
0111 
0112     val = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
0113     if (rmod == DW_WDT_RMOD_IRQ)
0114         val |= WDOG_CONTROL_REG_RESP_MODE_MASK;
0115     else
0116         val &= ~WDOG_CONTROL_REG_RESP_MODE_MASK;
0117     writel(val, dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
0118 
0119     dw_wdt->rmod = rmod;
0120 }
0121 
0122 static unsigned int dw_wdt_find_best_top(struct dw_wdt *dw_wdt,
0123                      unsigned int timeout, u32 *top_val)
0124 {
0125     int idx;
0126 
0127     /*
0128      * Find a TOP with timeout greater or equal to the requested number.
0129      * Note we'll select a TOP with maximum timeout if the requested
0130      * timeout couldn't be reached.
0131      */
0132     for (idx = 0; idx < DW_WDT_NUM_TOPS; ++idx) {
0133         if (dw_wdt->timeouts[idx].sec >= timeout)
0134             break;
0135     }
0136 
0137     if (idx == DW_WDT_NUM_TOPS)
0138         --idx;
0139 
0140     *top_val = dw_wdt->timeouts[idx].top_val;
0141 
0142     return dw_wdt->timeouts[idx].sec;
0143 }
0144 
0145 static unsigned int dw_wdt_get_min_timeout(struct dw_wdt *dw_wdt)
0146 {
0147     int idx;
0148 
0149     /*
0150      * We'll find a timeout greater or equal to one second anyway because
0151      * the driver probe would have failed if there was none.
0152      */
0153     for (idx = 0; idx < DW_WDT_NUM_TOPS; ++idx) {
0154         if (dw_wdt->timeouts[idx].sec)
0155             break;
0156     }
0157 
0158     return dw_wdt->timeouts[idx].sec;
0159 }
0160 
0161 static unsigned int dw_wdt_get_max_timeout_ms(struct dw_wdt *dw_wdt)
0162 {
0163     struct dw_wdt_timeout *timeout = &dw_wdt->timeouts[DW_WDT_NUM_TOPS - 1];
0164     u64 msec;
0165 
0166     msec = (u64)timeout->sec * MSEC_PER_SEC + timeout->msec;
0167 
0168     return msec < UINT_MAX ? msec : UINT_MAX;
0169 }
0170 
0171 static unsigned int dw_wdt_get_timeout(struct dw_wdt *dw_wdt)
0172 {
0173     int top_val = readl(dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET) & 0xF;
0174     int idx;
0175 
0176     for (idx = 0; idx < DW_WDT_NUM_TOPS; ++idx) {
0177         if (dw_wdt->timeouts[idx].top_val == top_val)
0178             break;
0179     }
0180 
0181     /*
0182      * In IRQ mode due to the two stages counter, the actual timeout is
0183      * twice greater than the TOP setting.
0184      */
0185     return dw_wdt->timeouts[idx].sec * dw_wdt->rmod;
0186 }
0187 
0188 static int dw_wdt_ping(struct watchdog_device *wdd)
0189 {
0190     struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
0191 
0192     writel(WDOG_COUNTER_RESTART_KICK_VALUE, dw_wdt->regs +
0193            WDOG_COUNTER_RESTART_REG_OFFSET);
0194 
0195     return 0;
0196 }
0197 
0198 static int dw_wdt_set_timeout(struct watchdog_device *wdd, unsigned int top_s)
0199 {
0200     struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
0201     unsigned int timeout;
0202     u32 top_val;
0203 
0204     /*
0205      * Note IRQ mode being enabled means having a non-zero pre-timeout
0206      * setup. In this case we try to find a TOP as close to the half of the
0207      * requested timeout as possible since DW Watchdog IRQ mode is designed
0208      * in two stages way - first timeout rises the pre-timeout interrupt,
0209      * second timeout performs the system reset. So basically the effective
0210      * watchdog-caused reset happens after two watchdog TOPs elapsed.
0211      */
0212     timeout = dw_wdt_find_best_top(dw_wdt, DIV_ROUND_UP(top_s, dw_wdt->rmod),
0213                        &top_val);
0214     if (dw_wdt->rmod == DW_WDT_RMOD_IRQ)
0215         wdd->pretimeout = timeout;
0216     else
0217         wdd->pretimeout = 0;
0218 
0219     /*
0220      * Set the new value in the watchdog.  Some versions of dw_wdt
0221      * have TOPINIT in the TIMEOUT_RANGE register (as per
0222      * CP_WDT_DUAL_TOP in WDT_COMP_PARAMS_1).  On those we
0223      * effectively get a pat of the watchdog right here.
0224      */
0225     writel(top_val | top_val << WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT,
0226            dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
0227 
0228     /* Kick new TOP value into the watchdog counter if activated. */
0229     if (watchdog_active(wdd))
0230         dw_wdt_ping(wdd);
0231 
0232     /*
0233      * In case users set bigger timeout value than HW can support,
0234      * kernel(watchdog_dev.c) helps to feed watchdog before
0235      * wdd->max_hw_heartbeat_ms
0236      */
0237     if (top_s * 1000 <= wdd->max_hw_heartbeat_ms)
0238         wdd->timeout = timeout * dw_wdt->rmod;
0239     else
0240         wdd->timeout = top_s;
0241 
0242     return 0;
0243 }
0244 
0245 static int dw_wdt_set_pretimeout(struct watchdog_device *wdd, unsigned int req)
0246 {
0247     struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
0248 
0249     /*
0250      * We ignore actual value of the timeout passed from user-space
0251      * using it as a flag whether the pretimeout functionality is intended
0252      * to be activated.
0253      */
0254     dw_wdt_update_mode(dw_wdt, req ? DW_WDT_RMOD_IRQ : DW_WDT_RMOD_RESET);
0255     dw_wdt_set_timeout(wdd, wdd->timeout);
0256 
0257     return 0;
0258 }
0259 
0260 static void dw_wdt_arm_system_reset(struct dw_wdt *dw_wdt)
0261 {
0262     u32 val = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
0263 
0264     /* Disable/enable interrupt mode depending on the RMOD flag. */
0265     if (dw_wdt->rmod == DW_WDT_RMOD_IRQ)
0266         val |= WDOG_CONTROL_REG_RESP_MODE_MASK;
0267     else
0268         val &= ~WDOG_CONTROL_REG_RESP_MODE_MASK;
0269     /* Enable watchdog. */
0270     val |= WDOG_CONTROL_REG_WDT_EN_MASK;
0271     writel(val, dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
0272 }
0273 
0274 static int dw_wdt_start(struct watchdog_device *wdd)
0275 {
0276     struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
0277 
0278     dw_wdt_set_timeout(wdd, wdd->timeout);
0279     dw_wdt_ping(&dw_wdt->wdd);
0280     dw_wdt_arm_system_reset(dw_wdt);
0281 
0282     return 0;
0283 }
0284 
0285 static int dw_wdt_stop(struct watchdog_device *wdd)
0286 {
0287     struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
0288 
0289     if (!dw_wdt->rst) {
0290         set_bit(WDOG_HW_RUNNING, &wdd->status);
0291         return 0;
0292     }
0293 
0294     reset_control_assert(dw_wdt->rst);
0295     reset_control_deassert(dw_wdt->rst);
0296 
0297     return 0;
0298 }
0299 
0300 static int dw_wdt_restart(struct watchdog_device *wdd,
0301               unsigned long action, void *data)
0302 {
0303     struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
0304 
0305     writel(0, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
0306     dw_wdt_update_mode(dw_wdt, DW_WDT_RMOD_RESET);
0307     if (dw_wdt_is_enabled(dw_wdt))
0308         writel(WDOG_COUNTER_RESTART_KICK_VALUE,
0309                dw_wdt->regs + WDOG_COUNTER_RESTART_REG_OFFSET);
0310     else
0311         dw_wdt_arm_system_reset(dw_wdt);
0312 
0313     /* wait for reset to assert... */
0314     mdelay(500);
0315 
0316     return 0;
0317 }
0318 
0319 static unsigned int dw_wdt_get_timeleft(struct watchdog_device *wdd)
0320 {
0321     struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
0322     unsigned int sec;
0323     u32 val;
0324 
0325     val = readl(dw_wdt->regs + WDOG_CURRENT_COUNT_REG_OFFSET);
0326     sec = val / dw_wdt->rate;
0327 
0328     if (dw_wdt->rmod == DW_WDT_RMOD_IRQ) {
0329         val = readl(dw_wdt->regs + WDOG_INTERRUPT_STATUS_REG_OFFSET);
0330         if (!val)
0331             sec += wdd->pretimeout;
0332     }
0333 
0334     return sec;
0335 }
0336 
0337 static const struct watchdog_info dw_wdt_ident = {
0338     .options    = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
0339               WDIOF_MAGICCLOSE,
0340     .identity   = "Synopsys DesignWare Watchdog",
0341 };
0342 
0343 static const struct watchdog_info dw_wdt_pt_ident = {
0344     .options    = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
0345               WDIOF_PRETIMEOUT | WDIOF_MAGICCLOSE,
0346     .identity   = "Synopsys DesignWare Watchdog",
0347 };
0348 
0349 static const struct watchdog_ops dw_wdt_ops = {
0350     .owner      = THIS_MODULE,
0351     .start      = dw_wdt_start,
0352     .stop       = dw_wdt_stop,
0353     .ping       = dw_wdt_ping,
0354     .set_timeout    = dw_wdt_set_timeout,
0355     .set_pretimeout = dw_wdt_set_pretimeout,
0356     .get_timeleft   = dw_wdt_get_timeleft,
0357     .restart    = dw_wdt_restart,
0358 };
0359 
0360 static irqreturn_t dw_wdt_irq(int irq, void *devid)
0361 {
0362     struct dw_wdt *dw_wdt = devid;
0363     u32 val;
0364 
0365     /*
0366      * We don't clear the IRQ status. It's supposed to be done by the
0367      * following ping operations.
0368      */
0369     val = readl(dw_wdt->regs + WDOG_INTERRUPT_STATUS_REG_OFFSET);
0370     if (!val)
0371         return IRQ_NONE;
0372 
0373     watchdog_notify_pretimeout(&dw_wdt->wdd);
0374 
0375     return IRQ_HANDLED;
0376 }
0377 
0378 static int dw_wdt_suspend(struct device *dev)
0379 {
0380     struct dw_wdt *dw_wdt = dev_get_drvdata(dev);
0381 
0382     dw_wdt->control = readl(dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
0383     dw_wdt->timeout = readl(dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
0384 
0385     clk_disable_unprepare(dw_wdt->pclk);
0386     clk_disable_unprepare(dw_wdt->clk);
0387 
0388     return 0;
0389 }
0390 
0391 static int dw_wdt_resume(struct device *dev)
0392 {
0393     struct dw_wdt *dw_wdt = dev_get_drvdata(dev);
0394     int err = clk_prepare_enable(dw_wdt->clk);
0395 
0396     if (err)
0397         return err;
0398 
0399     err = clk_prepare_enable(dw_wdt->pclk);
0400     if (err) {
0401         clk_disable_unprepare(dw_wdt->clk);
0402         return err;
0403     }
0404 
0405     writel(dw_wdt->timeout, dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
0406     writel(dw_wdt->control, dw_wdt->regs + WDOG_CONTROL_REG_OFFSET);
0407 
0408     dw_wdt_ping(&dw_wdt->wdd);
0409 
0410     return 0;
0411 }
0412 
0413 static DEFINE_SIMPLE_DEV_PM_OPS(dw_wdt_pm_ops, dw_wdt_suspend, dw_wdt_resume);
0414 
0415 /*
0416  * In case if DW WDT IP core is synthesized with fixed TOP feature disabled the
0417  * TOPs array can be arbitrary ordered with nearly any sixteen uint numbers
0418  * depending on the system engineer imagination. The next method handles the
0419  * passed TOPs array to pre-calculate the effective timeouts and to sort the
0420  * TOP items out in the ascending order with respect to the timeouts.
0421  */
0422 
0423 static void dw_wdt_handle_tops(struct dw_wdt *dw_wdt, const u32 *tops)
0424 {
0425     struct dw_wdt_timeout tout, *dst;
0426     int val, tidx;
0427     u64 msec;
0428 
0429     /*
0430      * We walk over the passed TOPs array and calculate corresponding
0431      * timeouts in seconds and milliseconds. The milliseconds granularity
0432      * is needed to distinguish the TOPs with very close timeouts and to
0433      * set the watchdog max heartbeat setting further.
0434      */
0435     for (val = 0; val < DW_WDT_NUM_TOPS; ++val) {
0436         tout.top_val = val;
0437         tout.sec = tops[val] / dw_wdt->rate;
0438         msec = (u64)tops[val] * MSEC_PER_SEC;
0439         do_div(msec, dw_wdt->rate);
0440         tout.msec = msec - ((u64)tout.sec * MSEC_PER_SEC);
0441 
0442         /*
0443          * Find a suitable place for the current TOP in the timeouts
0444          * array so that the list is remained in the ascending order.
0445          */
0446         for (tidx = 0; tidx < val; ++tidx) {
0447             dst = &dw_wdt->timeouts[tidx];
0448             if (tout.sec > dst->sec || (tout.sec == dst->sec &&
0449                 tout.msec >= dst->msec))
0450                 continue;
0451             else
0452                 swap(*dst, tout);
0453         }
0454 
0455         dw_wdt->timeouts[val] = tout;
0456     }
0457 }
0458 
0459 static int dw_wdt_init_timeouts(struct dw_wdt *dw_wdt, struct device *dev)
0460 {
0461     u32 data, of_tops[DW_WDT_NUM_TOPS];
0462     const u32 *tops;
0463     int ret;
0464 
0465     /*
0466      * Retrieve custom or fixed counter values depending on the
0467      * WDT_USE_FIX_TOP flag found in the component specific parameters
0468      * #1 register.
0469      */
0470     data = readl(dw_wdt->regs + WDOG_COMP_PARAMS_1_REG_OFFSET);
0471     if (data & WDOG_COMP_PARAMS_1_USE_FIX_TOP) {
0472         tops = dw_wdt_fix_tops;
0473     } else {
0474         ret = of_property_read_variable_u32_array(dev_of_node(dev),
0475             "snps,watchdog-tops", of_tops, DW_WDT_NUM_TOPS,
0476             DW_WDT_NUM_TOPS);
0477         if (ret < 0) {
0478             dev_warn(dev, "No valid TOPs array specified\n");
0479             tops = dw_wdt_fix_tops;
0480         } else {
0481             tops = of_tops;
0482         }
0483     }
0484 
0485     /* Convert the specified TOPs into an array of watchdog timeouts. */
0486     dw_wdt_handle_tops(dw_wdt, tops);
0487     if (!dw_wdt->timeouts[DW_WDT_NUM_TOPS - 1].sec) {
0488         dev_err(dev, "No any valid TOP detected\n");
0489         return -EINVAL;
0490     }
0491 
0492     return 0;
0493 }
0494 
0495 #ifdef CONFIG_DEBUG_FS
0496 
0497 #define DW_WDT_DBGFS_REG(_name, _off) \
0498 {                     \
0499     .name = _name,            \
0500     .offset = _off            \
0501 }
0502 
0503 static const struct debugfs_reg32 dw_wdt_dbgfs_regs[] = {
0504     DW_WDT_DBGFS_REG("cr", WDOG_CONTROL_REG_OFFSET),
0505     DW_WDT_DBGFS_REG("torr", WDOG_TIMEOUT_RANGE_REG_OFFSET),
0506     DW_WDT_DBGFS_REG("ccvr", WDOG_CURRENT_COUNT_REG_OFFSET),
0507     DW_WDT_DBGFS_REG("crr", WDOG_COUNTER_RESTART_REG_OFFSET),
0508     DW_WDT_DBGFS_REG("stat", WDOG_INTERRUPT_STATUS_REG_OFFSET),
0509     DW_WDT_DBGFS_REG("param5", WDOG_COMP_PARAMS_5_REG_OFFSET),
0510     DW_WDT_DBGFS_REG("param4", WDOG_COMP_PARAMS_4_REG_OFFSET),
0511     DW_WDT_DBGFS_REG("param3", WDOG_COMP_PARAMS_3_REG_OFFSET),
0512     DW_WDT_DBGFS_REG("param2", WDOG_COMP_PARAMS_2_REG_OFFSET),
0513     DW_WDT_DBGFS_REG("param1", WDOG_COMP_PARAMS_1_REG_OFFSET),
0514     DW_WDT_DBGFS_REG("version", WDOG_COMP_VERSION_REG_OFFSET),
0515     DW_WDT_DBGFS_REG("type", WDOG_COMP_TYPE_REG_OFFSET)
0516 };
0517 
0518 static void dw_wdt_dbgfs_init(struct dw_wdt *dw_wdt)
0519 {
0520     struct device *dev = dw_wdt->wdd.parent;
0521     struct debugfs_regset32 *regset;
0522 
0523     regset = devm_kzalloc(dev, sizeof(*regset), GFP_KERNEL);
0524     if (!regset)
0525         return;
0526 
0527     regset->regs = dw_wdt_dbgfs_regs;
0528     regset->nregs = ARRAY_SIZE(dw_wdt_dbgfs_regs);
0529     regset->base = dw_wdt->regs;
0530 
0531     dw_wdt->dbgfs_dir = debugfs_create_dir(dev_name(dev), NULL);
0532 
0533     debugfs_create_regset32("registers", 0444, dw_wdt->dbgfs_dir, regset);
0534 }
0535 
0536 static void dw_wdt_dbgfs_clear(struct dw_wdt *dw_wdt)
0537 {
0538     debugfs_remove_recursive(dw_wdt->dbgfs_dir);
0539 }
0540 
0541 #else /* !CONFIG_DEBUG_FS */
0542 
0543 static void dw_wdt_dbgfs_init(struct dw_wdt *dw_wdt) {}
0544 static void dw_wdt_dbgfs_clear(struct dw_wdt *dw_wdt) {}
0545 
0546 #endif /* !CONFIG_DEBUG_FS */
0547 
0548 static int dw_wdt_drv_probe(struct platform_device *pdev)
0549 {
0550     struct device *dev = &pdev->dev;
0551     struct watchdog_device *wdd;
0552     struct dw_wdt *dw_wdt;
0553     int ret;
0554 
0555     dw_wdt = devm_kzalloc(dev, sizeof(*dw_wdt), GFP_KERNEL);
0556     if (!dw_wdt)
0557         return -ENOMEM;
0558 
0559     dw_wdt->regs = devm_platform_ioremap_resource(pdev, 0);
0560     if (IS_ERR(dw_wdt->regs))
0561         return PTR_ERR(dw_wdt->regs);
0562 
0563     /*
0564      * Try to request the watchdog dedicated timer clock source. It must
0565      * be supplied if asynchronous mode is enabled. Otherwise fallback
0566      * to the common timer/bus clocks configuration, in which the very
0567      * first found clock supply both timer and APB signals.
0568      */
0569     dw_wdt->clk = devm_clk_get(dev, "tclk");
0570     if (IS_ERR(dw_wdt->clk)) {
0571         dw_wdt->clk = devm_clk_get(dev, NULL);
0572         if (IS_ERR(dw_wdt->clk))
0573             return PTR_ERR(dw_wdt->clk);
0574     }
0575 
0576     ret = clk_prepare_enable(dw_wdt->clk);
0577     if (ret)
0578         return ret;
0579 
0580     dw_wdt->rate = clk_get_rate(dw_wdt->clk);
0581     if (dw_wdt->rate == 0) {
0582         ret = -EINVAL;
0583         goto out_disable_clk;
0584     }
0585 
0586     /*
0587      * Request APB clock if device is configured with async clocks mode.
0588      * In this case both tclk and pclk clocks are supposed to be specified.
0589      * Alas we can't know for sure whether async mode was really activated,
0590      * so the pclk phandle reference is left optional. If it couldn't be
0591      * found we consider the device configured in synchronous clocks mode.
0592      */
0593     dw_wdt->pclk = devm_clk_get_optional(dev, "pclk");
0594     if (IS_ERR(dw_wdt->pclk)) {
0595         ret = PTR_ERR(dw_wdt->pclk);
0596         goto out_disable_clk;
0597     }
0598 
0599     ret = clk_prepare_enable(dw_wdt->pclk);
0600     if (ret)
0601         goto out_disable_clk;
0602 
0603     dw_wdt->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
0604     if (IS_ERR(dw_wdt->rst)) {
0605         ret = PTR_ERR(dw_wdt->rst);
0606         goto out_disable_pclk;
0607     }
0608 
0609     /* Enable normal reset without pre-timeout by default. */
0610     dw_wdt_update_mode(dw_wdt, DW_WDT_RMOD_RESET);
0611 
0612     /*
0613      * Pre-timeout IRQ is optional, since some hardware may lack support
0614      * of it. Note we must request rising-edge IRQ, since the lane is left
0615      * pending either until the next watchdog kick event or up to the
0616      * system reset.
0617      */
0618     ret = platform_get_irq_optional(pdev, 0);
0619     if (ret > 0) {
0620         ret = devm_request_irq(dev, ret, dw_wdt_irq,
0621                        IRQF_SHARED | IRQF_TRIGGER_RISING,
0622                        pdev->name, dw_wdt);
0623         if (ret)
0624             goto out_disable_pclk;
0625 
0626         dw_wdt->wdd.info = &dw_wdt_pt_ident;
0627     } else {
0628         if (ret == -EPROBE_DEFER)
0629             goto out_disable_pclk;
0630 
0631         dw_wdt->wdd.info = &dw_wdt_ident;
0632     }
0633 
0634     reset_control_deassert(dw_wdt->rst);
0635 
0636     ret = dw_wdt_init_timeouts(dw_wdt, dev);
0637     if (ret)
0638         goto out_disable_clk;
0639 
0640     wdd = &dw_wdt->wdd;
0641     wdd->ops = &dw_wdt_ops;
0642     wdd->min_timeout = dw_wdt_get_min_timeout(dw_wdt);
0643     wdd->max_hw_heartbeat_ms = dw_wdt_get_max_timeout_ms(dw_wdt);
0644     wdd->parent = dev;
0645 
0646     watchdog_set_drvdata(wdd, dw_wdt);
0647     watchdog_set_nowayout(wdd, nowayout);
0648     watchdog_init_timeout(wdd, 0, dev);
0649 
0650     /*
0651      * If the watchdog is already running, use its already configured
0652      * timeout. Otherwise use the default or the value provided through
0653      * devicetree.
0654      */
0655     if (dw_wdt_is_enabled(dw_wdt)) {
0656         wdd->timeout = dw_wdt_get_timeout(dw_wdt);
0657         set_bit(WDOG_HW_RUNNING, &wdd->status);
0658     } else {
0659         wdd->timeout = DW_WDT_DEFAULT_SECONDS;
0660         watchdog_init_timeout(wdd, 0, dev);
0661     }
0662 
0663     platform_set_drvdata(pdev, dw_wdt);
0664 
0665     watchdog_set_restart_priority(wdd, 128);
0666 
0667     ret = watchdog_register_device(wdd);
0668     if (ret)
0669         goto out_disable_pclk;
0670 
0671     dw_wdt_dbgfs_init(dw_wdt);
0672 
0673     return 0;
0674 
0675 out_disable_pclk:
0676     clk_disable_unprepare(dw_wdt->pclk);
0677 
0678 out_disable_clk:
0679     clk_disable_unprepare(dw_wdt->clk);
0680     return ret;
0681 }
0682 
0683 static int dw_wdt_drv_remove(struct platform_device *pdev)
0684 {
0685     struct dw_wdt *dw_wdt = platform_get_drvdata(pdev);
0686 
0687     dw_wdt_dbgfs_clear(dw_wdt);
0688 
0689     watchdog_unregister_device(&dw_wdt->wdd);
0690     reset_control_assert(dw_wdt->rst);
0691     clk_disable_unprepare(dw_wdt->pclk);
0692     clk_disable_unprepare(dw_wdt->clk);
0693 
0694     return 0;
0695 }
0696 
0697 #ifdef CONFIG_OF
0698 static const struct of_device_id dw_wdt_of_match[] = {
0699     { .compatible = "snps,dw-wdt", },
0700     { /* sentinel */ }
0701 };
0702 MODULE_DEVICE_TABLE(of, dw_wdt_of_match);
0703 #endif
0704 
0705 static struct platform_driver dw_wdt_driver = {
0706     .probe      = dw_wdt_drv_probe,
0707     .remove     = dw_wdt_drv_remove,
0708     .driver     = {
0709         .name   = "dw_wdt",
0710         .of_match_table = of_match_ptr(dw_wdt_of_match),
0711         .pm = pm_sleep_ptr(&dw_wdt_pm_ops),
0712     },
0713 };
0714 
0715 module_platform_driver(dw_wdt_driver);
0716 
0717 MODULE_AUTHOR("Jamie Iles");
0718 MODULE_DESCRIPTION("Synopsys DesignWare Watchdog Driver");
0719 MODULE_LICENSE("GPL");