From patchwork Wed Feb 12 13:41:19 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Simek X-Patchwork-Id: 3638151 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 083219F382 for ; Wed, 12 Feb 2014 13:42:24 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E6337201D5 for ; Wed, 12 Feb 2014 13:42:22 +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 D158220142 for ; Wed, 12 Feb 2014 13:42:20 +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 1WDa4n-0002vO-K8; Wed, 12 Feb 2014 13:42:09 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WDa4l-0003Qp-43; Wed, 12 Feb 2014 13:42:07 +0000 Received: from mail-ea0-f174.google.com ([209.85.215.174]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WDa4h-0003Po-TX for linux-arm-kernel@lists.infradead.org; Wed, 12 Feb 2014 13:42:04 +0000 Received: by mail-ea0-f174.google.com with SMTP id z10so1102976ead.5 for ; Wed, 12 Feb 2014 05:41:41 -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:content-type; bh=NZ88cGn8gg+uS1TLDSj/ed9DX1QnguvFLbdFB0O4rSY=; b=Q76AFz5yXeDCSvcvvkk2fBQBNRToiju0krUVfL81a9Kvjj7iuORoUwj8D2jgfzDbV4 QAU5vzAcuyJaCopw6jB9eBkYc+TG93PX4d5g+4erPkrHd60RE+Sygce83blhRbSkLDke wlxotz17MAhNj4MmLEW/80LZxZXuYDozEWO04o1qFe/vvcvYxPxpKrD9klUDDTtVyf7X Nyc39sUUqPRnNb7rWP3/9beUPmi6Jkel5jBw2XwjQ6kHk5QN1YaaoK/kLtt6j1teD3N9 y1odieL5n+Mh6vhufDXaxp9S05/wOksca9qTcH4wUcfqbgMhqe2b4PdS3msUbgm7hxgn dI7g== X-Gm-Message-State: ALoCoQl2YIYYuBbmyIViOr8ADxeg8/9ZO3knz4vYAvw3DckSBBYFAH1KwZi5PxlyVszW0nxtLlVI X-Received: by 10.14.105.200 with SMTP id k48mr4017903eeg.44.1392212501293; Wed, 12 Feb 2014 05:41:41 -0800 (PST) Received: from localhost (nat-63.starnet.cz. [178.255.168.63]) by mx.google.com with ESMTPSA id x2sm81109625eeo.8.2014.02.12.05.41.33 for (version=TLSv1.1 cipher=RC4-SHA bits=128/128); Wed, 12 Feb 2014 05:41:39 -0800 (PST) From: Michal Simek To: linux-kernel@vger.kernel.org, monstr@monstr.eu Subject: [PATCH v3 05/11] watchdog: xilinx: Allocate private structure per device Date: Wed, 12 Feb 2014 14:41:19 +0100 Message-Id: X-Mailer: git-send-email 1.8.2.3 In-Reply-To: References: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140212_084204_181947_71F49762 X-CRM114-Status: GOOD ( 18.76 ) X-Spam-Score: -1.9 (-) Cc: linux-arm-kernel@lists.infradead.org, wim@iguana.be, linux-watchdog@vger.kernel.org, linux@roeck-us.net 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 --- Changes in v3: None Changes in v2: None 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; }