Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Watchdog timer for PowerPC Book-E systems
0004  *
0005  * Author: Matthew McClintock
0006  * Maintainer: Kumar Gala <galak@kernel.crashing.org>
0007  *
0008  * Copyright 2005, 2008, 2010-2011 Freescale Semiconductor Inc.
0009  */
0010 
0011 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0012 
0013 #include <linux/module.h>
0014 #include <linux/smp.h>
0015 #include <linux/watchdog.h>
0016 
0017 #include <asm/reg_booke.h>
0018 #include <asm/time.h>
0019 #include <asm/div64.h>
0020 
0021 /* If the kernel parameter wdt=1, the watchdog will be enabled at boot.
0022  * Also, the wdt_period sets the watchdog timer period timeout.
0023  * For E500 cpus the wdt_period sets which bit changing from 0->1 will
0024  * trigger a watchdog timeout. This watchdog timeout will occur 3 times, the
0025  * first time nothing will happen, the second time a watchdog exception will
0026  * occur, and the final time the board will reset.
0027  */
0028 
0029 
0030 #ifdef  CONFIG_PPC_FSL_BOOK3E
0031 #define WDTP(x)     ((((x)&0x3)<<30)|(((x)&0x3c)<<15))
0032 #define WDTP_MASK   (WDTP(0x3f))
0033 #else
0034 #define WDTP(x)     (TCR_WP(x))
0035 #define WDTP_MASK   (TCR_WP_MASK)
0036 #endif
0037 
0038 static bool booke_wdt_enabled;
0039 module_param(booke_wdt_enabled, bool, 0);
0040 static int  booke_wdt_period = CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT;
0041 module_param(booke_wdt_period, int, 0);
0042 static bool nowayout = WATCHDOG_NOWAYOUT;
0043 module_param(nowayout, bool, 0);
0044 MODULE_PARM_DESC(nowayout,
0045         "Watchdog cannot be stopped once started (default="
0046                 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
0047 
0048 #ifdef CONFIG_PPC_FSL_BOOK3E
0049 
0050 /* For the specified period, determine the number of seconds
0051  * corresponding to the reset time.  There will be a watchdog
0052  * exception at approximately 3/5 of this time.
0053  *
0054  * The formula to calculate this is given by:
0055  * 2.5 * (2^(63-period+1)) / timebase_freq
0056  *
0057  * In order to simplify things, we assume that period is
0058  * at least 1.  This will still result in a very long timeout.
0059  */
0060 static unsigned long long period_to_sec(unsigned int period)
0061 {
0062     unsigned long long tmp = 1ULL << (64 - period);
0063     unsigned long tmp2 = ppc_tb_freq;
0064 
0065     /* tmp may be a very large number and we don't want to overflow,
0066      * so divide the timebase freq instead of multiplying tmp
0067      */
0068     tmp2 = tmp2 / 5 * 2;
0069 
0070     do_div(tmp, tmp2);
0071     return tmp;
0072 }
0073 
0074 /*
0075  * This procedure will find the highest period which will give a timeout
0076  * greater than the one required. e.g. for a bus speed of 66666666 and
0077  * a parameter of 2 secs, then this procedure will return a value of 38.
0078  */
0079 static unsigned int sec_to_period(unsigned int secs)
0080 {
0081     unsigned int period;
0082     for (period = 63; period > 0; period--) {
0083         if (period_to_sec(period) >= secs)
0084             return period;
0085     }
0086     return 0;
0087 }
0088 
0089 #define MAX_WDT_TIMEOUT     period_to_sec(1)
0090 
0091 #else /* CONFIG_PPC_FSL_BOOK3E */
0092 
0093 static unsigned long long period_to_sec(unsigned int period)
0094 {
0095     return period;
0096 }
0097 
0098 static unsigned int sec_to_period(unsigned int secs)
0099 {
0100     return secs;
0101 }
0102 
0103 #define MAX_WDT_TIMEOUT     3   /* from Kconfig */
0104 
0105 #endif /* !CONFIG_PPC_FSL_BOOK3E */
0106 
0107 static void __booke_wdt_set(void *data)
0108 {
0109     u32 val;
0110     struct watchdog_device *wdog = data;
0111 
0112     val = mfspr(SPRN_TCR);
0113     val &= ~WDTP_MASK;
0114     val |= WDTP(sec_to_period(wdog->timeout));
0115 
0116     mtspr(SPRN_TCR, val);
0117 }
0118 
0119 static void booke_wdt_set(void *data)
0120 {
0121     on_each_cpu(__booke_wdt_set, data, 0);
0122 }
0123 
0124 static void __booke_wdt_ping(void *data)
0125 {
0126     mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);
0127 }
0128 
0129 static int booke_wdt_ping(struct watchdog_device *wdog)
0130 {
0131     on_each_cpu(__booke_wdt_ping, NULL, 0);
0132 
0133     return 0;
0134 }
0135 
0136 static void __booke_wdt_enable(void *data)
0137 {
0138     u32 val;
0139     struct watchdog_device *wdog = data;
0140 
0141     /* clear status before enabling watchdog */
0142     __booke_wdt_ping(NULL);
0143     val = mfspr(SPRN_TCR);
0144     val &= ~WDTP_MASK;
0145     val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(sec_to_period(wdog->timeout)));
0146 
0147     mtspr(SPRN_TCR, val);
0148 }
0149 
0150 /**
0151  * __booke_wdt_disable - disable the watchdog on the given CPU
0152  *
0153  * This function is called on each CPU.  It disables the watchdog on that CPU.
0154  *
0155  * TCR[WRC] cannot be changed once it has been set to non-zero, but we can
0156  * effectively disable the watchdog by setting its period to the maximum value.
0157  */
0158 static void __booke_wdt_disable(void *data)
0159 {
0160     u32 val;
0161 
0162     val = mfspr(SPRN_TCR);
0163     val &= ~(TCR_WIE | WDTP_MASK);
0164     mtspr(SPRN_TCR, val);
0165 
0166     /* clear status to make sure nothing is pending */
0167     __booke_wdt_ping(NULL);
0168 
0169 }
0170 
0171 static int booke_wdt_start(struct watchdog_device *wdog)
0172 {
0173     on_each_cpu(__booke_wdt_enable, wdog, 0);
0174     pr_debug("watchdog enabled (timeout = %u sec)\n", wdog->timeout);
0175 
0176     return 0;
0177 }
0178 
0179 static int booke_wdt_stop(struct watchdog_device *wdog)
0180 {
0181     on_each_cpu(__booke_wdt_disable, NULL, 0);
0182     pr_debug("watchdog disabled\n");
0183 
0184     return 0;
0185 }
0186 
0187 static int booke_wdt_set_timeout(struct watchdog_device *wdt_dev,
0188                  unsigned int timeout)
0189 {
0190     wdt_dev->timeout = timeout;
0191     booke_wdt_set(wdt_dev);
0192 
0193     return 0;
0194 }
0195 
0196 static struct watchdog_info booke_wdt_info __ro_after_init = {
0197     .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,
0198     .identity = "PowerPC Book-E Watchdog",
0199 };
0200 
0201 static const struct watchdog_ops booke_wdt_ops = {
0202     .owner = THIS_MODULE,
0203     .start = booke_wdt_start,
0204     .stop = booke_wdt_stop,
0205     .ping = booke_wdt_ping,
0206     .set_timeout = booke_wdt_set_timeout,
0207 };
0208 
0209 static struct watchdog_device booke_wdt_dev = {
0210     .info = &booke_wdt_info,
0211     .ops = &booke_wdt_ops,
0212     .min_timeout = 1,
0213 };
0214 
0215 static void __exit booke_wdt_exit(void)
0216 {
0217     watchdog_unregister_device(&booke_wdt_dev);
0218 }
0219 
0220 static int __init booke_wdt_init(void)
0221 {
0222     int ret = 0;
0223 
0224     pr_info("powerpc book-e watchdog driver loaded\n");
0225     booke_wdt_info.firmware_version = cur_cpu_spec->pvr_value;
0226     booke_wdt_set_timeout(&booke_wdt_dev,
0227                   period_to_sec(booke_wdt_period));
0228     watchdog_set_nowayout(&booke_wdt_dev, nowayout);
0229     booke_wdt_dev.max_timeout = MAX_WDT_TIMEOUT;
0230     if (booke_wdt_enabled)
0231         booke_wdt_start(&booke_wdt_dev);
0232 
0233     ret = watchdog_register_device(&booke_wdt_dev);
0234 
0235     return ret;
0236 }
0237 
0238 module_init(booke_wdt_init);
0239 module_exit(booke_wdt_exit);
0240 
0241 MODULE_ALIAS("booke_wdt");
0242 MODULE_DESCRIPTION("PowerPC Book-E watchdog driver");
0243 MODULE_LICENSE("GPL");