[PATCH 1/1] ide: pdc202xx_new PLL input clock fix

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Recently the PLL input clock of Promise 2027x is sometimes detected
higer than expected (e.g. 20.027 MHz compared to 16.714 MHz).
It seems sometimes the mdelay() function is not as precise as it
used to be. Per Alan's advice, HT or power management might affect
the precision of mdelay().

This patch calls gettimeofday() to mesure the time elapsed and
calculate the PLL input clock accordingly.

Signed-off-by: Albert Lee <albertcc@xxxxxxxxxx>
Cc: Alan Cox <alan@xxxxxxxxxxxxxxxxxxx>
---
(I have the Promise adapter at hand, so it's easier for me to verify.)
Attached please find the patch and the test result on my box for your review:
[   72.186805] PDC20275: chipset revision 1
[   72.196768] start[1039788039] end[1039620652] pll[16804952]
[   72.196819] PDC20275: PLL input clock is 16804 kHz
[   72.226586] PDC20275: 100% native mode on irq 10

Maybe Bahadir could also help to verify if it helps to his "hda lost interrupt" problem.

--- linux-2.6.22-rc7/drivers/ide/pci/pdc202xx_new.c.ori	2007-07-02 14:40:08.000000000 +0800
+++ linux-2.6.22-rc7/drivers/ide/pci/pdc202xx_new.c	2007-07-03 13:06:40.000000000 +0800
@@ -306,11 +306,13 @@ static long __devinit read_counter(u32 d
  */
 static long __devinit detect_pll_input_clock(unsigned long dma_base)
 {
+	struct timeval start_time, end_time;
 	long start_count, end_count;
-	long pll_input;
+	long pll_input, usec_elapsed;
 	u8 scr1;
 
 	start_count = read_counter(dma_base);
+	do_gettimeofday(&start_time);
 
 	/* Start the test mode */
 	outb(0x01, dma_base + 0x01);
@@ -322,6 +324,7 @@ static long __devinit detect_pll_input_c
 	mdelay(10);
 
 	end_count = read_counter(dma_base);
+	do_gettimeofday(&end_time);
 
 	/* Stop the test mode */
 	outb(0x01, dma_base + 0x01);
@@ -333,7 +336,10 @@ static long __devinit detect_pll_input_c
 	 * Calculate the input clock in Hz
 	 * (the clock counter is 30 bit wide and counts down)
 	 */
-	pll_input = ((start_count - end_count) & 0x3ffffff) * 100;
+	usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 +
+		(end_time.tv_usec - start_time.tv_usec);
+	pll_input = ((start_count - end_count) & 0x3ffffff) / 10 *
+		(10000000 / usec_elapsed);
 
 	DBG("start[%ld] end[%ld]\n", start_count, end_count);
 


-
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux