0001
0002
0003
0004
0005
0006
0007 #include <linux/bitops.h>
0008 #include <linux/clk.h>
0009 #include <linux/delay.h>
0010 #include <linux/io.h>
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/of.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/pm_runtime.h>
0016 #include <linux/reset.h>
0017 #include <linux/units.h>
0018 #include <linux/watchdog.h>
0019
0020 #define WDTCNT 0x00
0021 #define WDTSET 0x04
0022 #define WDTTIM 0x08
0023 #define WDTINT 0x0C
0024 #define PECR 0x10
0025 #define PEEN 0x14
0026 #define WDTCNT_WDTEN BIT(0)
0027 #define WDTINT_INTDISP BIT(0)
0028 #define PEEN_FORCE BIT(0)
0029
0030 #define WDT_DEFAULT_TIMEOUT 60U
0031
0032
0033 #define WDTSET_COUNTER_MASK (0xFFF00000)
0034 #define WDTSET_COUNTER_VAL(f) ((f) << 20)
0035
0036 #define F2CYCLE_NSEC(f) (1000000000 / (f))
0037
0038 static bool nowayout = WATCHDOG_NOWAYOUT;
0039 module_param(nowayout, bool, 0);
0040 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
0041 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
0042
0043 struct rzg2l_wdt_priv {
0044 void __iomem *base;
0045 struct watchdog_device wdev;
0046 struct reset_control *rstc;
0047 unsigned long osc_clk_rate;
0048 unsigned long delay;
0049 struct clk *pclk;
0050 struct clk *osc_clk;
0051 };
0052
0053 static void rzg2l_wdt_wait_delay(struct rzg2l_wdt_priv *priv)
0054 {
0055
0056 ndelay(priv->delay);
0057 }
0058
0059 static u32 rzg2l_wdt_get_cycle_usec(unsigned long cycle, u32 wdttime)
0060 {
0061 u64 timer_cycle_us = 1024 * 1024ULL * (wdttime + 1) * MICRO;
0062
0063 return div64_ul(timer_cycle_us, cycle);
0064 }
0065
0066 static void rzg2l_wdt_write(struct rzg2l_wdt_priv *priv, u32 val, unsigned int reg)
0067 {
0068 if (reg == WDTSET)
0069 val &= WDTSET_COUNTER_MASK;
0070
0071 writel_relaxed(val, priv->base + reg);
0072
0073 if (reg != WDTINT)
0074 rzg2l_wdt_wait_delay(priv);
0075 }
0076
0077 static void rzg2l_wdt_init_timeout(struct watchdog_device *wdev)
0078 {
0079 struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
0080 u32 time_out;
0081
0082
0083 rzg2l_wdt_write(priv, WDTINT_INTDISP, WDTINT);
0084
0085 time_out = (wdev->timeout * (MICRO / 2)) /
0086 rzg2l_wdt_get_cycle_usec(priv->osc_clk_rate, 0);
0087 rzg2l_wdt_write(priv, WDTSET_COUNTER_VAL(time_out), WDTSET);
0088 }
0089
0090 static int rzg2l_wdt_start(struct watchdog_device *wdev)
0091 {
0092 struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
0093
0094 pm_runtime_get_sync(wdev->parent);
0095
0096
0097 rzg2l_wdt_init_timeout(wdev);
0098
0099
0100 rzg2l_wdt_write(priv, 0, WDTTIM);
0101
0102
0103 rzg2l_wdt_write(priv, WDTCNT_WDTEN, WDTCNT);
0104
0105 return 0;
0106 }
0107
0108 static int rzg2l_wdt_stop(struct watchdog_device *wdev)
0109 {
0110 struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
0111
0112 pm_runtime_put(wdev->parent);
0113 reset_control_reset(priv->rstc);
0114
0115 return 0;
0116 }
0117
0118 static int rzg2l_wdt_set_timeout(struct watchdog_device *wdev, unsigned int timeout)
0119 {
0120 struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
0121
0122 wdev->timeout = timeout;
0123
0124
0125
0126
0127
0128 if (watchdog_active(wdev)) {
0129 pm_runtime_put(wdev->parent);
0130 reset_control_reset(priv->rstc);
0131 rzg2l_wdt_start(wdev);
0132 }
0133
0134 return 0;
0135 }
0136
0137 static int rzg2l_wdt_restart(struct watchdog_device *wdev,
0138 unsigned long action, void *data)
0139 {
0140 struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
0141
0142 clk_prepare_enable(priv->pclk);
0143 clk_prepare_enable(priv->osc_clk);
0144
0145
0146 rzg2l_wdt_write(priv, 0, PECR);
0147
0148
0149 rzg2l_wdt_write(priv, PEEN_FORCE, PEEN);
0150
0151 return 0;
0152 }
0153
0154 static const struct watchdog_info rzg2l_wdt_ident = {
0155 .options = WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
0156 .identity = "Renesas RZ/G2L WDT Watchdog",
0157 };
0158
0159 static int rzg2l_wdt_ping(struct watchdog_device *wdev)
0160 {
0161 struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
0162
0163 rzg2l_wdt_write(priv, WDTINT_INTDISP, WDTINT);
0164
0165 return 0;
0166 }
0167
0168 static const struct watchdog_ops rzg2l_wdt_ops = {
0169 .owner = THIS_MODULE,
0170 .start = rzg2l_wdt_start,
0171 .stop = rzg2l_wdt_stop,
0172 .ping = rzg2l_wdt_ping,
0173 .set_timeout = rzg2l_wdt_set_timeout,
0174 .restart = rzg2l_wdt_restart,
0175 };
0176
0177 static void rzg2l_wdt_reset_assert_pm_disable(void *data)
0178 {
0179 struct watchdog_device *wdev = data;
0180 struct rzg2l_wdt_priv *priv = watchdog_get_drvdata(wdev);
0181
0182 pm_runtime_disable(wdev->parent);
0183 reset_control_assert(priv->rstc);
0184 }
0185
0186 static int rzg2l_wdt_probe(struct platform_device *pdev)
0187 {
0188 struct device *dev = &pdev->dev;
0189 struct rzg2l_wdt_priv *priv;
0190 unsigned long pclk_rate;
0191 int ret;
0192
0193 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0194 if (!priv)
0195 return -ENOMEM;
0196
0197 priv->base = devm_platform_ioremap_resource(pdev, 0);
0198 if (IS_ERR(priv->base))
0199 return PTR_ERR(priv->base);
0200
0201
0202 priv->osc_clk = devm_clk_get(&pdev->dev, "oscclk");
0203 if (IS_ERR(priv->osc_clk))
0204 return dev_err_probe(&pdev->dev, PTR_ERR(priv->osc_clk), "no oscclk");
0205
0206 priv->osc_clk_rate = clk_get_rate(priv->osc_clk);
0207 if (!priv->osc_clk_rate)
0208 return dev_err_probe(&pdev->dev, -EINVAL, "oscclk rate is 0");
0209
0210
0211 priv->pclk = devm_clk_get(&pdev->dev, "pclk");
0212 if (IS_ERR(priv->pclk))
0213 return dev_err_probe(&pdev->dev, PTR_ERR(priv->pclk), "no pclk");
0214
0215 pclk_rate = clk_get_rate(priv->pclk);
0216 if (!pclk_rate)
0217 return dev_err_probe(&pdev->dev, -EINVAL, "pclk rate is 0");
0218
0219 priv->delay = F2CYCLE_NSEC(priv->osc_clk_rate) * 6 + F2CYCLE_NSEC(pclk_rate) * 9;
0220
0221 priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
0222 if (IS_ERR(priv->rstc))
0223 return dev_err_probe(&pdev->dev, PTR_ERR(priv->rstc),
0224 "failed to get cpg reset");
0225
0226 ret = reset_control_deassert(priv->rstc);
0227 if (ret)
0228 return dev_err_probe(dev, ret, "failed to deassert");
0229
0230 pm_runtime_enable(&pdev->dev);
0231
0232 priv->wdev.info = &rzg2l_wdt_ident;
0233 priv->wdev.ops = &rzg2l_wdt_ops;
0234 priv->wdev.parent = dev;
0235 priv->wdev.min_timeout = 1;
0236 priv->wdev.max_timeout = rzg2l_wdt_get_cycle_usec(priv->osc_clk_rate, 0xfff) /
0237 USEC_PER_SEC;
0238 priv->wdev.timeout = WDT_DEFAULT_TIMEOUT;
0239
0240 watchdog_set_drvdata(&priv->wdev, priv);
0241 ret = devm_add_action_or_reset(&pdev->dev,
0242 rzg2l_wdt_reset_assert_pm_disable,
0243 &priv->wdev);
0244 if (ret < 0)
0245 return ret;
0246
0247 watchdog_set_nowayout(&priv->wdev, nowayout);
0248 watchdog_stop_on_unregister(&priv->wdev);
0249
0250 ret = watchdog_init_timeout(&priv->wdev, 0, dev);
0251 if (ret)
0252 dev_warn(dev, "Specified timeout invalid, using default");
0253
0254 return devm_watchdog_register_device(&pdev->dev, &priv->wdev);
0255 }
0256
0257 static const struct of_device_id rzg2l_wdt_ids[] = {
0258 { .compatible = "renesas,rzg2l-wdt", },
0259 { }
0260 };
0261 MODULE_DEVICE_TABLE(of, rzg2l_wdt_ids);
0262
0263 static struct platform_driver rzg2l_wdt_driver = {
0264 .driver = {
0265 .name = "rzg2l_wdt",
0266 .of_match_table = rzg2l_wdt_ids,
0267 },
0268 .probe = rzg2l_wdt_probe,
0269 };
0270 module_platform_driver(rzg2l_wdt_driver);
0271
0272 MODULE_DESCRIPTION("Renesas RZ/G2L WDT Watchdog Driver");
0273 MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
0274 MODULE_LICENSE("GPL v2");