aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2007-02-16 04:27:57 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-16 11:13:58 -0500
commitd66bea57e779cd592657cca6e61345ae899b78d9 (patch)
tree70fe41bf930ac96a59d594ba5a37272a3df775e0
parent169a0abbe32813af4904cc1605c0f7ea0534f77b (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.c5
-rw-r--r--drivers/clocksource/acpi_pm.c17
-rw-r--r--include/linux/acpi_pmtmr.h38
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
680extern u32 pmtmr_ioport;
681#endif
682
683static int __init acpi_parse_fadt(struct acpi_table_header *table) 680static 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 */
33u32 pmtmr_ioport __read_mostly; 31u32 pmtmr_ioport __read_mostly;
34 32
35#define ACPI_PM_MASK CLOCKSOURCE_MASK(24) /* limit it to 24 bits */
36
37static inline u32 read_pmtmr(void) 33static 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
43static cycle_t acpi_pm_read_verified(void) 39u32 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
59static cycle_t acpi_pm_read_slow(void)
60{
61 return (cycle_t)acpi_pm_read_verified();
61} 62}
62 63
63static cycle_t acpi_pm_read(void) 64static cycle_t acpi_pm_read(void)
@@ -88,7 +89,7 @@ __setup("acpi_pm_good", acpi_pm_good_setup);
88 89
89static inline void acpi_pm_need_workaround(void) 90static 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
17extern u32 acpi_pm_read_verified(void);
18extern u32 pmtmr_ioport;
19
20static 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
30static inline u32 acpi_pm_read_early(void)
31{
32 return 0;
33}
34
35#endif
36
37#endif
38