All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Arlott <simon@fire.lp0.eu>
To: Guenter Roeck <linux@roeck-us.net>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
	Ralf Baechle <ralf@linux-mips.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Jason Cooper <jason@lakedaemon.net>,
	Marc Zyngier <marc.zyngier@arm.com>,
	Kevin Cernekee <cernekee@gmail.com>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Wim Van Sebroeck <wim@iguana.be>,
	Maxime Bizon <mbizon@freebox.fr>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	linux-mips@linux-mips.org, linux-watchdog@vger.kernel.org
Cc: Rob Herring <robh+dt@kernel.org>, Pawel Moll <pawel.moll@arm.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Ian Campbell <ijc+devicetree@hellion.org.uk>,
	Kumar Gala <galak@codeaurora.org>,
	Jonas Gorski <jogo@openwrt.org>
Subject: [PATCH (v2) 10/11] watchdog: bcm63xx_wdt: Use bcm63xx_timer interrupt directly
Date: Wed, 25 Nov 2015 23:03:49 +0000	[thread overview]
Message-ID: <56563E55.3060109@simon.arlott.org.uk> (raw)
In-Reply-To: <5651CD67.6090507@simon.arlott.org.uk>

There is only one user of bcm63xx_timer and that is the watchdog.
To allow the watchdog driver to be used on machine types other than
mach-bcm63xx, it needs to use an interrupt instead of a custom register
function.

Modify bcm63xx_timer to only disable the timers (so that they don't
interfere with the watchdog if an interrupt occurs) and remove its
exported functions.

Use the timer interrupt directly in bcm63xx_wdt.

Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
---
Patch 7 split into two patches.

There was no change to patch 8/10 which is now 9/11.

On 25/11/15 22:40, Simon Arlott wrote:
> Moved registration of the timer in the probe function to after register
> of the watchdog device because the interrupt handler uses wdd->dev.

This patch (9/10 now 10/11) was affected by this reordering, and an
earlier change to use "hw" instead of "wdd" as the interrupt data.

 arch/mips/bcm63xx/dev-wdt.c                        |   7 +
 arch/mips/bcm63xx/timer.c                          | 181 +--------------------
 arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h |  11 --
 drivers/watchdog/bcm63xx_wdt.c                     |  41 +++--
 4 files changed, 36 insertions(+), 204 deletions(-)
 delete mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h

diff --git a/arch/mips/bcm63xx/dev-wdt.c b/arch/mips/bcm63xx/dev-wdt.c
index 2a2346a..a7a5497 100644
--- a/arch/mips/bcm63xx/dev-wdt.c
+++ b/arch/mips/bcm63xx/dev-wdt.c
@@ -17,6 +17,11 @@ static struct resource wdt_resources[] = {
 		.end		= -1, /* filled at runtime */
 		.flags		= IORESOURCE_MEM,
 	},
+	{
+		.start		= -1, /* filled at runtime */
+		.end		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
 };
 
 static struct platform_device bcm63xx_wdt_device = {
@@ -32,6 +37,8 @@ int __init bcm63xx_wdt_register(void)
 	wdt_resources[0].end = wdt_resources[0].start;
 	wdt_resources[0].end += RSET_WDT_SIZE - 1;
 
+	wdt_resources[1].start = bcm63xx_get_irq_number(IRQ_TIMER);
+
 	return platform_device_register(&bcm63xx_wdt_device);
 }
 arch_initcall(bcm63xx_wdt_register);
diff --git a/arch/mips/bcm63xx/timer.c b/arch/mips/bcm63xx/timer.c
index 2110359..9c7b41a6 100644
--- a/arch/mips/bcm63xx/timer.c
+++ b/arch/mips/bcm63xx/timer.c
@@ -9,196 +9,23 @@
 #include <linux/kernel.h>
 #include <linux/err.h>
 #include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/clk.h>
 #include <bcm63xx_cpu.h>
 #include <bcm63xx_io.h>
-#include <bcm63xx_timer.h>
 #include <bcm63xx_regs.h>
 
-static DEFINE_RAW_SPINLOCK(timer_reg_lock);
-static DEFINE_RAW_SPINLOCK(timer_data_lock);
-static struct clk *periph_clk;
-
-static struct timer_data {
-	void	(*cb)(void *);
-	void	*data;
-} timer_data[BCM63XX_TIMER_COUNT];
-
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
-	u32 stat;
-	int i;
-
-	raw_spin_lock(&timer_reg_lock);
-	stat = bcm_timer_readl(TIMER_IRQSTAT_REG);
-	bcm_timer_writel(stat, TIMER_IRQSTAT_REG);
-	raw_spin_unlock(&timer_reg_lock);
-
-	for (i = 0; i < BCM63XX_TIMER_COUNT; i++) {
-		if (!(stat & TIMER_IRQSTAT_TIMER_CAUSE(i)))
-			continue;
-
-		raw_spin_lock(&timer_data_lock);
-		if (!timer_data[i].cb) {
-			raw_spin_unlock(&timer_data_lock);
-			continue;
-		}
-
-		timer_data[i].cb(timer_data[i].data);
-		raw_spin_unlock(&timer_data_lock);
-	}
-
-	return IRQ_HANDLED;
-}
-
-int bcm63xx_timer_enable(int id)
-{
-	u32 reg;
-	unsigned long flags;
-
-	if (id >= BCM63XX_TIMER_COUNT)
-		return -EINVAL;
-
-	raw_spin_lock_irqsave(&timer_reg_lock, flags);
-
-	reg = bcm_timer_readl(TIMER_CTLx_REG(id));
-	reg |= TIMER_CTL_ENABLE_MASK;
-	bcm_timer_writel(reg, TIMER_CTLx_REG(id));
-
-	reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
-	reg |= TIMER_IRQSTAT_TIMER_IR_EN(id);
-	bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
-
-	raw_spin_unlock_irqrestore(&timer_reg_lock, flags);
-	return 0;
-}
-
-EXPORT_SYMBOL(bcm63xx_timer_enable);
-
-int bcm63xx_timer_disable(int id)
+static int bcm63xx_timer_init(void)
 {
 	u32 reg;
-	unsigned long flags;
-
-	if (id >= BCM63XX_TIMER_COUNT)
-		return -EINVAL;
-
-	raw_spin_lock_irqsave(&timer_reg_lock, flags);
-
-	reg = bcm_timer_readl(TIMER_CTLx_REG(id));
-	reg &= ~TIMER_CTL_ENABLE_MASK;
-	bcm_timer_writel(reg, TIMER_CTLx_REG(id));
-
-	reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
-	reg &= ~TIMER_IRQSTAT_TIMER_IR_EN(id);
-	bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
-
-	raw_spin_unlock_irqrestore(&timer_reg_lock, flags);
-	return 0;
-}
-
-EXPORT_SYMBOL(bcm63xx_timer_disable);
-
-int bcm63xx_timer_register(int id, void (*callback)(void *data), void *data)
-{
-	unsigned long flags;
-	int ret;
-
-	if (id >= BCM63XX_TIMER_COUNT || !callback)
-		return -EINVAL;
-
-	ret = 0;
-	raw_spin_lock_irqsave(&timer_data_lock, flags);
-	if (timer_data[id].cb) {
-		ret = -EBUSY;
-		goto out;
-	}
-
-	timer_data[id].cb = callback;
-	timer_data[id].data = data;
-
-out:
-	raw_spin_unlock_irqrestore(&timer_data_lock, flags);
-	return ret;
-}
-
-EXPORT_SYMBOL(bcm63xx_timer_register);
-
-void bcm63xx_timer_unregister(int id)
-{
-	unsigned long flags;
-
-	if (id >= BCM63XX_TIMER_COUNT)
-		return;
-
-	raw_spin_lock_irqsave(&timer_data_lock, flags);
-	timer_data[id].cb = NULL;
-	raw_spin_unlock_irqrestore(&timer_data_lock, flags);
-}
-
-EXPORT_SYMBOL(bcm63xx_timer_unregister);
-
-unsigned int bcm63xx_timer_countdown(unsigned int countdown_us)
-{
-	return (clk_get_rate(periph_clk) / (1000 * 1000)) * countdown_us;
-}
-
-EXPORT_SYMBOL(bcm63xx_timer_countdown);
-
-int bcm63xx_timer_set(int id, int monotonic, unsigned int countdown_us)
-{
-	u32 reg, countdown;
-	unsigned long flags;
-
-	if (id >= BCM63XX_TIMER_COUNT)
-		return -EINVAL;
-
-	countdown = bcm63xx_timer_countdown(countdown_us);
-	if (countdown & ~TIMER_CTL_COUNTDOWN_MASK)
-		return -EINVAL;
-
-	raw_spin_lock_irqsave(&timer_reg_lock, flags);
-	reg = bcm_timer_readl(TIMER_CTLx_REG(id));
-
-	if (monotonic)
-		reg &= ~TIMER_CTL_MONOTONIC_MASK;
-	else
-		reg |= TIMER_CTL_MONOTONIC_MASK;
-
-	reg &= ~TIMER_CTL_COUNTDOWN_MASK;
-	reg |= countdown;
-	bcm_timer_writel(reg, TIMER_CTLx_REG(id));
-
-	raw_spin_unlock_irqrestore(&timer_reg_lock, flags);
-	return 0;
-}
-
-EXPORT_SYMBOL(bcm63xx_timer_set);
-
-int bcm63xx_timer_init(void)
-{
-	int ret, irq;
-	u32 reg;
 
+	/* Disable all timers so that they won't interfere with use of the
+	 * timer interrupt by the watchdog.
+	 */
 	reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
 	reg &= ~TIMER_IRQSTAT_TIMER0_IR_EN;
 	reg &= ~TIMER_IRQSTAT_TIMER1_IR_EN;
 	reg &= ~TIMER_IRQSTAT_TIMER2_IR_EN;
 	bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
 
-	periph_clk = clk_get(NULL, "periph");
-	if (IS_ERR(periph_clk))
-		return -ENODEV;
-
-	irq = bcm63xx_get_irq_number(IRQ_TIMER);
-	ret = request_irq(irq, timer_interrupt, 0, "bcm63xx_timer", NULL);
-	if (ret) {
-		pr_err("%s: failed to register irq\n", __func__);
-		return ret;
-	}
-
 	return 0;
 }
 
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h
deleted file mode 100644
index c0fce83..0000000
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef BCM63XX_TIMER_H_
-#define BCM63XX_TIMER_H_
-
-int bcm63xx_timer_register(int id, void (*callback)(void *data), void *data);
-void bcm63xx_timer_unregister(int id);
-int bcm63xx_timer_set(int id, int monotonic, unsigned int countdown_us);
-int bcm63xx_timer_enable(int id);
-int bcm63xx_timer_disable(int id);
-unsigned int bcm63xx_timer_countdown(unsigned int countdown_us);
-
-#endif /* !BCM63XX_TIMER_H_ */
diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c
index f409523..fa6c28b 100644
--- a/drivers/watchdog/bcm63xx_wdt.c
+++ b/drivers/watchdog/bcm63xx_wdt.c
@@ -17,6 +17,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -28,9 +29,6 @@
 #include <linux/resource.h>
 #include <linux/platform_device.h>
 
-#include <bcm63xx_regs.h>
-#include <bcm63xx_timer.h>
-
 #define PFX KBUILD_MODNAME
 
 #define WDT_CLK_NAME		"periph"
@@ -41,6 +39,7 @@ struct bcm63xx_wdt_hw {
 	void __iomem *regs;
 	struct clk *clk;
 	unsigned long clock_hz;
+	int irq;
 	bool running;
 };
 
@@ -99,7 +98,7 @@ static int bcm63xx_wdt_set_timeout(struct watchdog_device *wdd,
 }
 
 /* The watchdog interrupt occurs when half the timeout is remaining */
-static void bcm63xx_wdt_isr(void *data)
+static irqreturn_t bcm63xx_wdt_interrupt(int irq, void *data)
 {
 	struct bcm63xx_wdt_hw *hw = data;
 	unsigned long flags;
@@ -139,6 +138,7 @@ static void bcm63xx_wdt_isr(void *data)
 			"warning timer fired, reboot in %ums\n", ms);
 	}
 	raw_spin_unlock_irqrestore(&hw->lock, flags);
+	return IRQ_HANDLED;
 }
 
 static struct watchdog_ops bcm63xx_wdt_ops = {
@@ -237,24 +237,31 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
 		goto disable_clk;
 	}
 
-	ret = bcm63xx_timer_register(TIMER_WDT_ID, bcm63xx_wdt_isr, hw);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "failed to register wdt timer isr\n");
-		goto unregister_watchdog;
+	hw->irq = platform_get_irq(pdev, 0);
+	if (hw->irq >= 0) {
+		ret = devm_request_irq(&pdev->dev, hw->irq,
+			bcm63xx_wdt_interrupt, IRQF_TIMER,
+			dev_name(&pdev->dev), hw);
+		if (ret)
+			hw->irq = -1;
 	}
 
-	dev_info(&pdev->dev,
-		"%s at MMIO 0x%p (timeout = %us, max_timeout = %us)",
-		dev_name(wdd->dev), hw->regs,
-		wdd->timeout, wdd->max_timeout);
+	if (hw->irq >= 0) {
+		dev_info(&pdev->dev,
+			"%s at MMIO 0x%p (irq = %d, timeout = %us, max_timeout = %us)",
+			dev_name(wdd->dev), hw->regs, hw->irq,
+			wdd->timeout, wdd->max_timeout);
+	} else {
+		dev_info(&pdev->dev,
+			"%s at MMIO 0x%p (timeout = %us, max_timeout = %us)",
+			dev_name(wdd->dev), hw->regs,
+			wdd->timeout, wdd->max_timeout);
+	}
 
 	if (hw->running)
 		dev_alert(wdd->dev, "running, reboot in %us\n", timeleft);
 	return 0;
 
-unregister_watchdog:
-	watchdog_unregister_device(wdd);
-
 disable_clk:
 	clk_disable_unprepare(hw->clk);
 	return ret;
@@ -264,7 +271,9 @@ static int bcm63xx_wdt_remove(struct platform_device *pdev)
 {
 	struct bcm63xx_wdt_hw *hw = platform_get_drvdata(pdev);
 
-	bcm63xx_timer_unregister(TIMER_WDT_ID);
+	if (hw->irq >= 0)
+		devm_free_irq(&pdev->dev, hw->irq, hw);
+
 	watchdog_unregister_device(&hw->wdd);
 	clk_disable_unprepare(hw->clk);
 	return 0;
-- 
2.1.4

-- 
Simon Arlott

WARNING: multiple messages have this Message-ID (diff)
From: Simon Arlott <simon-A6De1vDTPLDsq35pWSNszA@public.gmane.org>
To: Guenter Roeck <linux-0h96xk9xTtrk1uMJSBkQmQ@public.gmane.org>,
	"devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org"
	<devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	Ralf Baechle <ralf-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org>,
	Thomas Gleixner <tglx-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org>,
	Jason Cooper <jason-NLaQJdtUoK4Be96aLqz0jA@public.gmane.org>,
	Marc Zyngier <marc.zyngier-5wv7dgnIgG8@public.gmane.org>,
	Kevin Cernekee <cernekee-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Florian Fainelli
	<f.fainelli-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Wim Van Sebroeck <wim-IQzOog9fTRqzQB+pC5nmwQ@public.gmane.org>,
	Maxime Bizon <mbizon-MmRyKUhfbQ9GWvitb5QawA@public.gmane.org>,
	Linux Kernel Mailing List
	<linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
	linux-mips-6z/3iImG2C8G8FEW9MqTrA@public.gmane.org,
	linux-watchdog-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Pawel Moll <pawel.moll-5wv7dgnIgG8@public.gmane.org>,
	Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>,
	Ian Campbell
	<ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org>,
	Kumar Gala <galak-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>,
	Jonas Gorski <jogo-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
Subject: [PATCH (v2) 10/11] watchdog: bcm63xx_wdt: Use bcm63xx_timer interrupt directly
Date: Wed, 25 Nov 2015 23:03:49 +0000	[thread overview]
Message-ID: <56563E55.3060109@simon.arlott.org.uk> (raw)
In-Reply-To: <5651CD67.6090507-qdVf85lJwsCyrPCCpiK2c/XRex20P6io@public.gmane.org>

There is only one user of bcm63xx_timer and that is the watchdog.
To allow the watchdog driver to be used on machine types other than
mach-bcm63xx, it needs to use an interrupt instead of a custom register
function.

Modify bcm63xx_timer to only disable the timers (so that they don't
interfere with the watchdog if an interrupt occurs) and remove its
exported functions.

Use the timer interrupt directly in bcm63xx_wdt.

Signed-off-by: Simon Arlott <simon-A6De1vDTPLDsq35pWSNszA@public.gmane.org>
---
Patch 7 split into two patches.

There was no change to patch 8/10 which is now 9/11.

On 25/11/15 22:40, Simon Arlott wrote:
> Moved registration of the timer in the probe function to after register
> of the watchdog device because the interrupt handler uses wdd->dev.

This patch (9/10 now 10/11) was affected by this reordering, and an
earlier change to use "hw" instead of "wdd" as the interrupt data.

 arch/mips/bcm63xx/dev-wdt.c                        |   7 +
 arch/mips/bcm63xx/timer.c                          | 181 +--------------------
 arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h |  11 --
 drivers/watchdog/bcm63xx_wdt.c                     |  41 +++--
 4 files changed, 36 insertions(+), 204 deletions(-)
 delete mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h

diff --git a/arch/mips/bcm63xx/dev-wdt.c b/arch/mips/bcm63xx/dev-wdt.c
index 2a2346a..a7a5497 100644
--- a/arch/mips/bcm63xx/dev-wdt.c
+++ b/arch/mips/bcm63xx/dev-wdt.c
@@ -17,6 +17,11 @@ static struct resource wdt_resources[] = {
 		.end		= -1, /* filled at runtime */
 		.flags		= IORESOURCE_MEM,
 	},
+	{
+		.start		= -1, /* filled at runtime */
+		.end		= -1, /* filled at runtime */
+		.flags		= IORESOURCE_IRQ,
+	},
 };
 
 static struct platform_device bcm63xx_wdt_device = {
@@ -32,6 +37,8 @@ int __init bcm63xx_wdt_register(void)
 	wdt_resources[0].end = wdt_resources[0].start;
 	wdt_resources[0].end += RSET_WDT_SIZE - 1;
 
+	wdt_resources[1].start = bcm63xx_get_irq_number(IRQ_TIMER);
+
 	return platform_device_register(&bcm63xx_wdt_device);
 }
 arch_initcall(bcm63xx_wdt_register);
diff --git a/arch/mips/bcm63xx/timer.c b/arch/mips/bcm63xx/timer.c
index 2110359..9c7b41a6 100644
--- a/arch/mips/bcm63xx/timer.c
+++ b/arch/mips/bcm63xx/timer.c
@@ -9,196 +9,23 @@
 #include <linux/kernel.h>
 #include <linux/err.h>
 #include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/clk.h>
 #include <bcm63xx_cpu.h>
 #include <bcm63xx_io.h>
-#include <bcm63xx_timer.h>
 #include <bcm63xx_regs.h>
 
-static DEFINE_RAW_SPINLOCK(timer_reg_lock);
-static DEFINE_RAW_SPINLOCK(timer_data_lock);
-static struct clk *periph_clk;
-
-static struct timer_data {
-	void	(*cb)(void *);
-	void	*data;
-} timer_data[BCM63XX_TIMER_COUNT];
-
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
-	u32 stat;
-	int i;
-
-	raw_spin_lock(&timer_reg_lock);
-	stat = bcm_timer_readl(TIMER_IRQSTAT_REG);
-	bcm_timer_writel(stat, TIMER_IRQSTAT_REG);
-	raw_spin_unlock(&timer_reg_lock);
-
-	for (i = 0; i < BCM63XX_TIMER_COUNT; i++) {
-		if (!(stat & TIMER_IRQSTAT_TIMER_CAUSE(i)))
-			continue;
-
-		raw_spin_lock(&timer_data_lock);
-		if (!timer_data[i].cb) {
-			raw_spin_unlock(&timer_data_lock);
-			continue;
-		}
-
-		timer_data[i].cb(timer_data[i].data);
-		raw_spin_unlock(&timer_data_lock);
-	}
-
-	return IRQ_HANDLED;
-}
-
-int bcm63xx_timer_enable(int id)
-{
-	u32 reg;
-	unsigned long flags;
-
-	if (id >= BCM63XX_TIMER_COUNT)
-		return -EINVAL;
-
-	raw_spin_lock_irqsave(&timer_reg_lock, flags);
-
-	reg = bcm_timer_readl(TIMER_CTLx_REG(id));
-	reg |= TIMER_CTL_ENABLE_MASK;
-	bcm_timer_writel(reg, TIMER_CTLx_REG(id));
-
-	reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
-	reg |= TIMER_IRQSTAT_TIMER_IR_EN(id);
-	bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
-
-	raw_spin_unlock_irqrestore(&timer_reg_lock, flags);
-	return 0;
-}
-
-EXPORT_SYMBOL(bcm63xx_timer_enable);
-
-int bcm63xx_timer_disable(int id)
+static int bcm63xx_timer_init(void)
 {
 	u32 reg;
-	unsigned long flags;
-
-	if (id >= BCM63XX_TIMER_COUNT)
-		return -EINVAL;
-
-	raw_spin_lock_irqsave(&timer_reg_lock, flags);
-
-	reg = bcm_timer_readl(TIMER_CTLx_REG(id));
-	reg &= ~TIMER_CTL_ENABLE_MASK;
-	bcm_timer_writel(reg, TIMER_CTLx_REG(id));
-
-	reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
-	reg &= ~TIMER_IRQSTAT_TIMER_IR_EN(id);
-	bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
-
-	raw_spin_unlock_irqrestore(&timer_reg_lock, flags);
-	return 0;
-}
-
-EXPORT_SYMBOL(bcm63xx_timer_disable);
-
-int bcm63xx_timer_register(int id, void (*callback)(void *data), void *data)
-{
-	unsigned long flags;
-	int ret;
-
-	if (id >= BCM63XX_TIMER_COUNT || !callback)
-		return -EINVAL;
-
-	ret = 0;
-	raw_spin_lock_irqsave(&timer_data_lock, flags);
-	if (timer_data[id].cb) {
-		ret = -EBUSY;
-		goto out;
-	}
-
-	timer_data[id].cb = callback;
-	timer_data[id].data = data;
-
-out:
-	raw_spin_unlock_irqrestore(&timer_data_lock, flags);
-	return ret;
-}
-
-EXPORT_SYMBOL(bcm63xx_timer_register);
-
-void bcm63xx_timer_unregister(int id)
-{
-	unsigned long flags;
-
-	if (id >= BCM63XX_TIMER_COUNT)
-		return;
-
-	raw_spin_lock_irqsave(&timer_data_lock, flags);
-	timer_data[id].cb = NULL;
-	raw_spin_unlock_irqrestore(&timer_data_lock, flags);
-}
-
-EXPORT_SYMBOL(bcm63xx_timer_unregister);
-
-unsigned int bcm63xx_timer_countdown(unsigned int countdown_us)
-{
-	return (clk_get_rate(periph_clk) / (1000 * 1000)) * countdown_us;
-}
-
-EXPORT_SYMBOL(bcm63xx_timer_countdown);
-
-int bcm63xx_timer_set(int id, int monotonic, unsigned int countdown_us)
-{
-	u32 reg, countdown;
-	unsigned long flags;
-
-	if (id >= BCM63XX_TIMER_COUNT)
-		return -EINVAL;
-
-	countdown = bcm63xx_timer_countdown(countdown_us);
-	if (countdown & ~TIMER_CTL_COUNTDOWN_MASK)
-		return -EINVAL;
-
-	raw_spin_lock_irqsave(&timer_reg_lock, flags);
-	reg = bcm_timer_readl(TIMER_CTLx_REG(id));
-
-	if (monotonic)
-		reg &= ~TIMER_CTL_MONOTONIC_MASK;
-	else
-		reg |= TIMER_CTL_MONOTONIC_MASK;
-
-	reg &= ~TIMER_CTL_COUNTDOWN_MASK;
-	reg |= countdown;
-	bcm_timer_writel(reg, TIMER_CTLx_REG(id));
-
-	raw_spin_unlock_irqrestore(&timer_reg_lock, flags);
-	return 0;
-}
-
-EXPORT_SYMBOL(bcm63xx_timer_set);
-
-int bcm63xx_timer_init(void)
-{
-	int ret, irq;
-	u32 reg;
 
+	/* Disable all timers so that they won't interfere with use of the
+	 * timer interrupt by the watchdog.
+	 */
 	reg = bcm_timer_readl(TIMER_IRQSTAT_REG);
 	reg &= ~TIMER_IRQSTAT_TIMER0_IR_EN;
 	reg &= ~TIMER_IRQSTAT_TIMER1_IR_EN;
 	reg &= ~TIMER_IRQSTAT_TIMER2_IR_EN;
 	bcm_timer_writel(reg, TIMER_IRQSTAT_REG);
 
-	periph_clk = clk_get(NULL, "periph");
-	if (IS_ERR(periph_clk))
-		return -ENODEV;
-
-	irq = bcm63xx_get_irq_number(IRQ_TIMER);
-	ret = request_irq(irq, timer_interrupt, 0, "bcm63xx_timer", NULL);
-	if (ret) {
-		pr_err("%s: failed to register irq\n", __func__);
-		return ret;
-	}
-
 	return 0;
 }
 
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h
deleted file mode 100644
index c0fce83..0000000
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_timer.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef BCM63XX_TIMER_H_
-#define BCM63XX_TIMER_H_
-
-int bcm63xx_timer_register(int id, void (*callback)(void *data), void *data);
-void bcm63xx_timer_unregister(int id);
-int bcm63xx_timer_set(int id, int monotonic, unsigned int countdown_us);
-int bcm63xx_timer_enable(int id);
-int bcm63xx_timer_disable(int id);
-unsigned int bcm63xx_timer_countdown(unsigned int countdown_us);
-
-#endif /* !BCM63XX_TIMER_H_ */
diff --git a/drivers/watchdog/bcm63xx_wdt.c b/drivers/watchdog/bcm63xx_wdt.c
index f409523..fa6c28b 100644
--- a/drivers/watchdog/bcm63xx_wdt.c
+++ b/drivers/watchdog/bcm63xx_wdt.c
@@ -17,6 +17,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -28,9 +29,6 @@
 #include <linux/resource.h>
 #include <linux/platform_device.h>
 
-#include <bcm63xx_regs.h>
-#include <bcm63xx_timer.h>
-
 #define PFX KBUILD_MODNAME
 
 #define WDT_CLK_NAME		"periph"
@@ -41,6 +39,7 @@ struct bcm63xx_wdt_hw {
 	void __iomem *regs;
 	struct clk *clk;
 	unsigned long clock_hz;
+	int irq;
 	bool running;
 };
 
@@ -99,7 +98,7 @@ static int bcm63xx_wdt_set_timeout(struct watchdog_device *wdd,
 }
 
 /* The watchdog interrupt occurs when half the timeout is remaining */
-static void bcm63xx_wdt_isr(void *data)
+static irqreturn_t bcm63xx_wdt_interrupt(int irq, void *data)
 {
 	struct bcm63xx_wdt_hw *hw = data;
 	unsigned long flags;
@@ -139,6 +138,7 @@ static void bcm63xx_wdt_isr(void *data)
 			"warning timer fired, reboot in %ums\n", ms);
 	}
 	raw_spin_unlock_irqrestore(&hw->lock, flags);
+	return IRQ_HANDLED;
 }
 
 static struct watchdog_ops bcm63xx_wdt_ops = {
@@ -237,24 +237,31 @@ static int bcm63xx_wdt_probe(struct platform_device *pdev)
 		goto disable_clk;
 	}
 
-	ret = bcm63xx_timer_register(TIMER_WDT_ID, bcm63xx_wdt_isr, hw);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "failed to register wdt timer isr\n");
-		goto unregister_watchdog;
+	hw->irq = platform_get_irq(pdev, 0);
+	if (hw->irq >= 0) {
+		ret = devm_request_irq(&pdev->dev, hw->irq,
+			bcm63xx_wdt_interrupt, IRQF_TIMER,
+			dev_name(&pdev->dev), hw);
+		if (ret)
+			hw->irq = -1;
 	}
 
-	dev_info(&pdev->dev,
-		"%s at MMIO 0x%p (timeout = %us, max_timeout = %us)",
-		dev_name(wdd->dev), hw->regs,
-		wdd->timeout, wdd->max_timeout);
+	if (hw->irq >= 0) {
+		dev_info(&pdev->dev,
+			"%s at MMIO 0x%p (irq = %d, timeout = %us, max_timeout = %us)",
+			dev_name(wdd->dev), hw->regs, hw->irq,
+			wdd->timeout, wdd->max_timeout);
+	} else {
+		dev_info(&pdev->dev,
+			"%s at MMIO 0x%p (timeout = %us, max_timeout = %us)",
+			dev_name(wdd->dev), hw->regs,
+			wdd->timeout, wdd->max_timeout);
+	}
 
 	if (hw->running)
 		dev_alert(wdd->dev, "running, reboot in %us\n", timeleft);
 	return 0;
 
-unregister_watchdog:
-	watchdog_unregister_device(wdd);
-
 disable_clk:
 	clk_disable_unprepare(hw->clk);
 	return ret;
@@ -264,7 +271,9 @@ static int bcm63xx_wdt_remove(struct platform_device *pdev)
 {
 	struct bcm63xx_wdt_hw *hw = platform_get_drvdata(pdev);
 
-	bcm63xx_timer_unregister(TIMER_WDT_ID);
+	if (hw->irq >= 0)
+		devm_free_irq(&pdev->dev, hw->irq, hw);
+
 	watchdog_unregister_device(&hw->wdd);
 	clk_disable_unprepare(hw->clk);
 	return 0;
-- 
2.1.4

-- 
Simon Arlott
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2015-11-25 23:04 UTC|newest]

Thread overview: 95+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-21 19:02 [PATCH 1/4] clocksource: Add brcm,bcm6345-timer device tree binding Simon Arlott
2015-11-21 19:02 ` Simon Arlott
2015-11-21 19:03 ` [PATCH 2/4] MIPS: bmips: Add bcm6345-l2-timer interrupt controller Simon Arlott
2015-11-21 19:04 ` [PATCH 3/4] watchdog: Add brcm,bcm6345-wdt device tree binding Simon Arlott
2015-11-22 22:13   ` Rob Herring
2015-11-22 22:13     ` Rob Herring
2015-11-21 19:05 ` [PATCH 4/4] MIPS: bmips: Convert bcm63xx_wdt to use WATCHDOG_CORE Simon Arlott
2015-11-21 19:05   ` Simon Arlott
2015-11-21 21:32   ` Guenter Roeck
2015-11-21 21:44     ` Simon Arlott
2015-11-21 21:44       ` Simon Arlott
2015-11-22  2:32       ` Guenter Roeck
2015-11-22 14:02         ` [PATCH 4/10] (Was: [PATCH 4/4]) " Simon Arlott
2015-11-22 14:05           ` [PATCH 4/10] watchdog: bcm63xx_wdt: Handle hardware interrupt and remove software timer Simon Arlott
2015-11-24 18:21             ` Guenter Roeck
2015-11-24 18:21               ` Guenter Roeck
2015-11-24 18:21               ` Guenter Roeck
2015-11-25 20:14               ` Jonas Gorski
2015-11-25 20:14                 ` Jonas Gorski
2015-11-25 20:28                 ` Simon Arlott
2015-11-25 20:28                   ` Simon Arlott
2015-11-25 22:33             ` [PATCH (v2) " Simon Arlott
2015-11-25 22:33               ` Simon Arlott
2015-11-22 14:06           ` [PATCH 5/10] watchdog: bcm63xx_wdt: Use WATCHDOG_CORE Simon Arlott
2015-11-22 14:06             ` Simon Arlott
2015-11-25  2:44             ` Guenter Roeck
2015-11-25  2:44               ` Guenter Roeck
2015-11-25 13:02               ` Simon Arlott
2015-11-25 14:10                 ` Guenter Roeck
2015-11-25 14:10                   ` Guenter Roeck
2015-11-25 19:43                   ` Simon Arlott
2015-11-25 19:43                     ` Simon Arlott
2015-11-25 22:40               ` [PATCH (v3) 5/11] " Simon Arlott
2015-11-25 22:40                 ` Simon Arlott
2015-11-22 14:07           ` [PATCH 6/10] watchdog: bcm63xx_wdt: Obtain watchdog clock HZ from "periph" clk Simon Arlott
2015-11-22 14:07             ` Simon Arlott
2015-11-23 15:02             ` Jonas Gorski
2015-11-23 15:02               ` Jonas Gorski
2015-11-23 18:19               ` Florian Fainelli
2015-11-23 18:19                 ` Florian Fainelli
2015-11-23 19:00                 ` Simon Arlott
2015-11-23 19:00                   ` Simon Arlott
2015-11-24 22:12             ` [PATCH (v2) " Simon Arlott
2015-11-24 22:42               ` Florian Fainelli
2015-11-24 22:42                 ` Florian Fainelli
2015-11-25 22:47                 ` [PATCH (v3) 6/11] " Simon Arlott
2015-11-25 22:47                   ` Simon Arlott
2015-11-22 14:09           ` [PATCH 7/10] watchdog: bcm63xx_wdt: Add get_timeleft function Simon Arlott
2015-11-22 14:09             ` Simon Arlott
2015-11-24 22:15             ` [PATCH (v2) " Simon Arlott
2015-11-24 22:15               ` Simon Arlott
2015-11-24 22:43               ` Florian Fainelli
2015-11-24 22:43                 ` Florian Fainelli
2015-11-25  2:51               ` Guenter Roeck
2015-11-25  2:51                 ` Guenter Roeck
2015-11-25  8:17                 ` Simon Arlott
2015-11-25  8:17                   ` Simon Arlott
2015-11-25 22:50                   ` [PATCH (v3) 7/11] " Simon Arlott
2015-11-25 22:50                     ` Simon Arlott
2015-11-25 22:54                     ` [PATCH (v4) " Simon Arlott
2015-11-25 22:54                       ` Simon Arlott
2015-11-25 22:57                       ` [PATCH (v4) 8/11] watchdog: bcm63xx_wdt: Warn if the watchdog is currently running Simon Arlott
2015-11-25 22:57                         ` Simon Arlott
2015-11-22 14:11           ` [PATCH 8/10] watchdog: bcm63xx_wdt: Remove dependency on mach-bcm63xx functions/defines Simon Arlott
2015-11-22 14:11             ` Simon Arlott
2015-11-22 14:12           ` [PATCH 9/10] watchdog: bcm63xx_wdt: Use bcm63xx_timer interrupt directly Simon Arlott
2015-11-22 14:12             ` Simon Arlott
2015-11-25 23:03             ` Simon Arlott [this message]
2015-11-25 23:03               ` [PATCH (v2) 10/11] " Simon Arlott
2015-11-22 14:14           ` [PATCH 10/10] watchdog: bcm63xx_wdt: Use brcm,bcm6345-wdt device tree binding Simon Arlott
2015-11-22 14:14             ` Simon Arlott
2015-11-25 23:09             ` [PATCH (v2) 11/11] " Simon Arlott
2015-11-25 23:09               ` Simon Arlott
2015-11-22 22:12 ` [PATCH 1/4] clocksource: Add brcm,bcm6345-timer " Rob Herring
2015-11-23 15:33 ` Jonas Gorski
2015-11-23 18:55   ` [PATCH (v2) 1/10] " Simon Arlott
2015-11-23 18:55     ` Simon Arlott
2015-11-23 18:57     ` [PATCH (v2) 2/10] MIPS: bmips: Add bcm6345-l2-timer interrupt controller Simon Arlott
2015-11-23 18:57       ` Simon Arlott
2015-11-24 22:10       ` [PATCH (v3) " Simon Arlott
2015-11-24 22:10         ` Simon Arlott
2015-11-24 22:36         ` Florian Fainelli
2015-11-24 22:36           ` Florian Fainelli
2015-11-26 22:32           ` [PATCH (v4) 2/11] " Simon Arlott
2015-11-27  8:37             ` Thomas Gleixner
2015-11-27  8:37               ` Thomas Gleixner
2015-11-28 12:26               ` [PATCH (v5) 3/11] " Simon Arlott
2015-11-28 12:26                 ` Simon Arlott
2015-12-01  0:22                 ` Guenter Roeck
2015-12-01  0:22                   ` Guenter Roeck
2016-05-09 12:01                   ` Álvaro Fernández Rojas
2016-05-09 13:06                     ` Guenter Roeck
2016-05-09 13:06                       ` Guenter Roeck
2016-05-11  6:40                       ` [PATCH 2/4] " Álvaro Fernández Rojas
2015-11-25  3:05     ` [PATCH (v2) 1/10] clocksource: Add brcm,bcm6345-timer device tree binding Rob Herring

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=56563E55.3060109@simon.arlott.org.uk \
    --to=simon@fire.lp0.eu \
    --cc=cernekee@gmail.com \
    --cc=devicetree@vger.kernel.org \
    --cc=f.fainelli@gmail.com \
    --cc=galak@codeaurora.org \
    --cc=ijc+devicetree@hellion.org.uk \
    --cc=jason@lakedaemon.net \
    --cc=jogo@openwrt.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mips@linux-mips.org \
    --cc=linux-watchdog@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=marc.zyngier@arm.com \
    --cc=mark.rutland@arm.com \
    --cc=mbizon@freebox.fr \
    --cc=pawel.moll@arm.com \
    --cc=ralf@linux-mips.org \
    --cc=robh+dt@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=wim@iguana.be \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.