diff options
Diffstat (limited to 'drivers/watchdog/s3c2410_wdt.c')
-rw-r--r-- | drivers/watchdog/s3c2410_wdt.c | 73 |
1 files changed, 35 insertions, 38 deletions
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 59e95762a6de..6ed97596ca80 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -23,8 +23,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/types.h> @@ -46,6 +44,7 @@ #define S3C2410_WTCON 0x00 #define S3C2410_WTDAT 0x04 #define S3C2410_WTCNT 0x08 +#define S3C2410_WTCLRINT 0x0c #define S3C2410_WTCNT_MAXCNT 0xffff @@ -64,14 +63,15 @@ #define S3C2410_WTCON_PRESCALE_MASK (0xff << 8) #define S3C2410_WTCON_PRESCALE_MAX 0xff -#define CONFIG_S3C2410_WATCHDOG_ATBOOT (0) -#define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15) +#define S3C2410_WATCHDOG_ATBOOT (0) +#define S3C2410_WATCHDOG_DEFAULT_TIME (15) #define EXYNOS5_RST_STAT_REG_OFFSET 0x0404 #define EXYNOS5_WDT_DISABLE_REG_OFFSET 0x0408 #define EXYNOS5_WDT_MASK_RESET_REG_OFFSET 0x040c #define QUIRK_HAS_PMU_CONFIG (1 << 0) #define QUIRK_HAS_RST_STAT (1 << 1) +#define QUIRK_HAS_WTCLRINT_REG (1 << 2) /* These quirks require that we have a PMU register map */ #define QUIRKS_HAVE_PMUREG (QUIRK_HAS_PMU_CONFIG | \ @@ -79,26 +79,23 @@ static bool nowayout = WATCHDOG_NOWAYOUT; static int tmr_margin; -static int tmr_atboot = CONFIG_S3C2410_WATCHDOG_ATBOOT; +static int tmr_atboot = S3C2410_WATCHDOG_ATBOOT; static int soft_noboot; -static int debug; module_param(tmr_margin, int, 0); module_param(tmr_atboot, int, 0); module_param(nowayout, bool, 0); module_param(soft_noboot, int, 0); -module_param(debug, int, 0); MODULE_PARM_DESC(tmr_margin, "Watchdog tmr_margin in seconds. (default=" - __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME) ")"); + __MODULE_STRING(S3C2410_WATCHDOG_DEFAULT_TIME) ")"); MODULE_PARM_DESC(tmr_atboot, "Watchdog is started at boot time if set to 1, default=" - __MODULE_STRING(CONFIG_S3C2410_WATCHDOG_ATBOOT)); + __MODULE_STRING(S3C2410_WATCHDOG_ATBOOT)); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, " "0 to reboot (default 0)"); -MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug (default 0)"); /** * struct s3c2410_wdt_variant - Per-variant config data @@ -143,13 +140,18 @@ static const struct s3c2410_wdt_variant drv_data_s3c2410 = { }; #ifdef CONFIG_OF +static const struct s3c2410_wdt_variant drv_data_s3c6410 = { + .quirks = QUIRK_HAS_WTCLRINT_REG, +}; + static const struct s3c2410_wdt_variant drv_data_exynos5250 = { .disable_reg = EXYNOS5_WDT_DISABLE_REG_OFFSET, .mask_reset_reg = EXYNOS5_WDT_MASK_RESET_REG_OFFSET, .mask_bit = 20, .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, .rst_stat_bit = 20, - .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, + .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ + | QUIRK_HAS_WTCLRINT_REG, }; static const struct s3c2410_wdt_variant drv_data_exynos5420 = { @@ -158,7 +160,8 @@ static const struct s3c2410_wdt_variant drv_data_exynos5420 = { .mask_bit = 0, .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, .rst_stat_bit = 9, - .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, + .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ + | QUIRK_HAS_WTCLRINT_REG, }; static const struct s3c2410_wdt_variant drv_data_exynos7 = { @@ -167,12 +170,15 @@ static const struct s3c2410_wdt_variant drv_data_exynos7 = { .mask_bit = 23, .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, .rst_stat_bit = 23, /* A57 WDTRESET */ - .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT, + .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ + | QUIRK_HAS_WTCLRINT_REG, }; static const struct of_device_id s3c2410_wdt_match[] = { { .compatible = "samsung,s3c2410-wdt", .data = &drv_data_s3c2410 }, + { .compatible = "samsung,s3c6410-wdt", + .data = &drv_data_s3c6410 }, { .compatible = "samsung,exynos5250-wdt", .data = &drv_data_exynos5250 }, { .compatible = "samsung,exynos5420-wdt", @@ -193,14 +199,6 @@ static const struct platform_device_id s3c2410_wdt_ids[] = { }; MODULE_DEVICE_TABLE(platform, s3c2410_wdt_ids); -/* watchdog control routines */ - -#define DBG(fmt, ...) \ -do { \ - if (debug) \ - pr_info(fmt, ##__VA_ARGS__); \ -} while (0) - /* functions */ static inline unsigned int s3c2410wdt_max_timeout(struct clk *clock) @@ -296,8 +294,8 @@ static int s3c2410wdt_start(struct watchdog_device *wdd) wtcon |= S3C2410_WTCON_RSTEN; } - DBG("%s: count=0x%08x, wtcon=%08lx\n", - __func__, wdt->count, wtcon); + dev_dbg(wdt->dev, "Starting watchdog: count=0x%08x, wtcon=%08lx\n", + wdt->count, wtcon); writel(wdt->count, wdt->reg_base + S3C2410_WTDAT); writel(wdt->count, wdt->reg_base + S3C2410_WTCNT); @@ -326,8 +324,8 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeou freq = DIV_ROUND_UP(freq, 128); count = timeout * freq; - DBG("%s: count=%d, timeout=%d, freq=%lu\n", - __func__, count, timeout, freq); + dev_dbg(wdt->dev, "Heartbeat: count=%d, timeout=%d, freq=%lu\n", + count, timeout, freq); /* if the count is bigger than the watchdog register, then work out what we need to do (and if) we can @@ -343,8 +341,8 @@ static int s3c2410wdt_set_heartbeat(struct watchdog_device *wdd, unsigned timeou } } - DBG("%s: timeout=%d, divisor=%d, count=%d (%08x)\n", - __func__, timeout, divisor, count, DIV_ROUND_UP(count, divisor)); + dev_dbg(wdt->dev, "Heartbeat: timeout=%d, divisor=%d, count=%d (%08x)\n", + timeout, divisor, count, DIV_ROUND_UP(count, divisor)); count = DIV_ROUND_UP(count, divisor); wdt->count = count; @@ -394,7 +392,7 @@ static const struct watchdog_info s3c2410_wdt_ident = { .identity = "S3C2410 Watchdog", }; -static struct watchdog_ops s3c2410wdt_ops = { +static const struct watchdog_ops s3c2410wdt_ops = { .owner = THIS_MODULE, .start = s3c2410wdt_start, .stop = s3c2410wdt_stop, @@ -406,7 +404,7 @@ static struct watchdog_ops s3c2410wdt_ops = { static struct watchdog_device s3c2410_wdd = { .info = &s3c2410_wdt_ident, .ops = &s3c2410wdt_ops, - .timeout = CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME, + .timeout = S3C2410_WATCHDOG_DEFAULT_TIME, }; /* interrupt handler code */ @@ -418,6 +416,10 @@ static irqreturn_t s3c2410wdt_irq(int irqno, void *param) dev_info(wdt->dev, "watchdog timer expired (irq)\n"); s3c2410wdt_keepalive(&wdt->wdt_device); + + if (wdt->drv_data->quirks & QUIRK_HAS_WTCLRINT_REG) + writel(0x1, wdt->reg_base + S3C2410_WTCLRINT); + return IRQ_HANDLED; } @@ -505,9 +507,8 @@ static inline unsigned int s3c2410wdt_get_bootstatus(struct s3c2410_wdt *wdt) return 0; } -/* s3c2410_get_wdt_driver_data */ static inline struct s3c2410_wdt_variant * -get_wdt_drv_data(struct platform_device *pdev) +s3c2410_get_wdt_drv_data(struct platform_device *pdev) { if (pdev->dev.of_node) { const struct of_device_id *match; @@ -529,8 +530,6 @@ static int s3c2410wdt_probe(struct platform_device *pdev) int started = 0; int ret; - DBG("%s: probe=%p\n", __func__, pdev); - dev = &pdev->dev; wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); @@ -541,7 +540,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev) spin_lock_init(&wdt->lock); wdt->wdt_device = s3c2410_wdd; - wdt->drv_data = get_wdt_drv_data(pdev); + wdt->drv_data = s3c2410_get_wdt_drv_data(pdev); if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) { wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, "samsung,syscon-phandle"); @@ -566,8 +565,6 @@ static int s3c2410wdt_probe(struct platform_device *pdev) goto err; } - DBG("probe: mapped reg_base=%p\n", wdt->reg_base); - wdt->clock = devm_clk_get(dev, "watchdog"); if (IS_ERR(wdt->clock)) { dev_err(dev, "failed to find watchdog clock source\n"); @@ -600,12 +597,12 @@ static int s3c2410wdt_probe(struct platform_device *pdev) wdt->wdt_device.timeout); if (ret) { started = s3c2410wdt_set_heartbeat(&wdt->wdt_device, - CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME); + S3C2410_WATCHDOG_DEFAULT_TIME); if (started == 0) dev_info(dev, "tmr_margin value out of range, default %d used\n", - CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME); + S3C2410_WATCHDOG_DEFAULT_TIME); else dev_info(dev, "default timer value is out of range, " "cannot start\n"); |