aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2006-07-12 12:03:10 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-07-12 15:52:55 -0400
commit0f74964627e0ece4ac8da0e2cd01906ec322b4fe (patch)
treea01f8d194ad1d9b3f921826f37b09efaff3a8662
parenta29b0b74e73b66674d20a170e463fe9032f2272a (diff)
[PATCH] lockdep: HPET/RTC fix
Joseph Fannin reported that hpet_rtc_interrupt() enables hardirqs in irq context: [ 25.628000] [<c014af4e>] trace_hardirqs_on+0xce/0x200 [ 25.628000] [<c036cf21>] _spin_unlock_irq+0x31/0x70 [ 25.628000] [<c0296584>] rtc_get_rtc_time+0x44/0x1a0 [ 25.628000] [<c01198bb>] hpet_rtc_interrupt+0x21b/0x280 [ 25.628000] [<c0161141>] handle_IRQ_event+0x31/0x70 [ 25.628000] [<c0162d37>] handle_edge_irq+0xe7/0x210 [ 25.628000] [<c0106192>] do_IRQ+0x92/0x120 [ 25.628000] [<c0104121>] common_interrupt+0x25/0x2c the call of rtc_get_rtc_time() is highly suspect. At a minimum we need the patch below to save/restore hardirq state. Signed-off-by: Ingo Molnar <mingo@elte.hu> Cc: Joseph Fannin <jfannin@gmail.com> Cc: John Stultz <johnstul@us.ibm.com> Cc: Arjan van de Ven <arjan@linux.intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/char/rtc.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 6ccc364c08df..6e6a7c7a7eff 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -1245,7 +1245,7 @@ static int rtc_proc_open(struct inode *inode, struct file *file)
1245 1245
1246void rtc_get_rtc_time(struct rtc_time *rtc_tm) 1246void rtc_get_rtc_time(struct rtc_time *rtc_tm)
1247{ 1247{
1248 unsigned long uip_watchdog = jiffies; 1248 unsigned long uip_watchdog = jiffies, flags;
1249 unsigned char ctrl; 1249 unsigned char ctrl;
1250#ifdef CONFIG_MACH_DECSTATION 1250#ifdef CONFIG_MACH_DECSTATION
1251 unsigned int real_year; 1251 unsigned int real_year;
@@ -1272,7 +1272,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
1272 * RTC has RTC_DAY_OF_WEEK, we should usually ignore it, as it is 1272 * RTC has RTC_DAY_OF_WEEK, we should usually ignore it, as it is
1273 * only updated by the RTC when initially set to a non-zero value. 1273 * only updated by the RTC when initially set to a non-zero value.
1274 */ 1274 */
1275 spin_lock_irq(&rtc_lock); 1275 spin_lock_irqsave(&rtc_lock, flags);
1276 rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS); 1276 rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
1277 rtc_tm->tm_min = CMOS_READ(RTC_MINUTES); 1277 rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
1278 rtc_tm->tm_hour = CMOS_READ(RTC_HOURS); 1278 rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
@@ -1286,7 +1286,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm)
1286 real_year = CMOS_READ(RTC_DEC_YEAR); 1286 real_year = CMOS_READ(RTC_DEC_YEAR);
1287#endif 1287#endif
1288 ctrl = CMOS_READ(RTC_CONTROL); 1288 ctrl = CMOS_READ(RTC_CONTROL);
1289 spin_unlock_irq(&rtc_lock); 1289 spin_unlock_irqrestore(&rtc_lock, flags);
1290 1290
1291 if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) 1291 if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
1292 { 1292 {