First cut on an implementation of an ACPI power management counter
backend for timecounters. Due to known bugs in some chipsets, always read until we get 3 successive samples which are monotonic, as FreeBSD does in its "safe" variant. This can be refined later, either by chipset quirks or by a test (as FreeBSD does).
This commit is contained in:
parent
9b00231778
commit
c14d23ac86
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: acpi.c,v 1.89 2006/06/20 12:31:19 cube Exp $ */
|
/* $NetBSD: acpi.c,v 1.90 2006/06/21 17:47:23 drochner Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.89 2006/06/20 12:31:19 cube Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.90 2006/06/21 17:47:23 drochner Exp $");
|
||||||
|
|
||||||
#include "opt_acpi.h"
|
#include "opt_acpi.h"
|
||||||
#include "opt_pcifixup.h"
|
#include "opt_pcifixup.h"
|
||||||
|
@ -94,6 +94,7 @@ __KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.89 2006/06/20 12:31:19 cube Exp $");
|
||||||
#include <dev/acpi/acpireg.h>
|
#include <dev/acpi/acpireg.h>
|
||||||
#include <dev/acpi/acpivar.h>
|
#include <dev/acpi/acpivar.h>
|
||||||
#include <dev/acpi/acpi_osd.h>
|
#include <dev/acpi/acpi_osd.h>
|
||||||
|
#include <dev/acpi/acpi_timer.h>
|
||||||
#ifdef ACPIVERBOSE
|
#ifdef ACPIVERBOSE
|
||||||
#include <dev/acpi/acpidevs_data.h>
|
#include <dev/acpi/acpidevs_data.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -351,6 +352,7 @@ acpi_attach(struct device *parent, struct device *self, void *aux)
|
||||||
* Check for fixed-hardware features.
|
* Check for fixed-hardware features.
|
||||||
*/
|
*/
|
||||||
acpi_enable_fixed_events(sc);
|
acpi_enable_fixed_events(sc);
|
||||||
|
acpitimer_init();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fix up PCI devices.
|
* Fix up PCI devices.
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/* $NetBSD: acpi_timer.c,v 1.1 2006/06/21 17:47:23 drochner Exp $ */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#ifdef __HAVE_TIMECOUNTER
|
||||||
|
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/timetc.h>
|
||||||
|
#include <dev/acpi/acpica.h>
|
||||||
|
#include <dev/acpi/acpi_timer.h>
|
||||||
|
|
||||||
|
static u_int acpitimer_read(struct timecounter *);
|
||||||
|
|
||||||
|
static struct timecounter acpi_timecounter = {
|
||||||
|
acpitimer_read,
|
||||||
|
0,
|
||||||
|
0x00ffffff,
|
||||||
|
PM_TIMER_FREQUENCY,
|
||||||
|
"ACPI_PM_TMR",
|
||||||
|
900
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
acpitimer_init()
|
||||||
|
{
|
||||||
|
uint32_t bits;
|
||||||
|
ACPI_STATUS res;
|
||||||
|
|
||||||
|
res = AcpiGetTimerResolution(&bits);
|
||||||
|
if (res != AE_OK)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
if (bits == 32)
|
||||||
|
acpi_timecounter.tc_counter_mask = 0xffffffff;
|
||||||
|
tc_init(&acpi_timecounter);
|
||||||
|
|
||||||
|
printf("acpitimer: %d bits\n", bits);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some chipsets (PIIX4 variants) do not latch correctly; there
|
||||||
|
* is a chance that a transition is hit.
|
||||||
|
* For now, just be conservative. We might detect the situation later
|
||||||
|
* (by testing, or chipset quirks).
|
||||||
|
*/
|
||||||
|
static u_int
|
||||||
|
acpitimer_read(struct timecounter *tc)
|
||||||
|
{
|
||||||
|
uint32_t t1, t2, t3;
|
||||||
|
|
||||||
|
AcpiGetTimer(&t2);
|
||||||
|
AcpiGetTimer(&t3);
|
||||||
|
do {
|
||||||
|
t1 = t2;
|
||||||
|
t2 = t3;
|
||||||
|
AcpiGetTimer(&t3);
|
||||||
|
} while ((t1 > t2) || (t2 > t3));
|
||||||
|
return (t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int
|
||||||
|
acpitimer_init()
|
||||||
|
{
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,3 @@
|
||||||
|
/* $NetBSD: acpi_timer.h,v 1.1 2006/06/21 17:47:23 drochner Exp $ */
|
||||||
|
|
||||||
|
int acpitimer_init(void);
|
|
@ -1,4 +1,4 @@
|
||||||
# $NetBSD: files.acpi,v 1.35 2006/01/31 09:30:06 kochi Exp $
|
# $NetBSD: files.acpi,v 1.36 2006/06/21 17:47:23 drochner Exp $
|
||||||
|
|
||||||
include "dev/acpi/acpica/files.acpica"
|
include "dev/acpi/acpica/files.acpica"
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ file dev/acpi/acpi_resource.c acpi
|
||||||
file dev/acpi/acpi_powerres.c acpi
|
file dev/acpi/acpi_powerres.c acpi
|
||||||
file dev/acpi/acpi_madt.c acpi & mpacpi
|
file dev/acpi/acpi_madt.c acpi & mpacpi
|
||||||
file dev/acpi/acpi_quirks.c acpi
|
file dev/acpi/acpi_quirks.c acpi
|
||||||
|
file dev/acpi/acpi_timer.c acpi
|
||||||
|
|
||||||
# ACPI Embedded Controller
|
# ACPI Embedded Controller
|
||||||
device acpiec
|
device acpiec
|
||||||
|
|
Loading…
Reference in New Issue