Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Spreadtrum watchdog driver
0004  * Copyright (C) 2017 Spreadtrum - http://www.spreadtrum.com
0005  */
0006 
0007 #include <linux/bitops.h>
0008 #include <linux/clk.h>
0009 #include <linux/delay.h>
0010 #include <linux/device.h>
0011 #include <linux/err.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/io.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/of.h>
0017 #include <linux/of_address.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/watchdog.h>
0020 
0021 #define SPRD_WDT_LOAD_LOW       0x0
0022 #define SPRD_WDT_LOAD_HIGH      0x4
0023 #define SPRD_WDT_CTRL           0x8
0024 #define SPRD_WDT_INT_CLR        0xc
0025 #define SPRD_WDT_INT_RAW        0x10
0026 #define SPRD_WDT_INT_MSK        0x14
0027 #define SPRD_WDT_CNT_LOW        0x18
0028 #define SPRD_WDT_CNT_HIGH       0x1c
0029 #define SPRD_WDT_LOCK           0x20
0030 #define SPRD_WDT_IRQ_LOAD_LOW       0x2c
0031 #define SPRD_WDT_IRQ_LOAD_HIGH      0x30
0032 
0033 /* WDT_CTRL */
0034 #define SPRD_WDT_INT_EN_BIT     BIT(0)
0035 #define SPRD_WDT_CNT_EN_BIT     BIT(1)
0036 #define SPRD_WDT_NEW_VER_EN     BIT(2)
0037 #define SPRD_WDT_RST_EN_BIT     BIT(3)
0038 
0039 /* WDT_INT_CLR */
0040 #define SPRD_WDT_INT_CLEAR_BIT      BIT(0)
0041 #define SPRD_WDT_RST_CLEAR_BIT      BIT(3)
0042 
0043 /* WDT_INT_RAW */
0044 #define SPRD_WDT_INT_RAW_BIT        BIT(0)
0045 #define SPRD_WDT_RST_RAW_BIT        BIT(3)
0046 #define SPRD_WDT_LD_BUSY_BIT        BIT(4)
0047 
0048 /* 1s equal to 32768 counter steps */
0049 #define SPRD_WDT_CNT_STEP       32768
0050 
0051 #define SPRD_WDT_UNLOCK_KEY     0xe551
0052 #define SPRD_WDT_MIN_TIMEOUT        3
0053 #define SPRD_WDT_MAX_TIMEOUT        60
0054 
0055 #define SPRD_WDT_CNT_HIGH_SHIFT     16
0056 #define SPRD_WDT_LOW_VALUE_MASK     GENMASK(15, 0)
0057 #define SPRD_WDT_LOAD_TIMEOUT       11
0058 
0059 struct sprd_wdt {
0060     void __iomem *base;
0061     struct watchdog_device wdd;
0062     struct clk *enable;
0063     struct clk *rtc_enable;
0064     int irq;
0065 };
0066 
0067 static inline struct sprd_wdt *to_sprd_wdt(struct watchdog_device *wdd)
0068 {
0069     return container_of(wdd, struct sprd_wdt, wdd);
0070 }
0071 
0072 static inline void sprd_wdt_lock(void __iomem *addr)
0073 {
0074     writel_relaxed(0x0, addr + SPRD_WDT_LOCK);
0075 }
0076 
0077 static inline void sprd_wdt_unlock(void __iomem *addr)
0078 {
0079     writel_relaxed(SPRD_WDT_UNLOCK_KEY, addr + SPRD_WDT_LOCK);
0080 }
0081 
0082 static irqreturn_t sprd_wdt_isr(int irq, void *dev_id)
0083 {
0084     struct sprd_wdt *wdt = (struct sprd_wdt *)dev_id;
0085 
0086     sprd_wdt_unlock(wdt->base);
0087     writel_relaxed(SPRD_WDT_INT_CLEAR_BIT, wdt->base + SPRD_WDT_INT_CLR);
0088     sprd_wdt_lock(wdt->base);
0089     watchdog_notify_pretimeout(&wdt->wdd);
0090     return IRQ_HANDLED;
0091 }
0092 
0093 static u32 sprd_wdt_get_cnt_value(struct sprd_wdt *wdt)
0094 {
0095     u32 val;
0096 
0097     val = readl_relaxed(wdt->base + SPRD_WDT_CNT_HIGH) <<
0098         SPRD_WDT_CNT_HIGH_SHIFT;
0099     val |= readl_relaxed(wdt->base + SPRD_WDT_CNT_LOW) &
0100         SPRD_WDT_LOW_VALUE_MASK;
0101 
0102     return val;
0103 }
0104 
0105 static int sprd_wdt_load_value(struct sprd_wdt *wdt, u32 timeout,
0106                    u32 pretimeout)
0107 {
0108     u32 val, delay_cnt = 0;
0109     u32 tmr_step = timeout * SPRD_WDT_CNT_STEP;
0110     u32 prtmr_step = pretimeout * SPRD_WDT_CNT_STEP;
0111 
0112     /*
0113      * Checking busy bit to make sure the previous loading operation is
0114      * done. According to the specification, the busy bit would be set
0115      * after a new loading operation and last 2 or 3 RTC clock
0116      * cycles (about 60us~92us).
0117      */
0118     do {
0119         val = readl_relaxed(wdt->base + SPRD_WDT_INT_RAW);
0120         if (!(val & SPRD_WDT_LD_BUSY_BIT))
0121             break;
0122 
0123         usleep_range(10, 100);
0124     } while (delay_cnt++ < SPRD_WDT_LOAD_TIMEOUT);
0125 
0126     if (delay_cnt >= SPRD_WDT_LOAD_TIMEOUT)
0127         return -EBUSY;
0128 
0129     sprd_wdt_unlock(wdt->base);
0130     writel_relaxed((tmr_step >> SPRD_WDT_CNT_HIGH_SHIFT) &
0131               SPRD_WDT_LOW_VALUE_MASK, wdt->base + SPRD_WDT_LOAD_HIGH);
0132     writel_relaxed((tmr_step & SPRD_WDT_LOW_VALUE_MASK),
0133                wdt->base + SPRD_WDT_LOAD_LOW);
0134     writel_relaxed((prtmr_step >> SPRD_WDT_CNT_HIGH_SHIFT) &
0135             SPRD_WDT_LOW_VALUE_MASK,
0136                wdt->base + SPRD_WDT_IRQ_LOAD_HIGH);
0137     writel_relaxed(prtmr_step & SPRD_WDT_LOW_VALUE_MASK,
0138                wdt->base + SPRD_WDT_IRQ_LOAD_LOW);
0139     sprd_wdt_lock(wdt->base);
0140 
0141     return 0;
0142 }
0143 
0144 static int sprd_wdt_enable(struct sprd_wdt *wdt)
0145 {
0146     u32 val;
0147     int ret;
0148 
0149     ret = clk_prepare_enable(wdt->enable);
0150     if (ret)
0151         return ret;
0152     ret = clk_prepare_enable(wdt->rtc_enable);
0153     if (ret) {
0154         clk_disable_unprepare(wdt->enable);
0155         return ret;
0156     }
0157 
0158     sprd_wdt_unlock(wdt->base);
0159     val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
0160     val |= SPRD_WDT_NEW_VER_EN;
0161     writel_relaxed(val, wdt->base + SPRD_WDT_CTRL);
0162     sprd_wdt_lock(wdt->base);
0163     return 0;
0164 }
0165 
0166 static void sprd_wdt_disable(void *_data)
0167 {
0168     struct sprd_wdt *wdt = _data;
0169 
0170     sprd_wdt_unlock(wdt->base);
0171     writel_relaxed(0x0, wdt->base + SPRD_WDT_CTRL);
0172     sprd_wdt_lock(wdt->base);
0173 
0174     clk_disable_unprepare(wdt->rtc_enable);
0175     clk_disable_unprepare(wdt->enable);
0176 }
0177 
0178 static int sprd_wdt_start(struct watchdog_device *wdd)
0179 {
0180     struct sprd_wdt *wdt = to_sprd_wdt(wdd);
0181     u32 val;
0182     int ret;
0183 
0184     ret = sprd_wdt_load_value(wdt, wdd->timeout, wdd->pretimeout);
0185     if (ret)
0186         return ret;
0187 
0188     sprd_wdt_unlock(wdt->base);
0189     val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
0190     val |= SPRD_WDT_CNT_EN_BIT | SPRD_WDT_INT_EN_BIT | SPRD_WDT_RST_EN_BIT;
0191     writel_relaxed(val, wdt->base + SPRD_WDT_CTRL);
0192     sprd_wdt_lock(wdt->base);
0193     set_bit(WDOG_HW_RUNNING, &wdd->status);
0194 
0195     return 0;
0196 }
0197 
0198 static int sprd_wdt_stop(struct watchdog_device *wdd)
0199 {
0200     struct sprd_wdt *wdt = to_sprd_wdt(wdd);
0201     u32 val;
0202 
0203     sprd_wdt_unlock(wdt->base);
0204     val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
0205     val &= ~(SPRD_WDT_CNT_EN_BIT | SPRD_WDT_RST_EN_BIT |
0206         SPRD_WDT_INT_EN_BIT);
0207     writel_relaxed(val, wdt->base + SPRD_WDT_CTRL);
0208     sprd_wdt_lock(wdt->base);
0209     return 0;
0210 }
0211 
0212 static int sprd_wdt_set_timeout(struct watchdog_device *wdd,
0213                 u32 timeout)
0214 {
0215     struct sprd_wdt *wdt = to_sprd_wdt(wdd);
0216 
0217     if (timeout == wdd->timeout)
0218         return 0;
0219 
0220     wdd->timeout = timeout;
0221 
0222     return sprd_wdt_load_value(wdt, timeout, wdd->pretimeout);
0223 }
0224 
0225 static int sprd_wdt_set_pretimeout(struct watchdog_device *wdd,
0226                    u32 new_pretimeout)
0227 {
0228     struct sprd_wdt *wdt = to_sprd_wdt(wdd);
0229 
0230     if (new_pretimeout < wdd->min_timeout)
0231         return -EINVAL;
0232 
0233     wdd->pretimeout = new_pretimeout;
0234 
0235     return sprd_wdt_load_value(wdt, wdd->timeout, new_pretimeout);
0236 }
0237 
0238 static u32 sprd_wdt_get_timeleft(struct watchdog_device *wdd)
0239 {
0240     struct sprd_wdt *wdt = to_sprd_wdt(wdd);
0241     u32 val;
0242 
0243     val = sprd_wdt_get_cnt_value(wdt);
0244     return val / SPRD_WDT_CNT_STEP;
0245 }
0246 
0247 static const struct watchdog_ops sprd_wdt_ops = {
0248     .owner = THIS_MODULE,
0249     .start = sprd_wdt_start,
0250     .stop = sprd_wdt_stop,
0251     .set_timeout = sprd_wdt_set_timeout,
0252     .set_pretimeout = sprd_wdt_set_pretimeout,
0253     .get_timeleft = sprd_wdt_get_timeleft,
0254 };
0255 
0256 static const struct watchdog_info sprd_wdt_info = {
0257     .options = WDIOF_SETTIMEOUT |
0258            WDIOF_PRETIMEOUT |
0259            WDIOF_MAGICCLOSE |
0260            WDIOF_KEEPALIVEPING,
0261     .identity = "Spreadtrum Watchdog Timer",
0262 };
0263 
0264 static int sprd_wdt_probe(struct platform_device *pdev)
0265 {
0266     struct device *dev = &pdev->dev;
0267     struct sprd_wdt *wdt;
0268     int ret;
0269 
0270     wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
0271     if (!wdt)
0272         return -ENOMEM;
0273 
0274     wdt->base = devm_platform_ioremap_resource(pdev, 0);
0275     if (IS_ERR(wdt->base))
0276         return PTR_ERR(wdt->base);
0277 
0278     wdt->enable = devm_clk_get(dev, "enable");
0279     if (IS_ERR(wdt->enable)) {
0280         dev_err(dev, "can't get the enable clock\n");
0281         return PTR_ERR(wdt->enable);
0282     }
0283 
0284     wdt->rtc_enable = devm_clk_get(dev, "rtc_enable");
0285     if (IS_ERR(wdt->rtc_enable)) {
0286         dev_err(dev, "can't get the rtc enable clock\n");
0287         return PTR_ERR(wdt->rtc_enable);
0288     }
0289 
0290     wdt->irq = platform_get_irq(pdev, 0);
0291     if (wdt->irq < 0)
0292         return wdt->irq;
0293 
0294     ret = devm_request_irq(dev, wdt->irq, sprd_wdt_isr, IRQF_NO_SUSPEND,
0295                    "sprd-wdt", (void *)wdt);
0296     if (ret) {
0297         dev_err(dev, "failed to register irq\n");
0298         return ret;
0299     }
0300 
0301     wdt->wdd.info = &sprd_wdt_info;
0302     wdt->wdd.ops = &sprd_wdt_ops;
0303     wdt->wdd.parent = dev;
0304     wdt->wdd.min_timeout = SPRD_WDT_MIN_TIMEOUT;
0305     wdt->wdd.max_timeout = SPRD_WDT_MAX_TIMEOUT;
0306     wdt->wdd.timeout = SPRD_WDT_MAX_TIMEOUT;
0307 
0308     ret = sprd_wdt_enable(wdt);
0309     if (ret) {
0310         dev_err(dev, "failed to enable wdt\n");
0311         return ret;
0312     }
0313     ret = devm_add_action_or_reset(dev, sprd_wdt_disable, wdt);
0314     if (ret) {
0315         dev_err(dev, "Failed to add wdt disable action\n");
0316         return ret;
0317     }
0318 
0319     watchdog_set_nowayout(&wdt->wdd, WATCHDOG_NOWAYOUT);
0320     watchdog_init_timeout(&wdt->wdd, 0, dev);
0321 
0322     ret = devm_watchdog_register_device(dev, &wdt->wdd);
0323     if (ret) {
0324         sprd_wdt_disable(wdt);
0325         return ret;
0326     }
0327     platform_set_drvdata(pdev, wdt);
0328 
0329     return 0;
0330 }
0331 
0332 static int __maybe_unused sprd_wdt_pm_suspend(struct device *dev)
0333 {
0334     struct sprd_wdt *wdt = dev_get_drvdata(dev);
0335 
0336     if (watchdog_active(&wdt->wdd))
0337         sprd_wdt_stop(&wdt->wdd);
0338     sprd_wdt_disable(wdt);
0339 
0340     return 0;
0341 }
0342 
0343 static int __maybe_unused sprd_wdt_pm_resume(struct device *dev)
0344 {
0345     struct sprd_wdt *wdt = dev_get_drvdata(dev);
0346     int ret;
0347 
0348     ret = sprd_wdt_enable(wdt);
0349     if (ret)
0350         return ret;
0351 
0352     if (watchdog_active(&wdt->wdd))
0353         ret = sprd_wdt_start(&wdt->wdd);
0354 
0355     return ret;
0356 }
0357 
0358 static const struct dev_pm_ops sprd_wdt_pm_ops = {
0359     SET_SYSTEM_SLEEP_PM_OPS(sprd_wdt_pm_suspend,
0360                 sprd_wdt_pm_resume)
0361 };
0362 
0363 static const struct of_device_id sprd_wdt_match_table[] = {
0364     { .compatible = "sprd,sp9860-wdt", },
0365     {},
0366 };
0367 MODULE_DEVICE_TABLE(of, sprd_wdt_match_table);
0368 
0369 static struct platform_driver sprd_watchdog_driver = {
0370     .probe  = sprd_wdt_probe,
0371     .driver = {
0372         .name = "sprd-wdt",
0373         .of_match_table = sprd_wdt_match_table,
0374         .pm = &sprd_wdt_pm_ops,
0375     },
0376 };
0377 module_platform_driver(sprd_watchdog_driver);
0378 
0379 MODULE_AUTHOR("Eric Long <eric.long@spreadtrum.com>");
0380 MODULE_DESCRIPTION("Spreadtrum Watchdog Timer Controller Driver");
0381 MODULE_LICENSE("GPL v2");