aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlbert Lee <albertcc@tw.ibm.com>2007-06-26 01:43:15 -0400
committerJeff Garzik <jeff@garzik.org>2007-07-02 10:12:34 -0400
commit8c781bf77a339748839bfd5eedfe2ad3e0e05c4a (patch)
treeb36feb822eaecec5735dcc18244503d5bb88e15e
parentabcdceb9d0bf39da7c7ff8bcdff6eb4d9dfec56f (diff)
libata: pata_pdc2027x PLL input clock fix
Recently the PLL input clock of pata_pdc2027x 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@tw.ibm.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/pata_pdc2027x.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index 0d2cc49fde4b..69a5aa4949f5 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -689,10 +689,12 @@ static long pdc_detect_pll_input_clock(struct ata_host *host)
689 void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR]; 689 void __iomem *mmio_base = host->iomap[PDC_MMIO_BAR];
690 u32 scr; 690 u32 scr;
691 long start_count, end_count; 691 long start_count, end_count;
692 long pll_clock; 692 struct timeval start_time, end_time;
693 long pll_clock, usec_elapsed;
693 694
694 /* Read current counter value */ 695 /* Read current counter value */
695 start_count = pdc_read_counter(host); 696 start_count = pdc_read_counter(host);
697 do_gettimeofday(&start_time);
696 698
697 /* Start the test mode */ 699 /* Start the test mode */
698 scr = readl(mmio_base + PDC_SYS_CTL); 700 scr = readl(mmio_base + PDC_SYS_CTL);
@@ -705,6 +707,7 @@ static long pdc_detect_pll_input_clock(struct ata_host *host)
705 707
706 /* Read the counter values again */ 708 /* Read the counter values again */
707 end_count = pdc_read_counter(host); 709 end_count = pdc_read_counter(host);
710 do_gettimeofday(&end_time);
708 711
709 /* Stop the test mode */ 712 /* Stop the test mode */
710 scr = readl(mmio_base + PDC_SYS_CTL); 713 scr = readl(mmio_base + PDC_SYS_CTL);
@@ -713,7 +716,11 @@ static long pdc_detect_pll_input_clock(struct ata_host *host)
713 readl(mmio_base + PDC_SYS_CTL); /* flush */ 716 readl(mmio_base + PDC_SYS_CTL); /* flush */
714 717
715 /* calculate the input clock in Hz */ 718 /* calculate the input clock in Hz */
716 pll_clock = (start_count - end_count) * 10; 719 usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 +
720 (end_time.tv_usec - start_time.tv_usec);
721
722 pll_clock = (start_count - end_count) / 100 *
723 (100000000 / usec_elapsed);
717 724
718 PDPRINTK("start[%ld] end[%ld] \n", start_count, end_count); 725 PDPRINTK("start[%ld] end[%ld] \n", start_count, end_count);
719 PDPRINTK("PLL input clock[%ld]Hz\n", pll_clock); 726 PDPRINTK("PLL input clock[%ld]Hz\n", pll_clock);