linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Pallipadi, Venkatesh" <venkatesh.pallipadi@intel.com>
To: "Andrew Morton" <akpm@osdl.org>
Cc: <torvalds@osdl.org>, <linux-kernel@vger.kernel.org>,
	"Nakajima, Jun" <jun.nakajima@intel.com>
Subject: RE: [PATCHSET][2.6-test4][0/6]Support for HPET based timer - Take 2
Date: Fri, 29 Aug 2003 16:58:56 -0700	[thread overview]
Message-ID: <C8C38546F90ABF408A5961FC01FDBF1902C7D224@fmsmsx405.fm.intel.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1256 bytes --]




> -----Original Message-----
> From: Andrew Morton [mailto:akpm@osdl.org] 
> 
> We seem to keep on proliferating home-grown x86 64-bit math functions.
> 
> Do you really need these?  Is it possible to use do_div() and 
> the C 64x64
> `*' operator instead?
> 


We can change these handcoded 64 bit divs to do_div, with just an
additional data copy 
(as do_div changes dividend in place). But, changing mul into 64x64 '*'
may be tricky. 
Gcc seem to generate a combination of mul, 2imul and add, where as we
are happy with 
using only one mull here.

> 
> I'd like the rtc emulation patch to be redone to remove the 
> ifdefs please,
> they're a real eyesore.
> 
> At the top of rtc.c, do something like this:
> 
> #ifndef CONFIG_HPET_EMULATE_RTC
> #define is_hpet_enabled() 0
> #define hpet_set_alarm_time(hrs, min, sec) 0
> #define hpet_set_periodic_freq(arg) 0
> static inline int hpet_mask_rtc_irq_bit(int arg) { return 0; }
> #define hpet_rtc_timer_init() do { } while (0)
> #define hpet_rtc_dropped_irq() 0
> #endif
> 
> And then all those eleven ifdefs can be removed from rtc.c.


Yes. That surely makes the patch lot more cleaner. Attached is the
updated rtc 
emulation patch.

Thanks,
-Venkatesh

[-- Attachment #2: hpet06_new.patch --]
[-- Type: application/octet-stream, Size: 14753 bytes --]

diff -purN linux-2.6.0-test4-hpetnortc/arch/i386/kernel/time_hpet.c linux-2.6.0-test4-hpet/arch/i386/kernel/time_hpet.c
--- linux-2.6.0-test4-hpetnortc/arch/i386/kernel/time_hpet.c	2003-08-29 17:56:48.000000000 -0700
+++ linux-2.6.0-test4-hpet/arch/i386/kernel/time_hpet.c	2003-08-28 16:20:50.000000000 -0700
@@ -168,4 +168,225 @@ static int __init hpet_setup(char* str)
 
 __setup("hpet=", hpet_setup);
 
+#ifdef CONFIG_HPET_EMULATE_RTC
+/* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET 
+ * is enabled, we support RTC interrupt functionality in software. 
+ * RTC has 3 kinds of interrupts:
+ * 1) Update Interrupt - generate an interrupt, every sec, when RTC clock
+ *    is updated
+ * 2) Alarm Interrupt - generate an interrupt at a specific time of day
+ * 3) Periodic Interrupt - generate periodic interrupt, with frequencies
+ *    2Hz-8192Hz (2Hz-64Hz for non-root user) (all freqs in powers of 2)
+ * (1) and (2) above are implemented using polling at a frequency of 
+ * 64 Hz. The exact frequency is a tradeoff between accuracy and interrupt
+ * overhead. (DEFAULT_RTC_INT_FREQ)
+ * For (3), we use interrupts at 64Hz or user specified periodic 
+ * frequency, whichever is higher.
+ */
+#include <linux/mc146818rtc.h>
+#include <linux/rtc.h>
+
+extern irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+extern void get_rtc_time(struct rtc_time *rtc_tm);
+
+#define DEFAULT_RTC_INT_FREQ 	64
+#define RTC_NUM_INTS 		1
+
+static unsigned long UIE_on;
+static unsigned long prev_update_sec;
+
+static unsigned long AIE_on;
+static struct rtc_time alarm_time;
+
+static unsigned long PIE_on;
+static unsigned long PIE_freq = DEFAULT_RTC_INT_FREQ;
+static unsigned long PIE_count;
+
+static unsigned long hpet_rtc_int_freq; /* RTC interrupt frequency */
+
+/*
+ * Timer 1 for RTC, we do not use periodic interrupt feature, 
+ * even if HPET supports periodic interrupts on Timer 1.
+ * The reason being, to set up a periodic interrupt in HPET, we need to 
+ * stop the main counter. And if we do that everytime someone diables/enables
+ * RTC, we will have adverse effect on main kernel timer running on Timer 0.
+ * So, for the time being, simulate the periodic interrupt in software.
+ * 
+ * hpet_rtc_timer_init() is called for the first time and during subsequent 
+ * interuppts reinit happens through hpet_rtc_timer_reinit().
+ */
+int hpet_rtc_timer_init(void)
+{
+	unsigned int cfg, cnt;
+	unsigned long flags;
+
+	if (!is_hpet_enabled())
+		return 0;
+	/*
+	 * Set the counter 1 and enable the interrupts.
+	 */
+	if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
+		hpet_rtc_int_freq = PIE_freq;
+	else
+		hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
+
+	local_irq_save(flags);
+	cnt = hpet_readl(HPET_COUNTER);
+	cnt += ((hpet_tick*HZ)/hpet_rtc_int_freq);
+	hpet_writel(cnt, HPET_T1_CMP);
+	local_irq_restore(flags);
+
+	cfg = hpet_readl(HPET_T1_CFG);
+	cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
+	hpet_writel(cfg, HPET_T1_CFG);
+
+	return 1;
+}
+
+static void hpet_rtc_timer_reinit(void)
+{
+	unsigned int cfg, cnt;
+
+	if (!(PIE_on | AIE_on | UIE_on))
+		return;
+
+	if (PIE_on && (PIE_freq > DEFAULT_RTC_INT_FREQ))
+		hpet_rtc_int_freq = PIE_freq;
+	else
+		hpet_rtc_int_freq = DEFAULT_RTC_INT_FREQ;
+
+	/* It is more accurate to use the comparator value than current count.*/
+	cnt = hpet_readl(HPET_T1_CMP);
+	cnt += hpet_tick*HZ/hpet_rtc_int_freq;
+	hpet_writel(cnt, HPET_T1_CMP);
+
+	cfg = hpet_readl(HPET_T1_CFG);
+	cfg |= HPET_TN_ENABLE | HPET_TN_SETVAL | HPET_TN_32BIT;
+	hpet_writel(cfg, HPET_T1_CFG);
+
+	return;
+}
+
+/* 
+ * The functions below are called from rtc driver. 
+ * Return 0 if HPET is not being used.
+ * Otherwise do the necessary changes and return 1.
+ */
+int hpet_mask_rtc_irq_bit(unsigned long bit_mask)
+{
+	if (!is_hpet_enabled())
+		return 0;
+
+	if (bit_mask & RTC_UIE)
+		UIE_on = 0;
+	if (bit_mask & RTC_PIE)
+		PIE_on = 0;
+	if (bit_mask & RTC_AIE)
+		AIE_on = 0;
+
+	return 1;
+}
+
+int hpet_set_rtc_irq_bit(unsigned long bit_mask)
+{
+	int timer_init_reqd = 0;
+
+	if (!is_hpet_enabled())
+		return 0;
+
+	if (!(PIE_on | AIE_on | UIE_on))
+		timer_init_reqd = 1;
+
+	if (bit_mask & RTC_UIE) {
+		UIE_on = 1;
+	}
+	if (bit_mask & RTC_PIE) {
+		PIE_on = 1;
+		PIE_count = 0;
+	}
+	if (bit_mask & RTC_AIE) {
+		AIE_on = 1;
+	}
+
+	if (timer_init_reqd)
+		hpet_rtc_timer_init();
+
+	return 1;
+}
+
+int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec)
+{
+	if (!is_hpet_enabled())
+		return 0;
+
+	alarm_time.tm_hour = hrs;
+	alarm_time.tm_min = min;
+	alarm_time.tm_sec = sec;
+
+	return 1;
+}
+
+int hpet_set_periodic_freq(unsigned long freq)
+{
+	if (!is_hpet_enabled())
+		return 0;
+
+	PIE_freq = freq;
+	PIE_count = 0;
+
+	return 1;
+}
+
+int hpet_rtc_dropped_irq(void)
+{
+	if (!is_hpet_enabled())
+		return 0;
+
+	return 1;
+}
+
+irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct rtc_time curr_time;
+	unsigned long rtc_int_flag = 0;
+	int call_rtc_interrupt = 0;
+
+	hpet_rtc_timer_reinit();
+
+	if (UIE_on | AIE_on) {
+		get_rtc_time(&curr_time);
+	}
+	if (UIE_on) {
+		if (curr_time.tm_sec != prev_update_sec) {
+			/* Set update int info, call real rtc int routine */
+			call_rtc_interrupt = 1;
+			rtc_int_flag = RTC_UF;
+			prev_update_sec = curr_time.tm_sec;
+		}
+	}
+	if (PIE_on) {
+		PIE_count++;
+		if (PIE_count >= hpet_rtc_int_freq/PIE_freq) {
+			/* Set periodic int info, call real rtc int routine */
+			call_rtc_interrupt = 1;
+			rtc_int_flag |= RTC_PF;
+			PIE_count = 0;
+		}
+	}
+	if (AIE_on) {
+		if ((curr_time.tm_sec == alarm_time.tm_sec) &&
+		    (curr_time.tm_min == alarm_time.tm_min) &&
+		    (curr_time.tm_hour == alarm_time.tm_hour)) {
+			/* Set alarm int info, call real rtc int routine */
+			call_rtc_interrupt = 1;
+			rtc_int_flag |= RTC_AF;
+		}
+	}
+	if (call_rtc_interrupt) {
+		rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8));
+		rtc_interrupt(rtc_int_flag, dev_id, regs);
+	}
+	return IRQ_HANDLED;
+}
+#endif
 
diff -purN linux-2.6.0-test4-hpetnortc/drivers/char/rtc.c linux-2.6.0-test4-hpet/drivers/char/rtc.c
--- linux-2.6.0-test4-hpetnortc/drivers/char/rtc.c	2003-08-29 17:56:48.000000000 -0700
+++ linux-2.6.0-test4-hpet/drivers/char/rtc.c	2003-08-29 17:06:24.000000000 -0700
@@ -44,10 +44,12 @@
  *      1.11    Takashi Iwai: Kernel access functions
  *			      rtc_register/rtc_unregister/rtc_control
  *      1.11a   Daniele Bellucci: Audit create_proc_read_entry in rtc_init
+ *	1.12	Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer
+ *		CONFIG_HPET_EMULATE_RTC
  *
  */
 
-#define RTC_VERSION		"1.11a"
+#define RTC_VERSION		"1.12"
 
 #define RTC_IO_EXTENT	0x8
 
@@ -80,6 +82,10 @@
 #include <asm/uaccess.h>
 #include <asm/system.h>
 
+#if defined(__i386__)
+#include <asm/hpet.h>
+#endif
+
 #ifdef __sparc__
 #include <linux/pci.h>
 #include <asm/ebus.h>
@@ -95,6 +101,17 @@ static int rtc_irq = PCI_IRQ_NONE;
 static int rtc_has_irq = 1;
 #endif
 
+#ifndef CONFIG_HPET_EMULATE_RTC
+#define is_hpet_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
+#define hpet_set_rtc_irq_bit(arg) 		0
+#define hpet_rtc_timer_init() 			do { } while (0)
+#define hpet_rtc_dropped_irq() 			0
+static inline irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) {return 0;}
+#endif
+
 /*
  *	We sponge a minor off of the misc major. No need slurping
  *	up another valuable major dev number for this. If you add
@@ -120,7 +137,7 @@ static int rtc_ioctl(struct inode *inode
 static unsigned int rtc_poll(struct file *file, poll_table *wait);
 #endif
 
-static void get_rtc_time (struct rtc_time *rtc_tm);
+void get_rtc_time (struct rtc_time *rtc_tm);
 static void get_rtc_alm_time (struct rtc_time *alm_tm);
 #if RTC_IRQ
 static void rtc_dropped_irq(unsigned long data);
@@ -182,7 +199,7 @@ static const unsigned char days_in_mo[] 
  *	(See ./arch/XXXX/kernel/time.c for the set_rtc_mmss() function.)
  */
 
-static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	/*
 	 *	Can be an alarm interrupt, update complete interrupt,
@@ -194,7 +211,16 @@ static irqreturn_t rtc_interrupt(int irq
 	spin_lock (&rtc_lock);
 	rtc_irq_data += 0x100;
 	rtc_irq_data &= ~0xff;
-	rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
+	if (is_hpet_enabled()) {
+		/*
+		 * In this case it is HPET RTC interrupt handler
+		 * calling us, with the interrupt information
+		 * passed as arg1, instead of irq.
+		 */
+		rtc_irq_data |= (unsigned long)irq & 0xF0;
+	} else {
+		rtc_irq_data |= (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
+	}
 
 	if (rtc_status & RTC_TIMER_ON)
 		mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
@@ -429,6 +455,12 @@ static int rtc_do_ioctl(unsigned int cmd
 		sec = alm_tm.tm_sec;
 
 		spin_lock_irq(&rtc_lock);
+		if (hpet_set_alarm_time(hrs, min, sec)) {
+			/*
+			 * Fallthru and set alarm time in CMOS too, 
+			 * so that we will get proper value in RTC_ALM_READ
+			 */
+		}
 		if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) ||
 		    RTC_ALWAYS_BCD)
 		{
@@ -582,6 +614,10 @@ static int rtc_do_ioctl(unsigned int cmd
 			return -EINVAL;
 
 		spin_lock_irq(&rtc_lock);
+		if (hpet_set_periodic_freq(arg)) {
+			spin_unlock_irq(&rtc_lock);
+			return 0;
+		}
 		rtc_freq = arg;
 
 		val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
@@ -667,13 +703,14 @@ static int rtc_release(struct inode *ino
 	 */
 
 	spin_lock_irq(&rtc_lock);
-	tmp = CMOS_READ(RTC_CONTROL);
-	tmp &=  ~RTC_PIE;
-	tmp &=  ~RTC_AIE;
-	tmp &=  ~RTC_UIE;
-	CMOS_WRITE(tmp, RTC_CONTROL);
-	CMOS_READ(RTC_INTR_FLAGS);
-
+	if (!hpet_mask_rtc_irq_bit(RTC_PIE | RTC_AIE | RTC_UIE)) {
+		tmp = CMOS_READ(RTC_CONTROL);
+		tmp &=  ~RTC_PIE;
+		tmp &=  ~RTC_AIE;
+		tmp &=  ~RTC_UIE;
+		CMOS_WRITE(tmp, RTC_CONTROL);
+		CMOS_READ(RTC_INTR_FLAGS);
+	}
 	if (rtc_status & RTC_TIMER_ON) {
 		rtc_status &= ~RTC_TIMER_ON;
 		del_timer(&rtc_irq_timer);
@@ -765,12 +802,14 @@ int rtc_unregister(rtc_task_t *task)
 	rtc_callback = NULL;
 	
 	/* disable controls */
-	tmp = CMOS_READ(RTC_CONTROL);
-	tmp &= ~RTC_PIE;
-	tmp &= ~RTC_AIE;
-	tmp &= ~RTC_UIE;
-	CMOS_WRITE(tmp, RTC_CONTROL);
-	CMOS_READ(RTC_INTR_FLAGS);
+	if (!hpet_mask_rtc_irq_bit(RTC_PIE | RTC_AIE | RTC_UIE)) {
+		tmp = CMOS_READ(RTC_CONTROL);
+		tmp &= ~RTC_PIE;
+		tmp &= ~RTC_AIE;
+		tmp &= ~RTC_UIE;
+		CMOS_WRITE(tmp, RTC_CONTROL);
+		CMOS_READ(RTC_INTR_FLAGS);
+	}
 	if (rtc_status & RTC_TIMER_ON) {
 		rtc_status &= ~RTC_TIMER_ON;
 		del_timer(&rtc_irq_timer);
@@ -822,6 +861,10 @@ static struct miscdevice rtc_dev=
 	&rtc_fops
 };
 
+#if RTC_IRQ
+static irqreturn_t (*rtc_int_handler_ptr)(int irq, void *dev_id, struct pt_regs *regs);
+#endif
+
 static int __init rtc_init(void)
 {
 #if defined(__alpha__) || defined(__mips__)
@@ -889,12 +932,20 @@ no_irq:
 	}
 
 #if RTC_IRQ
-	if (request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL)) {
+	if (is_hpet_enabled()) {
+		rtc_int_handler_ptr = hpet_rtc_interrupt;
+	} else {
+		rtc_int_handler_ptr = rtc_interrupt;
+	}
+
+	if(request_irq(RTC_IRQ, rtc_int_handler_ptr, SA_INTERRUPT, "rtc", NULL)) {
 		/* Yeah right, seeing as irq 8 doesn't even hit the bus. */
 		printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
 		release_region(RTC_PORT(0), RTC_IO_EXTENT);
 		return -EIO;
 	}
+	hpet_rtc_timer_init();
+
 #endif
 
 #endif /* __sparc__ vs. others */
@@ -965,10 +1016,12 @@ no_irq:
 	init_timer(&rtc_irq_timer);
 	rtc_irq_timer.function = rtc_dropped_irq;
 	spin_lock_irq(&rtc_lock);
-	/* Initialize periodic freq. to CMOS reset default, which is 1024Hz */
-	CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) & 0xF0) | 0x06), RTC_FREQ_SELECT);
-	spin_unlock_irq(&rtc_lock);
 	rtc_freq = 1024;
+	if (!hpet_set_periodic_freq(rtc_freq)) {
+		/* Initialize periodic freq. to CMOS reset default, which is 1024Hz */
+		CMOS_WRITE(((CMOS_READ(RTC_FREQ_SELECT) & 0xF0) | 0x06), RTC_FREQ_SELECT);
+	}
+	spin_unlock_irq(&rtc_lock);
 no_irq2:
 #endif
 
@@ -1019,6 +1072,11 @@ static void rtc_dropped_irq(unsigned lon
 
 	spin_lock_irq (&rtc_lock);
 
+	if (hpet_rtc_dropped_irq()) {
+		spin_unlock_irq(&rtc_lock);
+		return;
+	}
+
 	/* Just in case someone disabled the timer from behind our back... */
 	if (rtc_status & RTC_TIMER_ON)
 		mod_timer(&rtc_irq_timer, jiffies + HZ/rtc_freq + 2*HZ/100);
@@ -1148,7 +1206,7 @@ static inline unsigned char rtc_is_updat
 	return uip;
 }
 
-static void get_rtc_time(struct rtc_time *rtc_tm)
+void get_rtc_time(struct rtc_time *rtc_tm)
 {
 	unsigned long uip_watchdog = jiffies;
 	unsigned char ctrl;
@@ -1254,6 +1312,10 @@ static void mask_rtc_irq_bit(unsigned ch
 	unsigned char val;
 
 	spin_lock_irq(&rtc_lock);
+	if (hpet_mask_rtc_irq_bit(bit)) {
+		spin_unlock_irq(&rtc_lock);
+		return;
+	}
 	val = CMOS_READ(RTC_CONTROL);
 	val &=  ~bit;
 	CMOS_WRITE(val, RTC_CONTROL);
@@ -1268,6 +1330,10 @@ static void set_rtc_irq_bit(unsigned cha
 	unsigned char val;
 
 	spin_lock_irq(&rtc_lock);
+	if (hpet_set_rtc_irq_bit(bit)) {
+		spin_unlock_irq(&rtc_lock);
+		return;
+	}
 	val = CMOS_READ(RTC_CONTROL);
 	val |= bit;
 	CMOS_WRITE(val, RTC_CONTROL);
diff -purN linux-2.6.0-test4-hpetnortc/include/asm-i386/hpet.h linux-2.6.0-test4-hpet/include/asm-i386/hpet.h
--- linux-2.6.0-test4-hpetnortc/include/asm-i386/hpet.h	2003-08-29 17:56:48.000000000 -0700
+++ linux-2.6.0-test4-hpet/include/asm-i386/hpet.h	2003-08-28 16:20:50.000000000 -0700
@@ -102,5 +102,15 @@ extern int is_hpet_capable(void);
 extern int hpet_readl(unsigned long a);
 extern void hpet_writel(unsigned long d, unsigned long a);
 
+#ifdef CONFIG_RTC
+#define CONFIG_HPET_EMULATE_RTC 	1
+extern int hpet_mask_rtc_irq_bit(unsigned long bit_mask);
+extern int hpet_set_rtc_irq_bit(unsigned long bit_mask);
+extern int hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec);
+extern int hpet_set_periodic_freq(unsigned long freq);
+extern int hpet_rtc_dropped_irq(void);
+extern int hpet_rtc_timer_init(void);
+extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+#endif /* CONFIG_RTC */
 #endif /* CONFIG_HPET_TIMER */
 #endif /* _I386_HPET_H */
diff -purN linux-2.6.0-test4-hpetnortc/include/asm-i386/mc146818rtc.h linux-2.6.0-test4-hpet/include/asm-i386/mc146818rtc.h
--- linux-2.6.0-test4-hpetnortc/include/asm-i386/mc146818rtc.h	2003-08-29 17:56:48.000000000 -0700
+++ linux-2.6.0-test4-hpet/include/asm-i386/mc146818rtc.h	2003-08-28 16:20:50.000000000 -0700
@@ -24,10 +24,6 @@ outb_p((addr),RTC_PORT(0)); \
 outb_p((val),RTC_PORT(1)); \
 })
 
-#ifdef CONFIG_HPET_TIMER
-#define RTC_IRQ 0
-#else
 #define RTC_IRQ 8
-#endif
 
 #endif /* _ASM_MC146818RTC_H */

             reply	other threads:[~2003-08-29 23:59 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-08-29 23:58 Pallipadi, Venkatesh [this message]
2003-09-05 22:26 ` [PATCHSET][2.6-test4][0/6]Support for HPET based timer - Take 2 George Anzinger
  -- strict thread matches above, loose matches on Subject: below --
2003-09-06 19:04 Pallipadi, Venkatesh
2003-09-07 17:57 ` George Anzinger
2003-08-30 16:26 Pallipadi, Venkatesh
2003-08-29 16:12 Pallipadi, Venkatesh
2003-08-30  4:59 ` David Mosberger-Tang
     [not found] <pEGJ.73p.5@gated-at.bofh.it>
2003-08-29  3:40 ` David Mosberger-Tang
2003-08-28 23:41 Pallipadi, Venkatesh
2003-08-29 18:23 ` Andrew Morton
2003-08-29 21:03   ` Erik Andersen
2003-08-31 21:05     ` Linus Torvalds
2003-08-31 22:24       ` Erik Andersen
2003-08-31 22:48         ` Linus Torvalds
2003-09-05 22:19     ` George Anzinger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=C8C38546F90ABF408A5961FC01FDBF1902C7D224@fmsmsx405.fm.intel.com \
    --to=venkatesh.pallipadi@intel.com \
    --cc=akpm@osdl.org \
    --cc=jun.nakajima@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).