All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] rtc: twl: Use threaded IRQ, remove IRQ enable in interrupt handler
@ 2011-07-27  7:07 Todd Poynor
  2011-07-27  7:07 ` [PATCH 2/2] rtc: twl: Fix registration vs. init order Todd Poynor
  0 siblings, 1 reply; 2+ messages in thread
From: Todd Poynor @ 2011-07-27  7:07 UTC (permalink / raw)
  To: Alessandro Zummo; +Cc: rtc-linux, linux-omap, linux-kernel, Todd Poynor

IRQs disabled on entry to twl_rtc_interrupt is not a consequence
of LOCKDEP; both twl6030 and twl4030 explicitly disable IRQs
before calling the module IRQ handlers.

The ISR should not be enabling IRQs; use a threaded IRQ handler
instead.

Also fixes warnings:

  WARNING: at kernel/irq/handle.c:130 handle_irq_event_percpu+nnn
  irq nnn handler twl_rtc_interrupt+nnn enabled interrupts

Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
 drivers/rtc/rtc-twl.c |   14 +++-----------
 1 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index 9a81f77..ece41b9 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -362,14 +362,6 @@ static irqreturn_t twl_rtc_interrupt(int irq, void *rtc)
 	int res;
 	u8 rd_reg;
 
-#ifdef CONFIG_LOCKDEP
-	/* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
-	 * we don't want and can't tolerate.  Although it might be
-	 * friendlier not to borrow this thread context...
-	 */
-	local_irq_enable();
-#endif
-
 	res = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
 	if (res)
 		goto out;
@@ -462,9 +454,9 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto out1;
 
-	ret = request_irq(irq, twl_rtc_interrupt,
-				IRQF_TRIGGER_RISING,
-				dev_name(&rtc->dev), rtc);
+	ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
+				   IRQF_TRIGGER_RISING,
+				   dev_name(&rtc->dev), rtc);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "IRQ is not free.\n");
 		goto out1;
-- 
1.7.3.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH 2/2] rtc: twl: Fix registration vs. init order
  2011-07-27  7:07 [PATCH 1/2] rtc: twl: Use threaded IRQ, remove IRQ enable in interrupt handler Todd Poynor
@ 2011-07-27  7:07 ` Todd Poynor
  0 siblings, 0 replies; 2+ messages in thread
From: Todd Poynor @ 2011-07-27  7:07 UTC (permalink / raw)
  To: Alessandro Zummo; +Cc: rtc-linux, linux-omap, linux-kernel, Todd Poynor

Only register as an RTC device after the hardware has been
successfully initialized.  The RTC class driver will call
back to this driver to read a pending alarm, and other
drivers watching for new devices on the RTC class may
read the RTC time upon registration.  Such access might
occur while the RTC is stopped, prior to clearing
pending alarms, etc.

The new ordering also avoids leaving the platform
device drvdata set to an unregistered struct rtc_device *
on probe errors.

Signed-off-by: Todd Poynor <toddpoynor@google.com>
---
 drivers/rtc/rtc-twl.c |   52 ++++++++++++++++++++++--------------------------
 1 files changed, 24 insertions(+), 28 deletions(-)

diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
index ece41b9..20687d5 100644
--- a/drivers/rtc/rtc-twl.c
+++ b/drivers/rtc/rtc-twl.c
@@ -420,24 +420,12 @@ static struct rtc_class_ops twl_rtc_ops = {
 static int __devinit twl_rtc_probe(struct platform_device *pdev)
 {
 	struct rtc_device *rtc;
-	int ret = 0;
+	int ret = -EINVAL;
 	int irq = platform_get_irq(pdev, 0);
 	u8 rd_reg;
 
 	if (irq <= 0)
-		return -EINVAL;
-
-	rtc = rtc_device_register(pdev->name,
-				  &pdev->dev, &twl_rtc_ops, THIS_MODULE);
-	if (IS_ERR(rtc)) {
-		ret = PTR_ERR(rtc);
-		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
-			PTR_ERR(rtc));
-		goto out0;
-
-	}
-
-	platform_set_drvdata(pdev, rtc);
+		goto out1;
 
 	ret = twl_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
 	if (ret < 0)
@@ -454,14 +442,6 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto out1;
 
-	ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
-				   IRQF_TRIGGER_RISING,
-				   dev_name(&rtc->dev), rtc);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "IRQ is not free.\n");
-		goto out1;
-	}
-
 	if (twl_class_is_6030()) {
 		twl6030_interrupt_unmask(TWL6030_RTC_INT_MASK,
 			REG_INT_MSK_LINE_A);
@@ -472,28 +452,44 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev)
 	/* Check RTC module status, Enable if it is off */
 	ret = twl_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
 	if (ret < 0)
-		goto out2;
+		goto out1;
 
 	if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
 		dev_info(&pdev->dev, "Enabling TWL-RTC.\n");
 		rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
 		ret = twl_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
 		if (ret < 0)
-			goto out2;
+			goto out1;
 	}
 
 	/* init cached IRQ enable bits */
 	ret = twl_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
 	if (ret < 0)
+		goto out1;
+
+	rtc = rtc_device_register(pdev->name,
+				  &pdev->dev, &twl_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc)) {
+		ret = PTR_ERR(rtc);
+		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
+			PTR_ERR(rtc));
+		goto out1;
+	}
+
+	ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt,
+				   IRQF_TRIGGER_RISING,
+				   dev_name(&rtc->dev), rtc);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "IRQ is not free.\n");
 		goto out2;
+	}
 
-	return ret;
+	platform_set_drvdata(pdev, rtc);
+	return 0;
 
 out2:
-	free_irq(irq, rtc);
-out1:
 	rtc_device_unregister(rtc);
-out0:
+out1:
 	return ret;
 }
 
-- 
1.7.3.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-07-27  7:08 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-27  7:07 [PATCH 1/2] rtc: twl: Use threaded IRQ, remove IRQ enable in interrupt handler Todd Poynor
2011-07-27  7:07 ` [PATCH 2/2] rtc: twl: Fix registration vs. init order Todd Poynor

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.