Thread (9 messages) 9 messages, 4 authors, 2014-09-24

[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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help