From patchwork Tue Dec 31 21:22:13 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Mayer X-Patchwork-Id: 22851 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ve0-f199.google.com (mail-ve0-f199.google.com [209.85.128.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 689B8218C0 for ; Tue, 31 Dec 2013 21:34:51 +0000 (UTC) Received: by mail-ve0-f199.google.com with SMTP id c14sf16573327vea.2 for ; Tue, 31 Dec 2013 13:34:50 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe:content-type; bh=HkVGwJPBbNCIM0ja/ZBVgMePma/hfVhyug2q59Ajr9I=; b=U087fiTIJ4jLduju85SMz9sOJCRB60foOT4Ne9wOTEdRxmANFnoIVf97jaFpJcA6EE 7sOhtnNX0VHLYTFkKb2WIOuRcJeXvBnJXldvbWJbIlWKQLwvBhGk0ViFBRRw1b+eACzH rlJJhNxyuvmpwGmtNvBxGuen0Am+V8duWLW5vGkTDOSQ6iKwf2X2HDxiPYj/1RgU1cFw DJPjAPXxROy0AQrMQhaZAXHYdtf4DCkVOZYHX9f/rgXX3V2/QlLmw+2oxj5aJZlc1Y+I zyGCNX01e8bYZm5cblRk2aG+nm5bCmuJpcEnjbJrC0QALAPY2skHV6RSr6QFjuX+EElS ZiVg== X-Gm-Message-State: ALoCoQm3pk0OswWWceA4pVWPfTbFYzO3hHNZJOlCXx9z87czIvQxEgsgiS7IL1IdmBdfAl29c8Wv X-Received: by 10.58.171.135 with SMTP id au7mr31190823vec.22.1388525690243; Tue, 31 Dec 2013 13:34:50 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.17.163 with SMTP id p3ls4116618qed.41.gmail; Tue, 31 Dec 2013 13:34:50 -0800 (PST) X-Received: by 10.58.67.9 with SMTP id j9mr42250115vet.3.1388525690113; Tue, 31 Dec 2013 13:34:50 -0800 (PST) Received: from mail-vc0-f182.google.com (mail-vc0-f182.google.com [209.85.220.182]) by mx.google.com with ESMTPS id a6si4152552vdp.1.2013.12.31.13.34.50 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 31 Dec 2013 13:34:50 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.182 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.182; Received: by mail-vc0-f182.google.com with SMTP id lc6so6699448vcb.27 for ; Tue, 31 Dec 2013 13:34:50 -0800 (PST) X-Received: by 10.220.116.197 with SMTP id n5mr1964653vcq.42.1388525690003; Tue, 31 Dec 2013 13:34:50 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.59.13.131 with SMTP id ey3csp690377ved; Tue, 31 Dec 2013 13:34:49 -0800 (PST) X-Received: by 10.68.189.165 with SMTP id gj5mr77589076pbc.111.1388525688689; Tue, 31 Dec 2013 13:34:48 -0800 (PST) Received: from mail-gw4-out.broadcom.com (mail-gw4-out.broadcom.com. [216.31.217.44]) by mx.google.com with ESMTP id yd9si37767057pab.234.2013.12.31.13.34.47 for ; Tue, 31 Dec 2013 13:34:48 -0800 (PST) Received-SPF: neutral (google.com: 216.31.217.44 is neither permitted nor denied by best guess record for domain of markus.mayer@linaro.org) client-ip=216.31.217.44; X-IronPort-AV: E=Sophos;i="4.95,582,1384329600"; d="scan'208";a="278660" Received: from unknown (HELO IRVEXCHCAS06.corp.ad.broadcom.com) ([10.9.208.53]) by mail-gw4-out.broadcom.com with ESMTP; 31 Dec 2013 13:45:33 -0800 Received: from IRVEXCHSMTP2.corp.ad.broadcom.com (10.9.207.52) by IRVEXCHCAS06.corp.ad.broadcom.com (10.9.208.53) with Microsoft SMTP Server (TLS) id 14.1.438.0; Tue, 31 Dec 2013 13:24:46 -0800 Received: from mail-irva-13.broadcom.com (10.10.10.20) by IRVEXCHSMTP2.corp.ad.broadcom.com (10.9.207.52) with Microsoft SMTP Server id 14.1.438.0; Tue, 31 Dec 2013 13:24:46 -0800 Received: from mail.broadcom.com (lbrmn-lnxub70.ric.broadcom.com [10.136.8.215]) by mail-irva-13.broadcom.com (Postfix) with ESMTP id C75E5246A5; Tue, 31 Dec 2013 13:24:45 -0800 (PST) From: Markus Mayer To: Wim Van Sebroeck , Guenter Roeck , Christian Daudt CC: Linaro Patches , Linux Watchdog List , Linux Kernel Mailing List , Markus Mayer Subject: [PATCH 1/2] watchdog: bcm281xx: Debugfs support Date: Tue, 31 Dec 2013 13:22:13 -0800 Message-ID: <1388524934-10563-2-git-send-email-markus.mayer@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1388524934-10563-1-git-send-email-markus.mayer@linaro.org> References: <1388524934-10563-1-git-send-email-markus.mayer@linaro.org> MIME-Version: 1.0 X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: markus.mayer@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.182 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This change introduces debugfs support for the BCM281xx watchdog driver. Signed-off-by: Markus Mayer --- drivers/watchdog/Kconfig | 10 ++++ drivers/watchdog/bcm_kona_wdt.c | 116 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 122 insertions(+), 4 deletions(-) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 10d188a..9b8b96d 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1152,6 +1152,16 @@ config BCM_KONA_WDT Say 'Y' or 'M' here to enable the driver. The module will be called bcm_kona_wdt. +config BCM_KONA_WDT_DEBUG + bool "DEBUGFS support for BCM Kona Watchdog" + depends on BCM_KONA_WDT + help + If enabled, adds /sys/kernel/debug/bcm-kona-wdt/info which provides + access to the driver's internal data structures as well as watchdog + timer hardware registres. + + If in doubt, say 'N'. + config LANTIQ_WDT tristate "Lantiq SoC watchdog" depends on LANTIQ diff --git a/drivers/watchdog/bcm_kona_wdt.c b/drivers/watchdog/bcm_kona_wdt.c index 7e41a83..d3aa473 100644 --- a/drivers/watchdog/bcm_kona_wdt.c +++ b/drivers/watchdog/bcm_kona_wdt.c @@ -11,6 +11,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -55,9 +56,13 @@ struct bcm_kona_wdt { */ int resolution; spinlock_t lock; +#ifdef CONFIG_BCM_KONA_WDT_DEBUG + unsigned long busy_count; + struct dentry *debugfs; +#endif }; -static int secure_register_read(void __iomem *addr) +static int secure_register_read(struct bcm_kona_wdt *wdt, uint32_t offset) { uint32_t val; unsigned count = 0; @@ -70,10 +75,16 @@ static int secure_register_read(void __iomem *addr) do { if (unlikely(count > 1)) udelay(5); - val = readl_relaxed(addr); + val = readl_relaxed(wdt->base + offset); count++; } while ((val & SECWDOG_WD_LOAD_FLAG) && count < SECWDOG_MAX_TRY); +#ifdef CONFIG_BCM_KONA_WDT_DEBUG + /* Remember the maximum number iterations due to WD_LOAD_FLAG */ + if (count > wdt->busy_count) + wdt->busy_count = count; +#endif + /* This is the only place we return a negative value. */ if (val & SECWDOG_WD_LOAD_FLAG) return -ETIMEDOUT; @@ -84,6 +95,80 @@ static int secure_register_read(void __iomem *addr) return val; } +#ifdef CONFIG_BCM_KONA_WDT_DEBUG + +static int bcm_kona_wdt_dbg_show(struct seq_file *s, void *data) +{ + int ctl_val, cur_val, ret; + unsigned long flags; + struct bcm_kona_wdt *wdt = s->private; + + if (!wdt) + return seq_puts(s, "No device pointer\n"); + + spin_lock_irqsave(&wdt->lock, flags); + ctl_val = secure_register_read(wdt, SECWDOG_CTRL_REG); + cur_val = secure_register_read(wdt, SECWDOG_COUNT_REG); + spin_unlock_irqrestore(&wdt->lock, flags); + + if (ctl_val < 0 || cur_val < 0) { + ret = seq_puts(s, "Error accessing hardware\n"); + } else { + int ctl, cur, ctl_sec, cur_sec, res; + + ctl = ctl_val & SECWDOG_COUNT_MASK; + res = (ctl_val & SECWDOG_RES_MASK) >> SECWDOG_CLKS_SHIFT; + cur = cur_val & SECWDOG_COUNT_MASK; + ctl_sec = TICKS_TO_SECS(ctl, wdt); + cur_sec = TICKS_TO_SECS(cur, wdt); + ret = seq_printf(s, "Resolution: %d / %d\n" + "Control: %d s / %d (%#x) ticks\n" + "Current: %d s / %d (%#x) ticks\n" + "Busy count: %lu\n", res, + wdt->resolution, ctl_sec, ctl, ctl, cur_sec, + cur, cur, wdt->busy_count); + } + + return ret; +} + +static int bcm_kona_dbg_open(struct inode *inode, struct file *file) +{ + return single_open(file, bcm_kona_wdt_dbg_show, inode->i_private); +} + +static const struct file_operations bcm_kona_dbg_operations = { + .open = bcm_kona_dbg_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static struct dentry *bcm_kona_wdt_debugfs_init(struct bcm_kona_wdt *wdt, + struct watchdog_device *wdd) +{ + struct dentry *dir; + + dir = debugfs_create_dir(BCM_KONA_WDT_NAME, NULL); + if (IS_ERR_OR_NULL(dir)) + return NULL; + + if (debugfs_create_file("info", S_IFREG | S_IRUGO, dir, wdt, + &bcm_kona_dbg_operations)) + return dir; + + /* Clean up */ + debugfs_remove_recursive(dir); + return NULL; +} + +static void bcm_kona_debugfs_exit(struct dentry *dir) +{ + debugfs_remove_recursive(dir); +} + +#endif /* CONFIG_BCM_KONA_WDT_DEBUG */ + static int bcm_kona_wdt_ctrl_reg_modify(struct bcm_kona_wdt *wdt, unsigned mask, unsigned newval) { @@ -93,7 +178,7 @@ static int bcm_kona_wdt_ctrl_reg_modify(struct bcm_kona_wdt *wdt, spin_lock_irqsave(&wdt->lock, flags); - val = secure_register_read(wdt->base + SECWDOG_CTRL_REG); + val = secure_register_read(wdt, SECWDOG_CTRL_REG); if (val < 0) { ret = val; } else { @@ -140,7 +225,7 @@ static unsigned int bcm_kona_wdt_get_timeleft(struct watchdog_device *wdog) unsigned long flags; spin_lock_irqsave(&wdt->lock, flags); - val = secure_register_read(wdt->base + SECWDOG_COUNT_REG); + val = secure_register_read(wdt, SECWDOG_COUNT_REG); spin_unlock_irqrestore(&wdt->lock, flags); if (val < 0) @@ -190,6 +275,27 @@ static void bcm_kona_wdt_shutdown(struct platform_device *pdev) bcm_kona_wdt_stop(&bcm_kona_wdt_wdd); } +#ifdef CONFIG_BCM_KONA_WDT_DEBUG +static void bcm_kona_wdt_debug_init(struct platform_device *pdev) +{ + struct bcm_kona_wdt *wdt = platform_get_drvdata(pdev); + + wdt->debugfs = bcm_kona_wdt_debugfs_init(wdt, &bcm_kona_wdt_wdd); +} + +static void bcm_kona_wdt_debug_exit(struct platform_device *pdev) +{ + struct bcm_kona_wdt *wdt = platform_get_drvdata(pdev); + + if (wdt->debugfs) + bcm_kona_debugfs_exit(wdt->debugfs); +} + +#else +static void bcm_kona_wdt_debug_init(struct platform_device *pdev) {} +static void bcm_kona_wdt_debug_exit(struct platform_device *pdev) {} +#endif + static int bcm_kona_wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -229,6 +335,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev) return ret; } + bcm_kona_wdt_debug_init(pdev); dev_dbg(dev, "Broadcom Kona Watchdog Timer"); return 0; @@ -236,6 +343,7 @@ static int bcm_kona_wdt_probe(struct platform_device *pdev) static int bcm_kona_wdt_remove(struct platform_device *pdev) { + bcm_kona_wdt_debug_exit(pdev); bcm_kona_wdt_shutdown(pdev); watchdog_unregister_device(&bcm_kona_wdt_wdd); dev_dbg(&pdev->dev, "Watchdog driver disabled");