Skip to content

Commit

Permalink
[PATCH] Allow early access to the power management timer
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
KAGA-KOKO authored and Linus Torvalds committed Feb 16, 2007
1 parent 169a0ab commit d66bea5
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 12 deletions.
5 changes: 1 addition & 4 deletions arch/i386/kernel/acpi/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <linux/init.h>
#include <linux/acpi.h>
#include <linux/acpi_pmtmr.h>
#include <linux/efi.h>
#include <linux/cpumask.h>
#include <linux/module.h>
Expand Down Expand Up @@ -676,10 +677,6 @@ static int __init acpi_parse_hpet(struct acpi_table_header *table)
#define acpi_parse_hpet NULL
#endif

#ifdef CONFIG_X86_PM_TIMER
extern u32 pmtmr_ioport;
#endif

static int __init acpi_parse_fadt(struct acpi_table_header *table)
{

Expand Down
17 changes: 9 additions & 8 deletions drivers/clocksource/acpi_pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,27 @@
* This file is licensed under the GPL v2.
*/

#include <linux/acpi_pmtmr.h>
#include <linux/clocksource.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <asm/io.h>

/* Number of PMTMR ticks expected during calibration run */
#define PMTMR_TICKS_PER_SEC 3579545

/*
* The I/O port the PMTMR resides at.
* The location is detected during setup_arch(),
* in arch/i386/acpi/boot.c
*/
u32 pmtmr_ioport __read_mostly;

#define ACPI_PM_MASK CLOCKSOURCE_MASK(24) /* limit it to 24 bits */

static inline u32 read_pmtmr(void)
{
/* mask the output to 24 bits */
return inl(pmtmr_ioport) & ACPI_PM_MASK;
}

static cycle_t acpi_pm_read_verified(void)
u32 acpi_pm_read_verified(void)
{
u32 v1 = 0, v2 = 0, v3 = 0;

Expand All @@ -57,7 +53,12 @@ static cycle_t acpi_pm_read_verified(void)
} while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
|| (v3 > v1 && v3 < v2)));

return (cycle_t)v2;
return v2;
}

static cycle_t acpi_pm_read_slow(void)
{
return (cycle_t)acpi_pm_read_verified();
}

static cycle_t acpi_pm_read(void)
Expand Down Expand Up @@ -88,7 +89,7 @@ __setup("acpi_pm_good", acpi_pm_good_setup);

static inline void acpi_pm_need_workaround(void)
{
clocksource_acpi_pm.read = acpi_pm_read_verified;
clocksource_acpi_pm.read = acpi_pm_read_slow;
clocksource_acpi_pm.rating = 110;
}

Expand Down
38 changes: 38 additions & 0 deletions include/linux/acpi_pmtmr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef _ACPI_PMTMR_H_
#define _ACPI_PMTMR_H_

#include <linux/clocksource.h>

/* Number of PMTMR ticks expected during calibration run */
#define PMTMR_TICKS_PER_SEC 3579545

/* limit it to 24 bits */
#define ACPI_PM_MASK CLOCKSOURCE_MASK(24)

/* Overrun value */
#define ACPI_PM_OVRRUN (1<<24)

#ifdef CONFIG_X86_PM_TIMER

extern u32 acpi_pm_read_verified(void);
extern u32 pmtmr_ioport;

static inline u32 acpi_pm_read_early(void)
{
if (!pmtmr_ioport)
return 0;
/* mask the output to 24 bits */
return acpi_pm_read_verified() & ACPI_PM_MASK;
}

#else

static inline u32 acpi_pm_read_early(void)
{
return 0;
}

#endif

#endif

0 comments on commit d66bea5

Please sign in to comment.