diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index c404b61..102d706 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -164,7 +164,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
 	/* Init pie timer */
 	hrtimer_init(&rtc->pie_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 	rtc->pie_timer.function = rtc_pie_update_irq;
-	rtc->pie_enabled = 0;
+	rtc->pie_emul_enabled = 0;
 
 	strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
 	dev_set_name(&rtc->dev, "rtc%d", id);
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index cb2f072..6d5aa3b 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -450,16 +450,25 @@ 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);
+		rtc->pie_emul_enabled = 0;
 	} 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_emul_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,9 +496,16 @@ 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) {
+		if (rtc->pie_emul_enabled) {
 			ktime_t period;
 			hrtimer_cancel(&rtc->pie_timer);
 			period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq);
@@ -497,6 +513,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;
 }
diff --git a/include/linux/rtc.h b/include/linux/rtc.h
index 89c3e51..b2c0a62 100644
--- a/include/linux/rtc.h
+++ b/include/linux/rtc.h
@@ -201,7 +201,7 @@ struct rtc_device
 	struct rtc_timer aie_timer;
 	struct rtc_timer uie_rtctimer;
 	struct hrtimer pie_timer; /* sub second exp, so needs hrtimer */
-	int pie_enabled;
+	int pie_emul_enabled;
 	struct work_struct irqwork;
 
 
