add some common code to support the ACPI power management timer
independly of ACPI
This commit is contained in:
parent
c89713e730
commit
eff818776d
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files,v 1.783 2006/06/25 08:00:01 yamt Exp $
|
||||
# $NetBSD: files,v 1.784 2006/06/26 16:13:21 drochner Exp $
|
||||
|
||||
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
|
||||
|
||||
@ -913,6 +913,11 @@ file dev/ic/tea5757.c tea5757
|
||||
define lm700x
|
||||
file dev/ic/lm700x.c lm700x
|
||||
|
||||
# ACPI power management timer (hardware access, independent of ACPI)
|
||||
#
|
||||
define acpipmtimer
|
||||
file dev/ic/acpipmtimer.c acpipmtimer
|
||||
|
||||
# Definitions for wscons
|
||||
# device attributes: display, display with emulator, keyboard, and mouse
|
||||
#
|
||||
|
90
sys/dev/ic/acpipmtimer.c
Normal file
90
sys/dev/ic/acpipmtimer.c
Normal file
@ -0,0 +1,90 @@
|
||||
/* $NetBSD: acpipmtimer.c,v 1.1 2006/06/26 16:13:21 drochner Exp $ */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __HAVE_TIMECOUNTER
|
||||
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <machine/bus.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timetc.h>
|
||||
|
||||
#include <dev/ic/acpipmtimer.h>
|
||||
|
||||
#define ACPI_PM_TIMER_FREQUENCY 3579545
|
||||
|
||||
struct hwtc {
|
||||
struct timecounter tc;
|
||||
bus_space_tag_t t;
|
||||
bus_space_handle_t h;
|
||||
bus_size_t off;
|
||||
};
|
||||
|
||||
static u_int acpihwtimer_read_safe(struct timecounter *);
|
||||
static u_int acpihwtimer_read_fast(struct timecounter *);
|
||||
|
||||
int
|
||||
acpipmtimer_attach(struct device *dev,
|
||||
bus_space_tag_t t, bus_space_handle_t h, bus_size_t off,
|
||||
int flags)
|
||||
{
|
||||
struct hwtc *tc;
|
||||
|
||||
tc = malloc(sizeof(struct hwtc), M_DEVBUF, M_WAITOK|M_ZERO);
|
||||
if (!tc)
|
||||
return (-1);
|
||||
|
||||
tc->tc.tc_name = dev->dv_xname;
|
||||
tc->tc.tc_frequency = ACPI_PM_TIMER_FREQUENCY;
|
||||
if (flags & ACPIPMT_32BIT)
|
||||
tc->tc.tc_counter_mask = 0xffffffff;
|
||||
else
|
||||
tc->tc.tc_counter_mask = 0x00ffffff;
|
||||
if (flags & ACPIPMT_BADLATCH) {
|
||||
tc->tc.tc_get_timecount = acpihwtimer_read_safe;
|
||||
tc->tc.tc_quality = 900;
|
||||
} else {
|
||||
tc->tc.tc_get_timecount = acpihwtimer_read_fast;
|
||||
tc->tc.tc_quality = 1000;
|
||||
}
|
||||
|
||||
tc->t = t;
|
||||
tc->h = h;
|
||||
tc->off = off;
|
||||
|
||||
tc->tc.tc_priv = tc;
|
||||
tc_init(&tc->tc);
|
||||
aprint_normal("%s %d-bit timer\n", tc->tc.tc_name,
|
||||
(flags & ACPIPMT_32BIT ? 32 : 24));
|
||||
return (0);
|
||||
}
|
||||
|
||||
#define r(h) bus_space_read_4(h->t, h->h, h->off)
|
||||
|
||||
static u_int
|
||||
acpihwtimer_read_safe(struct timecounter *tc)
|
||||
{
|
||||
struct hwtc *h = tc->tc_priv;
|
||||
uint32_t t1, t2, t3;
|
||||
|
||||
t2 = r(h);
|
||||
t3 = r(h);
|
||||
do {
|
||||
t1 = t2;
|
||||
t2 = t3;
|
||||
t3 = r(h);
|
||||
} while ((t1 > t2) || (t2 > t3));
|
||||
return (t2);
|
||||
}
|
||||
|
||||
static u_int
|
||||
acpihwtimer_read_fast(struct timecounter *tc)
|
||||
{
|
||||
struct hwtc *h = tc->tc_priv;
|
||||
|
||||
return r(h);
|
||||
}
|
||||
|
||||
#endif
|
6
sys/dev/ic/acpipmtimer.h
Normal file
6
sys/dev/ic/acpipmtimer.h
Normal file
@ -0,0 +1,6 @@
|
||||
/* $NetBSD: acpipmtimer.h,v 1.1 2006/06/26 16:13:21 drochner Exp $ */
|
||||
|
||||
int acpipmtimer_attach(struct device *,
|
||||
bus_space_tag_t, bus_space_handle_t, bus_size_t, int);
|
||||
#define ACPIPMT_32BIT 1
|
||||
#define ACPIPMT_BADLATCH 2
|
Loading…
x
Reference in New Issue
Block a user