diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2007-02-16 04:27:57 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-16 11:13:58 -0500 |
commit | d66bea57e779cd592657cca6e61345ae899b78d9 (patch) | |
tree | 70fe41bf930ac96a59d594ba5a37272a3df775e0 | |
parent | 169a0abbe32813af4904cc1605c0f7ea0534f77b (diff) |
[PATCH] Allow early access to the power management timer
Allow early access to the power management timer by exposing the verified read
function and providing a helper function which checks the pmtmr_ioport
variable and returns either the pm timer readout or 0 in case the pm timer is
not available.
Create a new header file and replace also the ifdef'ed extern definition in
arch/i386/kernel/acpi/boot.c
This is a preperatory patch for the rework of the local apic timer
calibration.
No functional changes.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Roman Zippel <zippel@linux-m68k.org>
Cc: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/i386/kernel/acpi/boot.c | 5 | ||||
-rw-r--r-- | drivers/clocksource/acpi_pm.c | 17 | ||||
-rw-r--r-- | include/linux/acpi_pmtmr.h | 38 |
3 files changed, 48 insertions, 12 deletions
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index e94aff6888ca..56818cf5bc40 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/acpi.h> | 27 | #include <linux/acpi.h> |
28 | #include <linux/acpi_pmtmr.h> | ||
28 | #include <linux/efi.h> | 29 | #include <linux/efi.h> |
29 | #include <linux/cpumask.h> | 30 | #include <linux/cpumask.h> |
30 | #include <linux/module.h> | 31 | #include <linux/module.h> |
@@ -676,10 +677,6 @@ static int __init acpi_parse_hpet(struct acpi_table_header *table) | |||
676 | #define acpi_parse_hpet NULL | 677 | #define acpi_parse_hpet NULL |
677 | #endif | 678 | #endif |
678 | 679 | ||
679 | #ifdef CONFIG_X86_PM_TIMER | ||
680 | extern u32 pmtmr_ioport; | ||
681 | #endif | ||
682 | |||
683 | static int __init acpi_parse_fadt(struct acpi_table_header *table) | 680 | static int __init acpi_parse_fadt(struct acpi_table_header *table) |
684 | { | 681 | { |
685 | 682 | ||
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index c7276a61695b..ccaa6a39cb4b 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c | |||
@@ -16,15 +16,13 @@ | |||
16 | * This file is licensed under the GPL v2. | 16 | * This file is licensed under the GPL v2. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/acpi_pmtmr.h> | ||
19 | #include <linux/clocksource.h> | 20 | #include <linux/clocksource.h> |
20 | #include <linux/errno.h> | 21 | #include <linux/errno.h> |
21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
22 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
23 | #include <asm/io.h> | 24 | #include <asm/io.h> |
24 | 25 | ||
25 | /* Number of PMTMR ticks expected during calibration run */ | ||
26 | #define PMTMR_TICKS_PER_SEC 3579545 | ||
27 | |||
28 | /* | 26 | /* |
29 | * The I/O port the PMTMR resides at. | 27 | * The I/O port the PMTMR resides at. |
30 | * The location is detected during setup_arch(), | 28 | * The location is detected during setup_arch(), |
@@ -32,15 +30,13 @@ | |||
32 | */ | 30 | */ |
33 | u32 pmtmr_ioport __read_mostly; | 31 | u32 pmtmr_ioport __read_mostly; |
34 | 32 | ||
35 | #define ACPI_PM_MASK CLOCKSOURCE_MASK(24) /* limit it to 24 bits */ | ||
36 | |||
37 | static inline u32 read_pmtmr(void) | 33 | static inline u32 read_pmtmr(void) |
38 | { | 34 | { |
39 | /* mask the output to 24 bits */ | 35 | /* mask the output to 24 bits */ |
40 | return inl(pmtmr_ioport) & ACPI_PM_MASK; | 36 | return inl(pmtmr_ioport) & ACPI_PM_MASK; |
41 | } | 37 | } |
42 | 38 | ||
43 | static cycle_t acpi_pm_read_verified(void) | 39 | u32 acpi_pm_read_verified(void) |
44 | { | 40 | { |
45 | u32 v1 = 0, v2 = 0, v3 = 0; | 41 | u32 v1 = 0, v2 = 0, v3 = 0; |
46 | 42 | ||
@@ -57,7 +53,12 @@ static cycle_t acpi_pm_read_verified(void) | |||
57 | } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) | 53 | } while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) |
58 | || (v3 > v1 && v3 < v2))); | 54 | || (v3 > v1 && v3 < v2))); |
59 | 55 | ||
60 | return (cycle_t)v2; | 56 | return v2; |
57 | } | ||
58 | |||
59 | static cycle_t acpi_pm_read_slow(void) | ||
60 | { | ||
61 | return (cycle_t)acpi_pm_read_verified(); | ||
61 | } | 62 | } |
62 | 63 | ||
63 | static cycle_t acpi_pm_read(void) | 64 | static cycle_t acpi_pm_read(void) |
@@ -88,7 +89,7 @@ __setup("acpi_pm_good", acpi_pm_good_setup); | |||
88 | 89 | ||
89 | static inline void acpi_pm_need_workaround(void) | 90 | static inline void acpi_pm_need_workaround(void) |
90 | { | 91 | { |
91 | clocksource_acpi_pm.read = acpi_pm_read_verified; | 92 | clocksource_acpi_pm.read = acpi_pm_read_slow; |
92 | clocksource_acpi_pm.rating = 110; | 93 | clocksource_acpi_pm.rating = 110; |
93 | } | 94 | } |
94 | 95 | ||
diff --git a/include/linux/acpi_pmtmr.h b/include/linux/acpi_pmtmr.h new file mode 100644 index 000000000000..1d0ef1ae8036 --- /dev/null +++ b/include/linux/acpi_pmtmr.h | |||
@@ -0,0 +1,38 @@ | |||
1 | #ifndef _ACPI_PMTMR_H_ | ||
2 | #define _ACPI_PMTMR_H_ | ||
3 | |||
4 | #include <linux/clocksource.h> | ||
5 | |||
6 | /* Number of PMTMR ticks expected during calibration run */ | ||
7 | #define PMTMR_TICKS_PER_SEC 3579545 | ||
8 | |||
9 | /* limit it to 24 bits */ | ||
10 | #define ACPI_PM_MASK CLOCKSOURCE_MASK(24) | ||
11 | |||
12 | /* Overrun value */ | ||
13 | #define ACPI_PM_OVRRUN (1<<24) | ||
14 | |||
15 | #ifdef CONFIG_X86_PM_TIMER | ||
16 | |||
17 | extern u32 acpi_pm_read_verified(void); | ||
18 | extern u32 pmtmr_ioport; | ||
19 | |||
20 | static inline u32 acpi_pm_read_early(void) | ||
21 | { | ||
22 | if (!pmtmr_ioport) | ||
23 | return 0; | ||
24 | /* mask the output to 24 bits */ | ||
25 | return acpi_pm_read_verified() & ACPI_PM_MASK; | ||
26 | } | ||
27 | |||
28 | #else | ||
29 | |||
30 | static inline u32 acpi_pm_read_early(void) | ||
31 | { | ||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | #endif | ||
36 | |||
37 | #endif | ||
38 | |||