예제 #1
0
static int __init init_acpi_pm_clocksource(void)
{
	u32 value1, value2;
	unsigned int i;

	if (!pmtmr_ioport)
		return -ENODEV;

	clocksource_acpi_pm.mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC,
						clocksource_acpi_pm.shift);

	/* "verify" this timing source: */
	value1 = read_pmtmr();
	for (i = 0; i < 10000; i++) {
		value2 = read_pmtmr();
		if (value2 == value1)
			continue;
		if (value2 > value1)
			goto pm_good;
		if ((value2 < value1) && ((value2) < 0xFFF))
			goto pm_good;
		printk(KERN_INFO "PM-Timer had inconsistent results:"
			" 0x%#x, 0x%#x - aborting.\n", value1, value2);
		return -EINVAL;
	}
	printk(KERN_INFO "PM-Timer had no reasonable result:"
			" 0x%#x - aborting.\n", value1);
	return -ENODEV;

pm_good:
	if (verify_pmtmr_rate() != 0)
		return -ENODEV;

	return clocksource_register(&clocksource_acpi_pm);
}
예제 #2
0
u32 acpi_pm_read_verified(void)
{
	u32 v1 = 0, v2 = 0, v3 = 0;

	
	do {
		v1 = read_pmtmr();
		v2 = read_pmtmr();
		v3 = read_pmtmr();
	} while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
			  || (v3 > v1 && v3 < v2)));

	return v2;
}
static int __init cpufreq_test_tsc(void)
{
	u32 now, then, diff;
	u64 now_tsc, then_tsc, diff_tsc;
	int i;

	/*                                                                      
                      */

	/*                                          */
	if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) {
		/*             */
		if (acpi_gbl_FADT.xpm_timer_block.space_id !=
		    ACPI_ADR_SPACE_SYSTEM_IO)
			return 0;

		pm_tmr_ioport = acpi_gbl_FADT.xpm_timer_block.address;
		/*
                                                            
                                                             
                                   
    */
		if (!pm_tmr_ioport)
			pm_tmr_ioport = acpi_gbl_FADT.pm_timer_block;
	} else {
		/*             */
		pm_tmr_ioport = acpi_gbl_FADT.pm_timer_block;
	}

	printk(KERN_DEBUG "start--> \n");
	then = read_pmtmr();
        rdtscll(then_tsc);
	for (i=0;i<20;i++) {
		mdelay(100);
		now = read_pmtmr();
		rdtscll(now_tsc);
		diff = (now - then) & 0xFFFFFF;
		diff_tsc = now_tsc - then_tsc;
		printk(KERN_DEBUG "t1: %08u t2: %08u diff_pmtmr: %08u diff_tsc: %016llu\n", then, now, diff, diff_tsc);
		then = now;
		then_tsc = now_tsc;
	}
	printk(KERN_DEBUG "<-- end \n");
	return -ENODEV;
}
예제 #4
0
static int __init cpufreq_test_tsc(void)
{
	u32 now, then, diff;
	u64 now_tsc, then_tsc, diff_tsc;
	int i;

	/* the following code snipped is copied from arch/x86/kernel/acpi/boot.c
	   of Linux v2.6.25. */

	/* detect the location of the ACPI PM Timer */
	if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) {
		/* FADT rev. 2 */
		if (acpi_gbl_FADT.xpm_timer_block.space_id !=
		    ACPI_ADR_SPACE_SYSTEM_IO)
			return 0;

		pm_tmr_ioport = acpi_gbl_FADT.xpm_timer_block.address;
		/*
		 * "X" fields are optional extensions to the original V1.0
		 * fields, so we must selectively expand V1.0 fields if the
		 * corresponding X field is zero.
	 	 */
		if (!pm_tmr_ioport)
			pm_tmr_ioport = acpi_gbl_FADT.pm_timer_block;
	} else {
		/* FADT rev. 1 */
		pm_tmr_ioport = acpi_gbl_FADT.pm_timer_block;
	}

	printk(KERN_DEBUG "start--> \n");
	then = read_pmtmr();
        rdtscll(then_tsc);
	for (i=0;i<20;i++) {
		mdelay(100);
		now = read_pmtmr();
		rdtscll(now_tsc);
		diff = (now - then) & 0xFFFFFF;
		diff_tsc = now_tsc - then_tsc;
		printk(KERN_DEBUG "t1: %08u t2: %08u diff_pmtmr: %08u diff_tsc: %016llu\n", then, now, diff, diff_tsc);
		then = now;
		then_tsc = now_tsc;
	}
	printk(KERN_DEBUG "<-- end \n");
	return -ENODEV;
}
예제 #5
0
u32 acpi_pm_read_verified(void)
{
	u32 v1 = 0, v2 = 0, v3 = 0;

	/*
	 * It has been reported that because of various broken
	 * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM clock
	 * source is not latched, you must read it multiple
	 * times to ensure a safe value is read:
	 */
	do {
		v1 = read_pmtmr();
		v2 = read_pmtmr();
		v3 = read_pmtmr();
	} while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
			  || (v3 > v1 && v3 < v2)));

	return v2;
}
예제 #6
0
/*
 * Some boards have the PMTMR running way too fast. We check
 * the PMTMR rate against PIT channel 2 to catch these cases.
 */
static int verify_pmtmr_rate(void)
{
	u32 value1, value2;
	unsigned long count, delta;

	mach_prepare_counter();
	value1 = read_pmtmr();
	mach_countup(&count);
	value2 = read_pmtmr();
	delta = (value2 - value1) & ACPI_PM_MASK;

	/* Check that the PMTMR delta is within 5% of what we expect */
	if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 ||
	    delta > (PMTMR_EXPECTED_RATE * 21) / 20) {
		printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% of normal - aborting.\n", 100UL * delta / PMTMR_EXPECTED_RATE);
		return -1;
	}

	return 0;
}
예제 #7
0
static cycle_t acpi_pm_read(void)
{
	return (cycle_t)read_pmtmr();
}
예제 #8
0
static cycle_t acpi_pm_read(struct clocksource *cs)
{
	return (cycle_t)read_pmtmr();
}