root/dev/acpi/acpihpet.c

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

DEFINITIONS

This source file includes following definitions.
  1. acpihpet_match
  2. acpihpet_attach
  3. acpihpet_gettime

    1 /*      $OpenBSD: acpihpet.c,v 1.4 2007/02/20 23:54:46 marco 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 #include <dev/acpi/acpidev.h>
   31 
   32 int acpihpet_match(struct device *, void *, void *);
   33 void acpihpet_attach(struct device *, struct device *, void *);
   34 
   35 #ifdef __HAVE_TIMECOUNTER
   36 u_int acpihpet_gettime(struct timecounter *tc);
   37 
   38 static struct timecounter hpet_timecounter = {
   39         acpihpet_gettime,       /* get_timecount */
   40         0,                      /* no poll_pps */
   41         0xffffffff,             /* counter_mask (24 bits) */
   42         0,                      /* frequency */
   43         0,                      /* name */
   44         1000                    /* quality */
   45 };
   46 #endif
   47 
   48 struct acpihpet_softc {
   49         struct device           sc_dev;
   50 
   51         bus_space_tag_t         sc_iot;
   52         bus_space_handle_t      sc_ioh;
   53 };
   54 
   55 struct cfattach acpihpet_ca = {
   56         sizeof(struct acpihpet_softc), acpihpet_match, acpihpet_attach
   57 };
   58 
   59 struct cfdriver acpihpet_cd = {
   60         NULL, "acpihpet", DV_DULL
   61 };
   62 
   63 int
   64 acpihpet_match(struct device *parent, void *match, void *aux)
   65 {
   66         struct acpi_attach_args *aaa = aux;
   67         struct acpi_table_header *hdr;
   68 
   69         /*
   70          * If we do not have a table, it is not us
   71          */
   72         if (aaa->aaa_table == NULL)
   73                 return (0);
   74 
   75         /*
   76          * If it is an HPET table, we can attach
   77          */
   78         hdr = (struct acpi_table_header *)aaa->aaa_table;
   79         if (memcmp(hdr->signature, HPET_SIG, sizeof(HPET_SIG) - 1) != 0)
   80                 return (0);
   81 
   82         return (1);
   83 }
   84 
   85 void
   86 acpihpet_attach(struct device *parent, struct device *self, void *aux)
   87 {
   88         struct acpihpet_softc *sc = (struct acpihpet_softc *) self;
   89         struct acpi_softc *psc = (struct acpi_softc *)parent;
   90         struct acpi_attach_args *aaa = aux;
   91         struct acpi_hpet *hpet = (struct acpi_hpet *)aaa->aaa_table;
   92         u_int64_t period, freq; /* timer period in femtoseconds (10^-15) */
   93 
   94         if (acpi_map_address(psc, &hpet->base_address, 0, HPET_REG_SIZE,
   95             &sc->sc_ioh, &sc->sc_iot))  {
   96                 printf(": can't map i/o space\n");
   97                 return;
   98         }
   99 
  100         period = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
  101             HPET_CAPABILITIES + sizeof(u_int32_t));
  102         freq =  1000000000000000ull / period;
  103         printf(": %lld Hz\n", freq);
  104 
  105 #ifdef __HAVE_TIMECOUNTER
  106         hpet_timecounter.tc_frequency = (u_int32_t)freq;
  107         hpet_timecounter.tc_priv = sc;
  108         hpet_timecounter.tc_name = sc->sc_dev.dv_xname;
  109         bus_space_write_4(sc->sc_iot, sc->sc_ioh, HPET_CONFIGURATION, 1);
  110         tc_init(&hpet_timecounter);
  111 #endif
  112 }
  113 
  114 #ifdef __HAVE_TIMECOUNTER
  115 u_int
  116 acpihpet_gettime(struct timecounter *tc)
  117 {
  118         struct acpihpet_softc *sc = tc->tc_priv;
  119 
  120         return (bus_space_read_4(sc->sc_iot, sc->sc_ioh, HPET_MAIN_COUNTER));
  121 }
  122 #endif

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