[PATCH v2 1/3] watchdog: qcom: add support for KPSS WDT
From: Josh Cartwright <hidden>
Date: 2014-09-24 18:36:27
Also in:
linux-arm-msm, linux-devicetree, linux-watchdog, lkml
On Wed, Sep 24, 2014 at 08:58:54AM -0700, Guenter Roeck wrote:
On Tue, Sep 23, 2014 at 06:04:36PM -0500, Josh Cartwright wrote:quoted
Add a driver for the watchdog timer block found in the Krait Processor Subsystem (KPSS) on the MSM8960, APQ8064, and IPQ8064. Signed-off-by: Josh Cartwright <redacted>Hi Josh, looks much better. Couple of comments inline.
Thanks for another review! [..]
quoted
+++ b/drivers/watchdog/Kconfig@@ -443,6 +443,19 @@ config TEGRA_WATCHDOG To compile this driver as a module, choose M here: the module will be called tegra_wdt. +config QCOM_WDT + tristate "QCOM watchdog" + depends on HAS_IOMEM + depends on ARCH_QCOM + select WATCHDOG_CORE + help + Say Y here to include Watchdog timer support for the watchdog found + on QCOM chipsets. Currently supported targets are the MSM8960, + APQ8064, and IPQ8064. + + To compile this driver as a module, choose M here: the + module will be called qcom_wdt. + # AVR32 Architecture
[..]
quoted
+static int qcom_wdt_probe(struct platform_device *pdev) +{ + struct qcom_wdt *wdt; + struct resource *res; + unsigned long freq; + int ret; + + wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); + if (!wdt) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + wdt->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(wdt->base)) + return PTR_ERR(wdt->base); + + wdt->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(wdt->clk)) + return PTR_ERR(wdt->clk); + + ret = clk_prepare_enable(wdt->clk); + if (ret) { + dev_err(&pdev->dev, "failed to setup clock\n"); + return ret; + } + + /* + * We use the clock rate to calculate the max timeout, so ensure it's + * not zero to avoid a divide-by-zero exception. + */ + freq = clk_get_rate(wdt->clk); + if (freq == 0) { + dev_err(&pdev->dev, "invalid clock rate\n"); + return -EINVAL; + }This will need clk_disable_unprepare().
Yep. Nice catch. Will fix.
Since you are reading the frequency here, it might make sense to store it in struct qcom_wdt so you don't have to call clk_get_rate() again in the start function.
Yeah, it doesn't save much, but I'll go ahead and add it.
quoted
+ wdt->wdd.dev = &pdev->dev; + wdt->wdd.info = &qcom_wdt_info; + wdt->wdd.ops = &qcom_wdt_ops; + wdt->wdd.min_timeout = 1; + wdt->wdd.max_timeout = 0x10000000U / freq;What if the frequency turns out to be larger than 8947848 Hz ? Then your maximum timeout is below the default timeout. And if the frequency is larger than 268435456 Hz, the maximum timeout would be 0.
Yes, I should be doing more sanity checking. I'll do so.
quoted
+ /* + * If 'timeout-sec' unspecified in devicetree, assume a 30 second + * default. + */ + if (watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev)) + wdt->wdd.timeout = 30;You can just initialize timeout above with 30 seconds. Saves you the if statement here.
Great. Thanks.
quoted
+ ret = watchdog_register_device(&wdt->wdd); + if (ret) { + dev_err(&pdev->dev, "failed to register watchdog\n");This will need a clk_disable_unprepare(). Given that this is needed twice, you might want to consider using error exit code below, as suggested in CodingStyle.
Indeed. Will do. Thanks again, Josh -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation