diff options
author | Jonas Aaberg <jonas.aberg@stericsson.com> | 2011-09-21 09:30:42 +0200 |
---|---|---|
committer | Jonas ABERG <jonas.aberg@stericsson.com> | 2011-09-29 08:57:30 +0200 |
commit | ea4fb36bddd96459395159a808a908fc2f59d595 (patch) | |
tree | f9f9217f98b6688b68bade43d8b03eda676f2847 /drivers/watchdog | |
parent | 1fbc2d19aa6e6dc1ed45775e39cabb82745057b2 (diff) |
drivers: watchdog: u8500: Add debugfs interface
Change-Id: I0c2da769eea8ff3d89ded8253482d805d4913f00
Signed-off-by: Jonas Aaberg <jonas.aberg@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32089
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/Kconfig | 6 | ||||
-rw-r--r-- | drivers/watchdog/u8500_wdt.c | 168 |
2 files changed, 174 insertions, 0 deletions
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 445b559a2ee..9831700e25b 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -341,6 +341,12 @@ config U8500_WATCHDOG This watchdog is used to reset the system and thus cannot be compiled as a module. +config U8500_WATCHDOG_DEBUG + bool "ST-Ericsson U8500 watchdog DEBUG" + depends on UX500_SOC_DB8500 && DEBUG_FS + help + Say Y here to add various debugfs entries in wdog/ + # AVR32 Architecture config AT32AP700X_WDT diff --git a/drivers/watchdog/u8500_wdt.c b/drivers/watchdog/u8500_wdt.c index 6433e798916..3ac23ab05f3 100644 --- a/drivers/watchdog/u8500_wdt.c +++ b/drivers/watchdog/u8500_wdt.c @@ -186,6 +186,167 @@ static struct miscdevice u8500_wdt_miscdev = { .fops = &u8500_wdt_fops, }; +#ifdef CONFIG_U8500_WATCHDOG_DEBUG + +enum wdog_dbg { + WDOG_DBG_CONFIG, + WDOG_DBG_LOAD, + WDOG_DBG_KICK, + WDOG_DBG_EN, + WDOG_DBG_DIS, +}; + +static ssize_t wdog_dbg_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + unsigned long val; + int err; + enum wdog_dbg v = (enum wdog_dbg)((struct seq_file *) + (file->private_data))->private; + + switch(v) { + case WDOG_DBG_CONFIG: + err = kstrtoul_from_user(user_buf, count, 0, &val); + + if (!err) { + wdt_auto_off = val != 0; + (void) prcmu_config_a9wdog(1, + wdt_auto_off); + } + else { + pr_err("u8500_wdt:dbg: unknown value\n"); + } + break; + case WDOG_DBG_LOAD: + err = kstrtoul_from_user(user_buf, count, 0, &val); + + if (!err) { + timeout = val; + /* Convert seconds to ms */ + prcmu_disable_a9wdog(wdog_id); + prcmu_load_a9wdog(wdog_id, timeout * 1000); + prcmu_enable_a9wdog(wdog_id); + } + else { + pr_err("u8500_wdt:dbg: unknown value\n"); + } + break; + case WDOG_DBG_KICK: + (void) prcmu_kick_a9wdog(wdog_id); + break; + case WDOG_DBG_EN: + wdt_en = true; + (void) prcmu_enable_a9wdog(wdog_id); + break; + case WDOG_DBG_DIS: + wdt_en = false; + (void) prcmu_disable_a9wdog(wdog_id); + break; + } + + return count; +} + +static int wdog_dbg_read(struct seq_file *s, void *p) +{ + enum wdog_dbg v = (enum wdog_dbg)s->private; + + switch(v) { + case WDOG_DBG_CONFIG: + seq_printf(s,"wdog is on id %d, auto off on sleep: %s\n", + (int)wdog_id, + wdt_auto_off ? "enabled": "disabled"); + break; + case WDOG_DBG_LOAD: + /* In 1s */ + seq_printf(s, "wdog load is: %d s\n", + timeout); + break; + case WDOG_DBG_KICK: + break; + case WDOG_DBG_EN: + case WDOG_DBG_DIS: + seq_printf(s, "wdog is %sabled\n", + wdt_en ? "en" : "dis"); + break; + } + return 0; +} + +static int wdog_dbg_open(struct inode *inode, + struct file *file) +{ + return single_open(file, wdog_dbg_read, inode->i_private); +} + +static const struct file_operations wdog_dbg_fops = { + .open = wdog_dbg_open, + .write = wdog_dbg_write, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int __init wdog_dbg_init(void) +{ + struct dentry *wdog_dir; + + wdog_dir = debugfs_create_dir("wdog", NULL); + if (IS_ERR_OR_NULL(wdog_dir)) + goto fail; + + if (IS_ERR_OR_NULL(debugfs_create_u8("id", + S_IWUGO | S_IRUGO, wdog_dir, + &wdog_id))) + goto fail; + + if (IS_ERR_OR_NULL(debugfs_create_file("config", + S_IWUGO | S_IRUGO, wdog_dir, + (void *)WDOG_DBG_CONFIG, + &wdog_dbg_fops))) + goto fail; + + if (IS_ERR_OR_NULL(debugfs_create_file("load", + S_IWUGO | S_IRUGO, wdog_dir, + (void *)WDOG_DBG_LOAD, + &wdog_dbg_fops))) + goto fail; + + if (IS_ERR_OR_NULL(debugfs_create_file("kick", + S_IWUGO, wdog_dir, + (void *)WDOG_DBG_KICK, + &wdog_dbg_fops))) + goto fail; + + if (IS_ERR_OR_NULL(debugfs_create_file("enable", + S_IWUGO | S_IRUGO, wdog_dir, + (void *)WDOG_DBG_EN, + &wdog_dbg_fops))) + goto fail; + + if (IS_ERR_OR_NULL(debugfs_create_file("disable", + S_IWUGO | S_IRUGO, wdog_dir, + (void *)WDOG_DBG_DIS, + &wdog_dbg_fops))) + goto fail; + + return 0; +fail: + pr_err("u8500:wdog: Failed to initialize wdog dbg\n"); + debugfs_remove_recursive(wdog_dir); + + return -EFAULT; +} + +#else +static inline int __init wdog_dbg_init(void) +{ + return 0; +} +#endif + static int __init u8500_wdt_probe(struct platform_device *pdev) { int ret; @@ -201,9 +362,16 @@ static int __init u8500_wdt_probe(struct platform_device *pdev) return ret; } + ret = wdog_dbg_init(); + if (ret < 0) + goto fail; + dev_info(&pdev->dev, "initialized\n"); return 0; +fail: + misc_deregister(&u8500_wdt_miscdev); + return ret; } static int __exit u8500_wdt_remove(struct platform_device *dev) |