Patchwork RTC: Selectively enable PIE-Hrtimer emulation.

login
register
mail settings
Submitter MyungJoo Ham
Date March 8, 2011, 6:58 a.m.
Message ID <1299567514-23375-1-git-send-email-myungjoo.ham@samsung.com>
Download mbox | patch
Permalink /patch/85926/
State New
Headers show

Comments

MyungJoo Ham - March 8, 2011, 6:58 a.m.
The patch of John Stultz, "RTC: Rework RTC code to use timerqueue for
events", enables PIE interrupt emulation with hrtimer unconditionally.
However, we do have RTC devices that support PIE and such devices are
not meant to be emulated by hrtimer.

This patch allows not to use the PIE emulation if the rtc device driver
has implemented PIE related features. Currently, rtc-s3c, rtc-cmos,
rtc-davinci, rtc-pl031, rtc-pxa, rtc-sa1100, rtc-sh, and rtc-vt41xx have
them.

Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/rtc/interface.c |   30 +++++++++++++++++++++++-------
 1 files changed, 23 insertions(+), 7 deletions(-)

Patch

diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index cb2f072..f2f1c9c 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -450,16 +450,24 @@  int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled
 		err = -EBUSY;
 	if (rtc->irq_task != task)
 		err = -EACCES;
+	if (err)
+		goto out;
 
-	if (enabled) {
-		ktime_t period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq);
-		hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL);
+	if (rtc->ops->irq_set_state) {
+		err = rtc->ops->irq_set_state(rtc->dev.parent, enabled);
 	} else {
-		hrtimer_cancel(&rtc->pie_timer);
+		if (enabled) {
+			ktime_t period = ktime_set(0, NSEC_PER_SEC /
+							rtc->irq_freq);
+			hrtimer_start(&rtc->pie_timer, period,
+					HRTIMER_MODE_REL);
+		} else {
+			hrtimer_cancel(&rtc->pie_timer);
+		}
+		rtc->pie_enabled = enabled;
 	}
-	rtc->pie_enabled = enabled;
+out:
 	spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
-
 	return err;
 }
 EXPORT_SYMBOL_GPL(rtc_irq_set_state);
@@ -487,7 +495,14 @@  int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
 		err = -EBUSY;
 	if (rtc->irq_task != task)
 		err = -EACCES;
-	if (err == 0) {
+	if (err)
+		goto out;
+
+	if (rtc->ops->irq_set_freq) {
+		err = rtc->ops->irq_set_freq(rtc->dev.parent, freq);
+		if (err == 0)
+			rtc->irq_freq = freq;
+	} else {
 		rtc->irq_freq = freq;
 		if (rtc->pie_enabled) {
 			ktime_t period;
@@ -497,6 +512,7 @@  int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
 					HRTIMER_MODE_REL);
 		}
 	}
+out:
 	spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
 	return err;
 }