Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * SBSA(Server Base System Architecture) Generic Watchdog driver
0004  *
0005  * Copyright (c) 2015, Linaro Ltd.
0006  * Author: Fu Wei <fu.wei@linaro.org>
0007  *         Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>
0008  *         Al Stone <al.stone@linaro.org>
0009  *         Timur Tabi <timur@codeaurora.org>
0010  *
0011  * ARM SBSA Generic Watchdog has two stage timeouts:
0012  * the first signal (WS0) is for alerting the system by interrupt,
0013  * the second one (WS1) is a real hardware reset.
0014  * More details about the hardware specification of this device:
0015  * ARM DEN0029B - Server Base System Architecture (SBSA)
0016  *
0017  * This driver can operate ARM SBSA Generic Watchdog as a single stage watchdog
0018  * or a two stages watchdog, it's set up by the module parameter "action".
0019  * In the single stage mode, when the timeout is reached, your system
0020  * will be reset by WS1. The first signal (WS0) is ignored.
0021  * In the two stages mode, when the timeout is reached, the first signal (WS0)
0022  * will trigger panic. If the system is getting into trouble and cannot be reset
0023  * by panic or restart properly by the kdump kernel(if supported), then the
0024  * second stage (as long as the first stage) will be reached, system will be
0025  * reset by WS1. This function can help administrator to backup the system
0026  * context info by panic console output or kdump.
0027  *
0028  * SBSA GWDT:
0029  * if action is 1 (the two stages mode):
0030  * |--------WOR-------WS0--------WOR-------WS1
0031  * |----timeout-----(panic)----timeout-----reset
0032  *
0033  * if action is 0 (the single stage mode):
0034  * |------WOR-----WS0(ignored)-----WOR------WS1
0035  * |--------------timeout-------------------reset
0036  *
0037  * Note: Since this watchdog timer has two stages, and each stage is determined
0038  * by WOR, in the single stage mode, the timeout is (WOR * 2); in the two
0039  * stages mode, the timeout is WOR. The maximum timeout in the two stages mode
0040  * is half of that in the single stage mode.
0041  */
0042 
0043 #include <linux/io.h>
0044 #include <linux/io-64-nonatomic-lo-hi.h>
0045 #include <linux/interrupt.h>
0046 #include <linux/module.h>
0047 #include <linux/moduleparam.h>
0048 #include <linux/of.h>
0049 #include <linux/of_device.h>
0050 #include <linux/platform_device.h>
0051 #include <linux/uaccess.h>
0052 #include <linux/watchdog.h>
0053 #include <asm/arch_timer.h>
0054 
0055 #define DRV_NAME        "sbsa-gwdt"
0056 #define WATCHDOG_NAME       "SBSA Generic Watchdog"
0057 
0058 /* SBSA Generic Watchdog register definitions */
0059 /* refresh frame */
0060 #define SBSA_GWDT_WRR       0x000
0061 
0062 /* control frame */
0063 #define SBSA_GWDT_WCS       0x000
0064 #define SBSA_GWDT_WOR       0x008
0065 #define SBSA_GWDT_WCV       0x010
0066 
0067 /* refresh/control frame */
0068 #define SBSA_GWDT_W_IIDR    0xfcc
0069 #define SBSA_GWDT_IDR       0xfd0
0070 
0071 /* Watchdog Control and Status Register */
0072 #define SBSA_GWDT_WCS_EN    BIT(0)
0073 #define SBSA_GWDT_WCS_WS0   BIT(1)
0074 #define SBSA_GWDT_WCS_WS1   BIT(2)
0075 
0076 #define SBSA_GWDT_VERSION_MASK  0xF
0077 #define SBSA_GWDT_VERSION_SHIFT 16
0078 
0079 /**
0080  * struct sbsa_gwdt - Internal representation of the SBSA GWDT
0081  * @wdd:        kernel watchdog_device structure
0082  * @clk:        store the System Counter clock frequency, in Hz.
0083  * @version:            store the architecture version
0084  * @refresh_base:   Virtual address of the watchdog refresh frame
0085  * @control_base:   Virtual address of the watchdog control frame
0086  */
0087 struct sbsa_gwdt {
0088     struct watchdog_device  wdd;
0089     u32         clk;
0090     int         version;
0091     void __iomem        *refresh_base;
0092     void __iomem        *control_base;
0093 };
0094 
0095 #define DEFAULT_TIMEOUT     10 /* seconds */
0096 
0097 static unsigned int timeout;
0098 module_param(timeout, uint, 0);
0099 MODULE_PARM_DESC(timeout,
0100          "Watchdog timeout in seconds. (>=0, default="
0101          __MODULE_STRING(DEFAULT_TIMEOUT) ")");
0102 
0103 /*
0104  * action refers to action taken when watchdog gets WS0
0105  * 0 = skip
0106  * 1 = panic
0107  * defaults to skip (0)
0108  */
0109 static int action;
0110 module_param(action, int, 0);
0111 MODULE_PARM_DESC(action, "after watchdog gets WS0 interrupt, do: "
0112          "0 = skip(*)  1 = panic");
0113 
0114 static bool nowayout = WATCHDOG_NOWAYOUT;
0115 module_param(nowayout, bool, S_IRUGO);
0116 MODULE_PARM_DESC(nowayout,
0117          "Watchdog cannot be stopped once started (default="
0118          __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
0119 
0120 /*
0121  * Arm Base System Architecture 1.0 introduces watchdog v1 which
0122  * increases the length watchdog offset register to 48 bits.
0123  * - For version 0: WOR is 32 bits;
0124  * - For version 1: WOR is 48 bits which comprises the register
0125  * offset 0x8 and 0xC, and the bits [63:48] are reserved which are
0126  * Read-As-Zero and Writes-Ignored.
0127  */
0128 static u64 sbsa_gwdt_reg_read(struct sbsa_gwdt *gwdt)
0129 {
0130     if (gwdt->version == 0)
0131         return readl(gwdt->control_base + SBSA_GWDT_WOR);
0132     else
0133         return lo_hi_readq(gwdt->control_base + SBSA_GWDT_WOR);
0134 }
0135 
0136 static void sbsa_gwdt_reg_write(u64 val, struct sbsa_gwdt *gwdt)
0137 {
0138     if (gwdt->version == 0)
0139         writel((u32)val, gwdt->control_base + SBSA_GWDT_WOR);
0140     else
0141         lo_hi_writeq(val, gwdt->control_base + SBSA_GWDT_WOR);
0142 }
0143 
0144 /*
0145  * watchdog operation functions
0146  */
0147 static int sbsa_gwdt_set_timeout(struct watchdog_device *wdd,
0148                  unsigned int timeout)
0149 {
0150     struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
0151 
0152     wdd->timeout = timeout;
0153 
0154     if (action)
0155         sbsa_gwdt_reg_write(gwdt->clk * timeout, gwdt);
0156     else
0157         /*
0158          * In the single stage mode, The first signal (WS0) is ignored,
0159          * the timeout is (WOR * 2), so the WOR should be configured
0160          * to half value of timeout.
0161          */
0162         sbsa_gwdt_reg_write(gwdt->clk / 2 * timeout, gwdt);
0163 
0164     return 0;
0165 }
0166 
0167 static unsigned int sbsa_gwdt_get_timeleft(struct watchdog_device *wdd)
0168 {
0169     struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
0170     u64 timeleft = 0;
0171 
0172     /*
0173      * In the single stage mode, if WS0 is deasserted
0174      * (watchdog is in the first stage),
0175      * timeleft = WOR + (WCV - system counter)
0176      */
0177     if (!action &&
0178         !(readl(gwdt->control_base + SBSA_GWDT_WCS) & SBSA_GWDT_WCS_WS0))
0179         timeleft += sbsa_gwdt_reg_read(gwdt);
0180 
0181     timeleft += lo_hi_readq(gwdt->control_base + SBSA_GWDT_WCV) -
0182             arch_timer_read_counter();
0183 
0184     do_div(timeleft, gwdt->clk);
0185 
0186     return timeleft;
0187 }
0188 
0189 static int sbsa_gwdt_keepalive(struct watchdog_device *wdd)
0190 {
0191     struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
0192 
0193     /*
0194      * Writing WRR for an explicit watchdog refresh.
0195      * You can write anyting (like 0).
0196      */
0197     writel(0, gwdt->refresh_base + SBSA_GWDT_WRR);
0198 
0199     return 0;
0200 }
0201 
0202 static void sbsa_gwdt_get_version(struct watchdog_device *wdd)
0203 {
0204     struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
0205     int ver;
0206 
0207     ver = readl(gwdt->control_base + SBSA_GWDT_W_IIDR);
0208     ver = (ver >> SBSA_GWDT_VERSION_SHIFT) & SBSA_GWDT_VERSION_MASK;
0209 
0210     gwdt->version = ver;
0211 }
0212 
0213 static int sbsa_gwdt_start(struct watchdog_device *wdd)
0214 {
0215     struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
0216 
0217     /* writing WCS will cause an explicit watchdog refresh */
0218     writel(SBSA_GWDT_WCS_EN, gwdt->control_base + SBSA_GWDT_WCS);
0219 
0220     return 0;
0221 }
0222 
0223 static int sbsa_gwdt_stop(struct watchdog_device *wdd)
0224 {
0225     struct sbsa_gwdt *gwdt = watchdog_get_drvdata(wdd);
0226 
0227     /* Simply write 0 to WCS to clean WCS_EN bit */
0228     writel(0, gwdt->control_base + SBSA_GWDT_WCS);
0229 
0230     return 0;
0231 }
0232 
0233 static irqreturn_t sbsa_gwdt_interrupt(int irq, void *dev_id)
0234 {
0235     panic(WATCHDOG_NAME " timeout");
0236 
0237     return IRQ_HANDLED;
0238 }
0239 
0240 static const struct watchdog_info sbsa_gwdt_info = {
0241     .identity   = WATCHDOG_NAME,
0242     .options    = WDIOF_SETTIMEOUT |
0243               WDIOF_KEEPALIVEPING |
0244               WDIOF_MAGICCLOSE |
0245               WDIOF_CARDRESET,
0246 };
0247 
0248 static const struct watchdog_ops sbsa_gwdt_ops = {
0249     .owner      = THIS_MODULE,
0250     .start      = sbsa_gwdt_start,
0251     .stop       = sbsa_gwdt_stop,
0252     .ping       = sbsa_gwdt_keepalive,
0253     .set_timeout    = sbsa_gwdt_set_timeout,
0254     .get_timeleft   = sbsa_gwdt_get_timeleft,
0255 };
0256 
0257 static int sbsa_gwdt_probe(struct platform_device *pdev)
0258 {
0259     void __iomem *rf_base, *cf_base;
0260     struct device *dev = &pdev->dev;
0261     struct watchdog_device *wdd;
0262     struct sbsa_gwdt *gwdt;
0263     int ret, irq;
0264     u32 status;
0265 
0266     gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
0267     if (!gwdt)
0268         return -ENOMEM;
0269     platform_set_drvdata(pdev, gwdt);
0270 
0271     cf_base = devm_platform_ioremap_resource(pdev, 0);
0272     if (IS_ERR(cf_base))
0273         return PTR_ERR(cf_base);
0274 
0275     rf_base = devm_platform_ioremap_resource(pdev, 1);
0276     if (IS_ERR(rf_base))
0277         return PTR_ERR(rf_base);
0278 
0279     /*
0280      * Get the frequency of system counter from the cp15 interface of ARM
0281      * Generic timer. We don't need to check it, because if it returns "0",
0282      * system would panic in very early stage.
0283      */
0284     gwdt->clk = arch_timer_get_cntfrq();
0285     gwdt->refresh_base = rf_base;
0286     gwdt->control_base = cf_base;
0287 
0288     wdd = &gwdt->wdd;
0289     wdd->parent = dev;
0290     wdd->info = &sbsa_gwdt_info;
0291     wdd->ops = &sbsa_gwdt_ops;
0292     wdd->min_timeout = 1;
0293     wdd->timeout = DEFAULT_TIMEOUT;
0294     watchdog_set_drvdata(wdd, gwdt);
0295     watchdog_set_nowayout(wdd, nowayout);
0296     sbsa_gwdt_get_version(wdd);
0297     if (gwdt->version == 0)
0298         wdd->max_hw_heartbeat_ms = U32_MAX / gwdt->clk * 1000;
0299     else
0300         wdd->max_hw_heartbeat_ms = GENMASK_ULL(47, 0) / gwdt->clk * 1000;
0301 
0302     status = readl(cf_base + SBSA_GWDT_WCS);
0303     if (status & SBSA_GWDT_WCS_WS1) {
0304         dev_warn(dev, "System reset by WDT.\n");
0305         wdd->bootstatus |= WDIOF_CARDRESET;
0306     }
0307     if (status & SBSA_GWDT_WCS_EN)
0308         set_bit(WDOG_HW_RUNNING, &wdd->status);
0309 
0310     if (action) {
0311         irq = platform_get_irq(pdev, 0);
0312         if (irq < 0) {
0313             action = 0;
0314             dev_warn(dev, "unable to get ws0 interrupt.\n");
0315         } else {
0316             /*
0317              * In case there is a pending ws0 interrupt, just ping
0318              * the watchdog before registering the interrupt routine
0319              */
0320             writel(0, rf_base + SBSA_GWDT_WRR);
0321             if (devm_request_irq(dev, irq, sbsa_gwdt_interrupt, 0,
0322                          pdev->name, gwdt)) {
0323                 action = 0;
0324                 dev_warn(dev, "unable to request IRQ %d.\n",
0325                      irq);
0326             }
0327         }
0328         if (!action)
0329             dev_warn(dev, "falling back to single stage mode.\n");
0330     }
0331     /*
0332      * In the single stage mode, The first signal (WS0) is ignored,
0333      * the timeout is (WOR * 2), so the maximum timeout should be doubled.
0334      */
0335     if (!action)
0336         wdd->max_hw_heartbeat_ms *= 2;
0337 
0338     watchdog_init_timeout(wdd, timeout, dev);
0339     /*
0340      * Update timeout to WOR.
0341      * Because of the explicit watchdog refresh mechanism,
0342      * it's also a ping, if watchdog is enabled.
0343      */
0344     sbsa_gwdt_set_timeout(wdd, wdd->timeout);
0345 
0346     watchdog_stop_on_reboot(wdd);
0347     ret = devm_watchdog_register_device(dev, wdd);
0348     if (ret)
0349         return ret;
0350 
0351     dev_info(dev, "Initialized with %ds timeout @ %u Hz, action=%d.%s\n",
0352          wdd->timeout, gwdt->clk, action,
0353          status & SBSA_GWDT_WCS_EN ? " [enabled]" : "");
0354 
0355     return 0;
0356 }
0357 
0358 /* Disable watchdog if it is active during suspend */
0359 static int __maybe_unused sbsa_gwdt_suspend(struct device *dev)
0360 {
0361     struct sbsa_gwdt *gwdt = dev_get_drvdata(dev);
0362 
0363     if (watchdog_active(&gwdt->wdd))
0364         sbsa_gwdt_stop(&gwdt->wdd);
0365 
0366     return 0;
0367 }
0368 
0369 /* Enable watchdog if necessary */
0370 static int __maybe_unused sbsa_gwdt_resume(struct device *dev)
0371 {
0372     struct sbsa_gwdt *gwdt = dev_get_drvdata(dev);
0373 
0374     if (watchdog_active(&gwdt->wdd))
0375         sbsa_gwdt_start(&gwdt->wdd);
0376 
0377     return 0;
0378 }
0379 
0380 static const struct dev_pm_ops sbsa_gwdt_pm_ops = {
0381     SET_SYSTEM_SLEEP_PM_OPS(sbsa_gwdt_suspend, sbsa_gwdt_resume)
0382 };
0383 
0384 static const struct of_device_id sbsa_gwdt_of_match[] = {
0385     { .compatible = "arm,sbsa-gwdt", },
0386     {},
0387 };
0388 MODULE_DEVICE_TABLE(of, sbsa_gwdt_of_match);
0389 
0390 static const struct platform_device_id sbsa_gwdt_pdev_match[] = {
0391     { .name = DRV_NAME, },
0392     {},
0393 };
0394 MODULE_DEVICE_TABLE(platform, sbsa_gwdt_pdev_match);
0395 
0396 static struct platform_driver sbsa_gwdt_driver = {
0397     .driver = {
0398         .name = DRV_NAME,
0399         .pm = &sbsa_gwdt_pm_ops,
0400         .of_match_table = sbsa_gwdt_of_match,
0401     },
0402     .probe = sbsa_gwdt_probe,
0403     .id_table = sbsa_gwdt_pdev_match,
0404 };
0405 
0406 module_platform_driver(sbsa_gwdt_driver);
0407 
0408 MODULE_DESCRIPTION("SBSA Generic Watchdog Driver");
0409 MODULE_AUTHOR("Fu Wei <fu.wei@linaro.org>");
0410 MODULE_AUTHOR("Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com>");
0411 MODULE_AUTHOR("Al Stone <al.stone@linaro.org>");
0412 MODULE_AUTHOR("Timur Tabi <timur@codeaurora.org>");
0413 MODULE_LICENSE("GPL v2");