root/dev/acpi/acpitimer.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. acpitimermatch
  2. acpitimerattach
  3. acpi_get_timecount

    1 /*      $OpenBSD: acpitimer.c,v 1.6 2007/02/22 07:01:41 jordan Exp $    */
    2 /*
    3  * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
    4  *
    5  * Permission to use, copy, modify, and distribute this software for any
    6  * purpose with or without fee is hereby granted, provided that the above
    7  * copyright notice and this permission notice appear in all copies.
    8  *
    9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   16  */
   17 
   18 #include <sys/param.h>
   19 #include <sys/systm.h>
   20 #include <sys/device.h>
   21 #include <sys/malloc.h>
   22 #ifdef __HAVE_TIMECOUNTER
   23 #include <sys/timetc.h>
   24 #endif
   25 
   26 #include <machine/bus.h>
   27 
   28 #include <dev/acpi/acpireg.h>
   29 #include <dev/acpi/acpivar.h>
   30 
   31 int acpitimermatch(struct device *, void *, void *);
   32 void acpitimerattach(struct device *, struct device *, void *);
   33 
   34 #ifdef __HAVE_TIMECOUNTER
   35 u_int acpi_get_timecount(struct timecounter *tc);
   36 
   37 static struct timecounter acpi_timecounter = {
   38         acpi_get_timecount,     /* get_timecount */
   39         0,                      /* no poll_pps */
   40         0x00ffffff,             /* counter_mask (24 bits) */
   41         ACPI_FREQUENCY,         /* frequency */
   42         0,                      /* name */
   43         1000                    /* quality */
   44 };
   45 #endif
   46 
   47 struct acpitimer_softc {
   48         struct device           sc_dev;
   49 
   50         bus_space_tag_t         sc_iot;
   51         bus_space_handle_t      sc_ioh;
   52 };
   53 
   54 struct cfattach acpitimer_ca = {
   55         sizeof(struct acpitimer_softc), acpitimermatch, acpitimerattach
   56 };
   57 
   58 struct cfdriver acpitimer_cd = {
   59         NULL, "acpitimer", DV_DULL
   60 };
   61 
   62 int
   63 acpitimermatch(struct device *parent, void *match, void *aux)
   64 {
   65         struct acpi_attach_args *aa = aux;
   66         struct cfdata *cf = match;
   67 
   68         /* sanity */
   69         if (aa->aaa_name == NULL ||
   70             strcmp(aa->aaa_name, cf->cf_driver->cd_name) != 0 ||
   71             aa->aaa_table != NULL)
   72                 return (0);
   73 
   74         return (1);
   75 }
   76 
   77 void
   78 acpitimerattach(struct device *parent, struct device *self, void *aux)
   79 {
   80         struct acpitimer_softc *sc = (struct acpitimer_softc *) self;
   81         struct acpi_softc *psc = (struct acpi_softc *) parent;
   82         int rc;
   83 
   84         if (psc->sc_fadt->hdr_revision >= 3)
   85                 rc = acpi_map_address(psc, &psc->sc_fadt->x_pm_tmr_blk, 0,
   86                     psc->sc_fadt->pm_tmr_len, &sc->sc_ioh, &sc->sc_iot);
   87         else
   88                 rc = acpi_map_address(psc, NULL, psc->sc_fadt->pm_tmr_blk,
   89                     psc->sc_fadt->pm_tmr_len, &sc->sc_ioh, &sc->sc_iot);
   90         if (rc) {
   91                 printf(": can't map i/o space\n");
   92                 return;
   93         }
   94 
   95         printf(": %ld Hz, %d bits\n", ACPI_FREQUENCY,
   96             psc->sc_fadt->flags & FADT_TMR_VAL_EXT ? 32 : 24);
   97 
   98 #ifdef __HAVE_TIMECOUNTER
   99         if (psc->sc_fadt->flags & FADT_TMR_VAL_EXT)
  100                 acpi_timecounter.tc_counter_mask = 0xffffffffU;
  101         acpi_timecounter.tc_priv = sc;
  102         acpi_timecounter.tc_name = sc->sc_dev.dv_xname;
  103         tc_init(&acpi_timecounter);
  104 #endif
  105 }
  106 
  107 
  108 #ifdef __HAVE_TIMECOUNTER
  109 u_int
  110 acpi_get_timecount(struct timecounter *tc)
  111 {
  112         struct acpitimer_softc *sc = tc->tc_priv;
  113         u_int u1, u2, u3;
  114 
  115         u2 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 0);
  116         u3 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 0);
  117         do {
  118                 u1 = u2;
  119                 u2 = u3;
  120                 u3 = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 0);
  121         } while (u1 > u2 || u2 > u3);
  122 
  123         return (u2);
  124 }
  125 #endif

/* [<][>][^][v][top][bottom][index][help] */