From: michal.simek@xilinx.com (Michal Simek)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 05/11] watchdog: xilinx: Allocate private structure per device
Date: Wed, 12 Feb 2014 14:41:19 +0100 [thread overview]
Message-ID: <bdd7c2c78dd491d02d1c1ae8a59b92b7a1a17ec6.1392212059.git.michal.simek@xilinx.com> (raw)
In-Reply-To: <cover.1392212059.git.michal.simek@xilinx.com>
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 <michal.simek@xilinx.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
---
Changes in v3: None
Changes in v2: None
drivers/watchdog/of_xilinx_wdt.c | 97 +++++++++++++++++++++++-----------------
1 file changed, 55 insertions(+), 42 deletions(-)
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<<xdev.wdt_interval) / *pfreq);
+ xilinx_wdt_wdd->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;
}
--
1.8.2.3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140212/8a578026/attachment.sig>
next prev parent reply other threads:[~2014-02-12 13:41 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-12 13:34 [PATCH v3 0/11] Xilinx watchdog changes Michal Simek
2014-02-12 13:34 ` [PATCH v3 01/11] watchdog: xilinx: Convert driver to the watchdog framework Michal Simek
2014-02-12 13:34 ` [PATCH v3 02/11] watchdog: xilinx: Move control_status_reg to functions Michal Simek
2014-02-12 13:34 ` [PATCH v3 03/11] watchdog: xilinx: Simplify probe and remove functions Michal Simek
2014-02-12 13:34 ` [PATCH v3 04/11] watchdog: xilinx: Move no_timeout to probe function Michal Simek
2014-02-12 13:41 ` Michal Simek [this message]
2014-02-12 13:41 ` [PATCH v3 06/11] watchdog: xilinx: Fix all printk messages Michal Simek
2014-02-12 13:41 ` [PATCH v3 07/11] watchdog: xilinx: Use of_property_read_u32 Michal Simek
2014-02-12 17:15 ` Guenter Roeck
[not found] ` <20140222184604.GB21504@spo001.leaseweb.com>
2014-02-23 1:08 ` Alejandro Cabrera
2014-02-22 23:18 ` Guenter Roeck
2014-02-23 3:52 ` Alejandro Cabrera
2014-02-23 1:36 ` Guenter Roeck
2014-02-23 6:14 ` Alejandro Cabrera
2014-02-23 3:44 ` Guenter Roeck
2014-02-23 16:25 ` Alejandro Cabrera
2014-02-23 14:43 ` Guenter Roeck
2014-02-23 19:00 ` Alejandro Cabrera
2014-02-24 8:52 ` Michal Simek
[not found] ` <20140224192507.GO1484@spo001.leaseweb.com>
2014-02-25 7:39 ` Michal Simek
2014-02-12 13:41 ` [PATCH v3 08/11] watchdog: xilinx: Use correct comment indentation Michal Simek
2014-02-12 13:41 ` [PATCH v3 09/11] watchdog: xilinx: Add missing binding Michal Simek
2014-02-12 13:41 ` [PATCH v3 10/11] watchdog: xilinx: Enable this driver for Zynq Michal Simek
[not found] ` <20140222184419.GA21504@spo001.leaseweb.com>
2014-02-22 20:42 ` Guenter Roeck
2014-02-12 13:41 ` [PATCH v3 11/11] watchdog: xilinx: Remove no_timeout variable Michal Simek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=bdd7c2c78dd491d02d1c1ae8a59b92b7a1a17ec6.1392212059.git.michal.simek@xilinx.com \
--to=michal.simek@xilinx.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).