[PATCH] rtc class locking bugfixes

I got a lockdep warning when running "rtctest" so I though it'd be good
to see what was up.

 - The warning was for rtc->irq_task_lock, gotten from rtc_update_irq()
   by irq handlerss ... but in a handful of other cases, grabbed without
   blocking IRQs.

 - Some callers to rtc_update_irq() were not ensuring IRQs were blocked,
   yet the routine expects that; make sure all callers block IRQs.

It would appear that RTC API tests haven't been part of anyone's kernel
regression test suite recently, at least not with lockdep running.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Acked-by: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 3109865..814b9e1 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -61,7 +61,9 @@
 	int err;
 
 	err = rtc_read_time(&rtc->class_dev, &tm);
-	spin_lock_irq(&rtc->irq_lock);
+
+	local_irq_disable();
+	spin_lock(&rtc->irq_lock);
 	if (rtc->stop_uie_polling || err) {
 		rtc->uie_task_active = 0;
 	} else if (rtc->oldsecs != tm.tm_sec) {
@@ -74,11 +76,11 @@
 	} else if (schedule_work(&rtc->uie_task) == 0) {
 		rtc->uie_task_active = 0;
 	}
-	spin_unlock_irq(&rtc->irq_lock);
+	spin_unlock(&rtc->irq_lock);
 	if (num)
 		rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF);
+	local_irq_enable();
 }
-
 static void rtc_uie_timer(unsigned long data)
 {
 	struct rtc_device *rtc = (struct rtc_device *)data;
@@ -238,10 +240,10 @@
 
 	/* avoid conflicting IRQ users */
 	if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) {
-		spin_lock(&rtc->irq_task_lock);
+		spin_lock_irq(&rtc->irq_task_lock);
 		if (rtc->irq_task)
 			err = -EBUSY;
-		spin_unlock(&rtc->irq_task_lock);
+		spin_unlock_irq(&rtc->irq_task_lock);
 
 		if (err < 0)
 			return err;