From patchwork Fri Jan 31 14:18:14 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Simek X-Patchwork-Id: 3561801 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CCE6A9F382 for ; Fri, 31 Jan 2014 14:21:08 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A344520213 for ; Fri, 31 Jan 2014 14:21:07 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 336D0201FD for ; Fri, 31 Jan 2014 14:21:06 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W9Ewt-0001Kv-5Y; Fri, 31 Jan 2014 14:20:03 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1W9Ewb-000144-GK; Fri, 31 Jan 2014 14:19:45 +0000 Received: from mail-ea0-f170.google.com ([209.85.215.170]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W9Evy-0000ws-KY for linux-arm-kernel@lists.infradead.org; Fri, 31 Jan 2014 14:19:09 +0000 Received: by mail-ea0-f170.google.com with SMTP id k10so2389605eaj.29 for ; Fri, 31 Jan 2014 06:18:45 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:in-reply-to:references:content-type; bh=ilqIC+t0rICKZExAR0P9Pl63Hr99C3w6lVz3qC+YF7c=; b=CLzJCiak709LMWl0D1eoaLvdSOPO+u9Dr1yjvPhlmwbJ43EWrv/Kd1fThyIJhzoyrp bGvDBSOkn0kOzxbXswVPVdirc9TvLLQ7Gwv9qau/l8XfN3s+omyuIwKTi0xk/mjmEyfn R3z/YnnQ2gjy6zofBsXoqBzHxmbrobtEqhPYIl6tvG5Rp+rFKKNq2mqnDrQlYaKBJNFF rcom4sqz8SnOXJESYp0AhqQrvOYAzOADph1ptLGzpouyoGpkjqX7Ek70Y/1kh5YY+91U 1FmQAGd1hvJHIakSPYmzqzf+s9E390J0qierBKlEgmws4adUML54xAgaiZt/H/rDLYdI adAg== X-Gm-Message-State: ALoCoQl6OHukagCXdcdw4/y7dF6VP0VbFEgZZMLSg5Rii8kRMeeFn7WDyv6+97xPP4v7WPcHBL6P X-Received: by 10.14.173.68 with SMTP id u44mr2859608eel.102.1391177924557; Fri, 31 Jan 2014 06:18:44 -0800 (PST) Received: from localhost (nat-63.starnet.cz. [178.255.168.63]) by mx.google.com with ESMTPSA id x2sm36929452eeo.8.2014.01.31.06.18.43 for (version=TLSv1.1 cipher=RC4-SHA bits=128/128); Fri, 31 Jan 2014 06:18:43 -0800 (PST) From: Michal Simek To: linux-kernel@vger.kernel.org, monstr@monstr.eu Subject: [PATCH 05/10] watchdog: xilinx: Allocate private structure per device Date: Fri, 31 Jan 2014 15:18:14 +0100 Message-Id: <255ff18dc52347e1bc8b0a0060eaa1037e02bdaa.1391177880.git.michal.simek@xilinx.com> X-Mailer: git-send-email 1.8.2.3 In-Reply-To: References: In-Reply-To: References: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140131_091906_992111_60BBEF78 X-CRM114-Status: GOOD ( 18.25 ) X-Spam-Score: -1.9 (-) Cc: Wim Van Sebroeck , linux-watchdog@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.8 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Only one watchdog could be used by this driver. Create driver private data structure and move there all variables for one instance. Signed-off-by: Michal Simek Reviewed-by: Guenter Roeck --- drivers/watchdog/of_xilinx_wdt.c | 97 +++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 42 deletions(-) -- 1.8.2.3 diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c index 1f7ad91..d28bd3f 100644 --- a/drivers/watchdog/of_xilinx_wdt.c +++ b/drivers/watchdog/of_xilinx_wdt.c @@ -47,30 +47,27 @@ struct xwdt_device { void __iomem *base; u32 wdt_interval; + spinlock_t spinlock; + struct watchdog_device xilinx_wdt_wdd; }; -static struct xwdt_device xdev; - -static u32 timeout; - -static DEFINE_SPINLOCK(spinlock); - static int xilinx_wdt_start(struct watchdog_device *wdd) { u32 control_status_reg; + struct xwdt_device *xdev = watchdog_get_drvdata(wdd); - spin_lock(&spinlock); + spin_lock(&xdev->spinlock); /* Clean previous status and enable the watchdog timer */ - control_status_reg = ioread32(xdev.base + XWT_TWCSR0_OFFSET); + control_status_reg = ioread32(xdev->base + XWT_TWCSR0_OFFSET); control_status_reg |= (XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK); iowrite32((control_status_reg | XWT_CSR0_EWDT1_MASK), - xdev.base + XWT_TWCSR0_OFFSET); + xdev->base + XWT_TWCSR0_OFFSET); - iowrite32(XWT_CSRX_EWDT2_MASK, xdev.base + XWT_TWCSR1_OFFSET); + iowrite32(XWT_CSRX_EWDT2_MASK, xdev->base + XWT_TWCSR1_OFFSET); - spin_unlock(&spinlock); + spin_unlock(&xdev->spinlock); return 0; } @@ -78,17 +75,18 @@ static int xilinx_wdt_start(struct watchdog_device *wdd) static int xilinx_wdt_stop(struct watchdog_device *wdd) { u32 control_status_reg; + struct xwdt_device *xdev = watchdog_get_drvdata(wdd); - spin_lock(&spinlock); + spin_lock(&xdev->spinlock); - control_status_reg = ioread32(xdev.base + XWT_TWCSR0_OFFSET); + control_status_reg = ioread32(xdev->base + XWT_TWCSR0_OFFSET); iowrite32((control_status_reg & ~XWT_CSR0_EWDT1_MASK), - xdev.base + XWT_TWCSR0_OFFSET); + xdev->base + XWT_TWCSR0_OFFSET); - iowrite32(0, xdev.base + XWT_TWCSR1_OFFSET); + iowrite32(0, xdev->base + XWT_TWCSR1_OFFSET); - spin_unlock(&spinlock); + spin_unlock(&xdev->spinlock); pr_info("Stopped!\n"); return 0; @@ -97,14 +95,15 @@ static int xilinx_wdt_stop(struct watchdog_device *wdd) static int xilinx_wdt_keepalive(struct watchdog_device *wdd) { u32 control_status_reg; + struct xwdt_device *xdev = watchdog_get_drvdata(wdd); - spin_lock(&spinlock); + spin_lock(&xdev->spinlock); - control_status_reg = ioread32(xdev.base + XWT_TWCSR0_OFFSET); + control_status_reg = ioread32(xdev->base + XWT_TWCSR0_OFFSET); control_status_reg |= (XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK); - iowrite32(control_status_reg, xdev.base + XWT_TWCSR0_OFFSET); + iowrite32(control_status_reg, xdev->base + XWT_TWCSR0_OFFSET); - spin_unlock(&spinlock); + spin_unlock(&xdev->spinlock); return 0; } @@ -123,29 +122,24 @@ static const struct watchdog_ops xilinx_wdt_ops = { .ping = xilinx_wdt_keepalive, }; -static struct watchdog_device xilinx_wdt_wdd = { - .info = &xilinx_wdt_ident, - .ops = &xilinx_wdt_ops, -}; - -static u32 xwdt_selftest(void) +static u32 xwdt_selftest(struct xwdt_device *xdev) { int i; u32 timer_value1; u32 timer_value2; - spin_lock(&spinlock); + spin_lock(&xdev->spinlock); - timer_value1 = ioread32(xdev.base + XWT_TBR_OFFSET); - timer_value2 = ioread32(xdev.base + XWT_TBR_OFFSET); + timer_value1 = ioread32(xdev->base + XWT_TBR_OFFSET); + timer_value2 = ioread32(xdev->base + XWT_TBR_OFFSET); for (i = 0; ((i <= XWT_MAX_SELFTEST_LOOP_COUNT) && (timer_value2 == timer_value1)); i++) { - timer_value2 = ioread32(xdev.base + XWT_TBR_OFFSET); + timer_value2 = ioread32(xdev->base + XWT_TBR_OFFSET); } - spin_unlock(&spinlock); + spin_unlock(&xdev->spinlock); if (timer_value2 != timer_value1) return ~XWT_TIMER_FAILED; @@ -159,12 +153,23 @@ static int xwdt_probe(struct platform_device *pdev) u32 *tmptr; u32 *pfreq; struct resource *res; + struct xwdt_device *xdev; bool no_timeout = false; + struct watchdog_device *xilinx_wdt_wdd; + + xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL); + if (!xdev) + return -ENOMEM; + + xilinx_wdt_wdd = &xdev->xilinx_wdt_wdd; + xilinx_wdt_wdd->info = &xilinx_wdt_ident; + xilinx_wdt_wdd->ops = &xilinx_wdt_ops; + xilinx_wdt_wdd->parent = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - xdev.base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(xdev.base)) - return PTR_ERR(xdev.base); + xdev->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(xdev->base)) + return PTR_ERR(xdev->base); pfreq = (u32 *)of_get_property(pdev->dev.of_node, "clock-frequency", NULL); @@ -180,14 +185,14 @@ static int xwdt_probe(struct platform_device *pdev) pr_warn("Parameter \"xlnx,wdt-interval\" not found in device tree!\n"); no_timeout = true; } else { - xdev.wdt_interval = *tmptr; + xdev->wdt_interval = *tmptr; } tmptr = (u32 *)of_get_property(pdev->dev.of_node, "xlnx,wdt-enable-once", NULL); if (tmptr == NULL) { pr_warn("Parameter \"xlnx,wdt-enable-once\" not found in device tree!\n"); - watchdog_set_nowayout(&xilinx_wdt_wdd, true); + watchdog_set_nowayout(xilinx_wdt_wdd, true); } /* @@ -195,29 +200,37 @@ static int xwdt_probe(struct platform_device *pdev) * ignored (interrupt), reset is only generated at second wdt overflow */ if (!no_timeout) - timeout = 2 * ((1<timeout = 2 * ((1 << xdev->wdt_interval) / + *pfreq); + + spin_lock_init(&xdev->spinlock); + watchdog_set_drvdata(xilinx_wdt_wdd, xdev); - rc = xwdt_selftest(); + rc = xwdt_selftest(xdev); if (rc == XWT_TIMER_FAILED) { pr_err("SelfTest routine error!\n"); return rc; } - rc = watchdog_register_device(&xilinx_wdt_wdd); + rc = watchdog_register_device(xilinx_wdt_wdd); if (rc) { pr_err("cannot register watchdog (err=%d)\n", rc); return rc; } dev_info(&pdev->dev, "Xilinx Watchdog Timer at %p with timeout %ds\n", - xdev.base, timeout); + xdev->base, xilinx_wdt_wdd->timeout); + + platform_set_drvdata(pdev, xdev); return 0; } -static int xwdt_remove(struct platform_device *dev) +static int xwdt_remove(struct platform_device *pdev) { - watchdog_unregister_device(&xilinx_wdt_wdd); + struct xwdt_device *xdev = platform_get_drvdata(pdev); + + watchdog_unregister_device(&xdev->xilinx_wdt_wdd); return 0; }