Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 4021

kernel-2.6.18-194.11.1.el5.src.rpm

From: Brian Maly <bmaly@redhat.com>
Subject: Re: [RHEL5.1 patch] rtc support for HPET legacy replacement mode
Date: Thu, 14 Jun 2007 11:52:39 -0400
Bugzilla: 220196
Message-Id: <46716447.5060701@redhat.com>
Changelog: [x86] rtc support for HPET legacy replacement mode


Don Zickus wrote:
>On Wed, Jun 06, 2007 at 08:43:03PM -0400, Brian Maly wrote:
>  
>>resolves BZ 220196
>>
>>The IBM x460/x3950 platform does not support HPET Legacy Replacement 
>>mode for rtc. With HPET enabled, the RTC driver currently doesn't 
>>correctly handle legacy replacement mode in its HPET emulation code. 
>>This is a generic issue and a patch is being developed to submit upstream.
>>
>>When an HPET is present the RTC driver relies on the HPET's capabality 
>>to emulate update/periodic/alarm interrupts for the RTC. This is 
>>necessary when the HPET operates in legacy replacement mode where the 
>>RTC interrupt line is not connected. However if the HPET is not in 
>>legacy replacement mode the RTC still has its own interrupt line 
>>connected and is expected to generate its own interrupts. Currently the 
>>RTC driver checks for the presence of an HPET using the 
>>is_hpet_enabled() function. In cases where the HPET is not in legacy 
>>replacement mode this leads to no RTC interrupts being generated at all 
>>and to the failure of commands that rely on them such as hwclock. The 
>>attached patch addresses this situation by having the RTC check for
>>the presence of an HPET and for legacy replacement support. It does so 
>>through the introduction of a new function is_hpet_legacy_int_enabled() 
>>which is used only in conjuction with the HPET RTC emulation code.  The 
>>patch fixes a problem that affects all systems that use an HPET and 
>>where the HPET doesn't use the Legacy Replacement option for interrupt 
>>mapping.
>>
>>
>>Ive tested that this patch works on out x460, and IBM completed in house 
>>testing of this patch on affected hardware without any problems.
>>    
>

--- linux-2.6.18.noarch/arch/x86_64/kernel/time.c.orig	2007-06-06 13:21:54.000000000 -0400
+++ linux-2.6.18.noarch/arch/x86_64/kernel/time.c	2007-06-06 14:24:47.000000000 -0400
@@ -1166,6 +1166,11 @@ int is_hpet_enabled(void)
 	return vxtime.hpet_address != 0;
 }
 
+int is_hpet_legacy_int_enabled()
+{
+	return (is_hpet_enabled() && hpet_use_timer);
+}
+
 /*
  * Timer 1 for RTC, we do not use periodic interrupt feature,
  * even if HPET supports periodic interrupts on Timer 1.
@@ -1182,7 +1187,7 @@ int hpet_rtc_timer_init(void)
 	unsigned int cfg, cnt;
 	unsigned long flags;
 
-	if (!is_hpet_enabled())
+	if (!is_hpet_legacy_int_enabled())
 		return 0;
 	/*
 	 * Set the counter 1 and enable the interrupts.
@@ -1237,7 +1242,7 @@ static void hpet_rtc_timer_reinit(void)
  */
 int hpet_mask_rtc_irq_bit(unsigned long bit_mask)
 {
-	if (!is_hpet_enabled())
+	if (!is_hpet_legacy_int_enabled())
 		return 0;
 
 	if (bit_mask & RTC_UIE)
@@ -1254,7 +1259,7 @@ int hpet_set_rtc_irq_bit(unsigned long b
 {
 	int timer_init_reqd = 0;
 
-	if (!is_hpet_enabled())
+	if (!is_hpet_legacy_int_enabled())
 		return 0;
 
 	if (!(PIE_on | AIE_on | UIE_on))
@@ -1279,7 +1284,7 @@ int hpet_set_rtc_irq_bit(unsigned long b
 
 int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec)
 {
-	if (!is_hpet_enabled())
+	if (!is_hpet_legacy_int_enabled())
 		return 0;
 
 	alarm_time.tm_hour = hrs;
@@ -1291,7 +1296,7 @@ int hpet_set_alarm_time(unsigned char hr
 
 int hpet_set_periodic_freq(unsigned long freq)
 {
-	if (!is_hpet_enabled())
+	if (!is_hpet_legacy_int_enabled())
 		return 0;
 
 	PIE_freq = freq;
@@ -1302,7 +1307,7 @@ int hpet_set_periodic_freq(unsigned long
 
 int hpet_rtc_dropped_irq(void)
 {
-	if (!is_hpet_enabled())
+	if (!is_hpet_legacy_int_enabled())
 		return 0;
 
 	return 1;
--- linux-2.6.18.noarch/arch/i386/kernel/time_hpet.c.orig	2007-06-06 13:21:47.000000000 -0400
+++ linux-2.6.18.noarch/arch/i386/kernel/time_hpet.c	2007-06-06 14:24:47.000000000 -0400
@@ -224,6 +224,11 @@ int is_hpet_enabled(void)
 	return use_hpet;
 }
 
+int is_hpet_legacy_int_enabled()
+{
+	return (is_hpet_enabled() && hpet_use_timer);
+}
+
 int is_hpet_capable(void)
 {
 	if (!boot_hpet_disable && hpet_address)
@@ -292,7 +297,7 @@ int hpet_rtc_timer_init(void)
 	unsigned int cfg, cnt;
 	unsigned long flags;
 
-	if (!is_hpet_enabled())
+	if (!is_hpet_legacy_int_enabled())
 		return 0;
 	/*
 	 * Set the counter 1 and enable the interrupts.
@@ -347,7 +352,7 @@ static void hpet_rtc_timer_reinit(void)
  */
 int hpet_mask_rtc_irq_bit(unsigned long bit_mask)
 {
-	if (!is_hpet_enabled())
+	if (!is_hpet_legacy_int_enabled())
 		return 0;
 
 	if (bit_mask & RTC_UIE)
@@ -364,7 +369,7 @@ int hpet_set_rtc_irq_bit(unsigned long b
 {
 	int timer_init_reqd = 0;
 
-	if (!is_hpet_enabled())
+	if (!is_hpet_legacy_int_enabled())
 		return 0;
 
 	if (!(PIE_on | AIE_on | UIE_on))
@@ -389,7 +394,7 @@ int hpet_set_rtc_irq_bit(unsigned long b
 
 int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec)
 {
-	if (!is_hpet_enabled())
+	if (!is_hpet_legacy_int_enabled())
 		return 0;
 
 	alarm_time.tm_hour = hrs;
@@ -401,7 +406,7 @@ int hpet_set_alarm_time(unsigned char hr
 
 int hpet_set_periodic_freq(unsigned long freq)
 {
-	if (!is_hpet_enabled())
+	if (!is_hpet_legacy_int_enabled())
 		return 0;
 
 	PIE_freq = freq;
@@ -412,7 +417,7 @@ int hpet_set_periodic_freq(unsigned long
 
 int hpet_rtc_dropped_irq(void)
 {
-	if (!is_hpet_enabled())
+	if (!is_hpet_legacy_int_enabled())
 		return 0;
 
 	return 1;
--- linux-2.6.18.noarch/drivers/char/rtc.c.orig	2007-06-06 14:23:50.000000000 -0400
+++ linux-2.6.18.noarch/drivers/char/rtc.c	2007-06-06 14:24:47.000000000 -0400
@@ -106,7 +106,7 @@ static int rtc_has_irq = 1;
 #endif
 
 #ifndef CONFIG_HPET_EMULATE_RTC
-#define is_hpet_enabled()			0
+#define is_hpet_legacy_int_enabled()		0
 #define hpet_set_alarm_time(hrs, min, sec) 	0
 #define hpet_set_periodic_freq(arg) 		0
 #define hpet_mask_rtc_irq_bit(arg) 		0
@@ -241,7 +241,7 @@ irqreturn_t rtc_interrupt(int irq, void 
 	spin_lock (&rtc_lock);
 	rtc_irq_data += 0x100;
 	rtc_irq_data &= ~0xff;
-	if (is_hpet_enabled()) {
+	if (is_hpet_legacy_int_enabled()) {
 		/*
 		 * In this case it is HPET RTC interrupt handler
 		 * calling us, with the interrupt information
@@ -988,7 +988,7 @@ no_irq:
 	}
 
 #ifdef RTC_IRQ
-	if (is_hpet_enabled()) {
+	if (is_hpet_legacy_int_enabled()) {
 		rtc_int_handler_ptr = hpet_rtc_interrupt;
 	} else {
 		rtc_int_handler_ptr = rtc_interrupt;
--- linux-2.6.18.noarch/include/asm-x86_64/hpet.h.orig	2007-06-06 14:24:07.000000000 -0400
+++ linux-2.6.18.noarch/include/asm-x86_64/hpet.h	2007-06-06 14:24:47.000000000 -0400
@@ -54,6 +54,7 @@
 #define HPET_TICK_RATE (HZ * 100000UL)
 
 extern int is_hpet_enabled(void);
+extern int is_hpet_legacy_int_enabled(void);
 extern int hpet_rtc_timer_init(void);
 extern int apic_is_clustered_box(void);
 
--- linux-2.6.18.noarch/include/asm-i386/hpet.h.orig	2007-06-06 14:24:00.000000000 -0400
+++ linux-2.6.18.noarch/include/asm-i386/hpet.h	2007-06-06 14:24:47.000000000 -0400
@@ -98,6 +98,7 @@ extern int hpet_rtc_timer_init(void);
 extern int hpet_enable(void);
 extern int hpet_reenable(void);
 extern int is_hpet_enabled(void);
+extern int is_hpet_legacy_int_enabled(void);
 extern int is_hpet_capable(void);
 extern int hpet_readl(unsigned long a);