0001
0002
0003
0004
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
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
0040 #define SPRD_WDT_INT_CLEAR_BIT BIT(0)
0041 #define SPRD_WDT_RST_CLEAR_BIT BIT(3)
0042
0043
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
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
0114
0115
0116
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");