hpet_acpi.c revision 1.6
11.6Sjruoho/* $NetBSD: hpet_acpi.c,v 1.6 2011/06/14 13:59:23 jruoho Exp $ */ 21.1Snjoly 31.1Snjoly/* 41.6Sjruoho * Copyright (c) 2006, 2011 Nicolas Joly 51.1Snjoly * All rights reserved. 61.1Snjoly * 71.1Snjoly * Redistribution and use in source and binary forms, with or without 81.1Snjoly * modification, are permitted provided that the following conditions 91.1Snjoly * are met: 101.1Snjoly * 1. Redistributions of source code must retain the above copyright 111.1Snjoly * notice, this list of conditions and the following disclaimer. 121.1Snjoly * 2. Redistributions in binary form must reproduce the above copyright 131.1Snjoly * notice, this list of conditions and the following disclaimer in the 141.1Snjoly * documentation and/or other materials provided with the distribution. 151.1Snjoly * 3. The name of the author may not be used to endorse or promote products 161.1Snjoly * derived from this software without specific prior written permission. 171.1Snjoly * 181.1Snjoly * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS 191.1Snjoly * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 201.1Snjoly * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 211.1Snjoly * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 221.1Snjoly * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 231.1Snjoly * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 241.1Snjoly * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 251.1Snjoly * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 261.1Snjoly * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 271.1Snjoly * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 281.1Snjoly * POSSIBILITY OF SUCH DAMAGE. 291.1Snjoly */ 301.1Snjoly#include <sys/cdefs.h> 311.6Sjruoho__KERNEL_RCSID(0, "$NetBSD: hpet_acpi.c,v 1.6 2011/06/14 13:59:23 jruoho Exp $"); 321.1Snjoly 331.1Snjoly#include <sys/param.h> 341.5Sjruoho#include <sys/device.h> 351.5Sjruoho#include <sys/time.h> 361.5Sjruoho#include <sys/timetc.h> 371.1Snjoly 381.1Snjoly#include <dev/acpi/acpivar.h> 391.1Snjoly#include <dev/ic/hpetvar.h> 401.1Snjoly 411.6Sjruoho#define _COMPONENT ACPI_RESOURCE_COMPONENT 421.6SjruohoACPI_MODULE_NAME ("acpi_hpet") 431.1Snjoly 441.6Sjruoho#define HPET_MEM_WIDTH 0x3ff /* Expected memory region size. */ 451.1Snjoly 461.6Sjruohostatic int hpet_acpi_dev_match(device_t, cfdata_t, void *); 471.6Sjruohostatic void hpet_acpi_dev_attach(device_t, device_t, void *); 481.6Sjruohostatic int hpet_acpi_tab_match(device_t, cfdata_t, void *); 491.6Sjruohostatic void hpet_acpi_tab_attach(device_t, device_t, void *); 501.1Snjoly 511.1Snjolystatic const char * const hpet_acpi_ids[] = { 521.1Snjoly "PNP0103", 531.6Sjruoho NULL 541.1Snjoly}; 551.1Snjoly 561.6SjruohoCFATTACH_DECL_NEW(hpet_acpi_tab, sizeof(struct hpet_softc), 571.6Sjruoho hpet_acpi_tab_match, hpet_acpi_tab_attach, NULL, NULL); 581.6Sjruoho 591.6SjruohoCFATTACH_DECL_NEW(hpet_acpi_dev, sizeof(struct hpet_softc), 601.6Sjruoho hpet_acpi_dev_match, hpet_acpi_dev_attach, NULL, NULL); 611.6Sjruoho 621.6Sjruohostatic int 631.6Sjruohohpet_acpi_tab_match(device_t parent, cfdata_t match, void *aux) 641.6Sjruoho{ 651.6Sjruoho ACPI_TABLE_HPET *hpet; 661.6Sjruoho ACPI_STATUS rv; 671.6Sjruoho 681.6Sjruoho rv = AcpiGetTable(ACPI_SIG_HPET, 1, (ACPI_TABLE_HEADER **)&hpet); 691.6Sjruoho 701.6Sjruoho if (ACPI_FAILURE(rv)) 711.6Sjruoho return 0; 721.6Sjruoho 731.6Sjruoho if (hpet->Address.Address == 0) 741.6Sjruoho return 0; 751.6Sjruoho 761.6Sjruoho if (hpet->Address.SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) 771.6Sjruoho return 0; 781.6Sjruoho 791.6Sjruoho return 1; 801.6Sjruoho} 811.6Sjruoho 821.6Sjruohostatic void 831.6Sjruohohpet_acpi_tab_attach(device_t parent, device_t self, void *aux) 841.6Sjruoho{ 851.6Sjruoho struct hpet_softc *sc = device_private(self); 861.6Sjruoho struct acpi_attach_args *aa = aux; 871.6Sjruoho ACPI_TABLE_HPET *hpet; 881.6Sjruoho ACPI_STATUS rv; 891.6Sjruoho 901.6Sjruoho rv = AcpiGetTable(ACPI_SIG_HPET, 1, (ACPI_TABLE_HEADER **)&hpet); 911.6Sjruoho 921.6Sjruoho if (ACPI_FAILURE(rv)) 931.6Sjruoho return; 941.6Sjruoho 951.6Sjruoho sc->sc_memt = aa->aa_memt; 961.6Sjruoho 971.6Sjruoho if (hpet->Address.Address == 0xfed0000000000000UL) /* A quirk. */ 981.6Sjruoho hpet->Address.Address >>= 32; 991.6Sjruoho 1001.6Sjruoho if (bus_space_map(sc->sc_memt, hpet->Address.Address, 1011.6Sjruoho HPET_MEM_WIDTH, 0, &sc->sc_memh) != 0) { 1021.6Sjruoho aprint_error(": failed to map mem space\n"); 1031.6Sjruoho return; 1041.6Sjruoho } 1051.6Sjruoho 1061.6Sjruoho aprint_naive("\n"); 1071.6Sjruoho aprint_normal(": mem 0x%"PRIx64"-0x%"PRIx64"\n", 1081.6Sjruoho hpet->Address.Address, hpet->Address.Address + HPET_MEM_WIDTH); 1091.6Sjruoho 1101.6Sjruoho hpet_attach_subr(self); 1111.6Sjruoho} 1121.6Sjruoho 1131.1Snjolystatic int 1141.6Sjruohohpet_acpi_dev_match(device_t parent, cfdata_t match, void *aux) 1151.1Snjoly{ 1161.1Snjoly struct acpi_attach_args *aa = aux; 1171.1Snjoly 1181.1Snjoly if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE) 1191.1Snjoly return 0; 1201.1Snjoly 1211.1Snjoly return acpi_match_hid(aa->aa_node->ad_devinfo, hpet_acpi_ids); 1221.1Snjoly} 1231.1Snjoly 1241.1Snjolystatic void 1251.6Sjruohohpet_acpi_dev_attach(device_t parent, device_t self, void *aux) 1261.1Snjoly{ 1271.3Sxtraeme struct hpet_softc *sc = device_private(self); 1281.1Snjoly struct acpi_attach_args *aa = aux; 1291.1Snjoly struct acpi_resources res; 1301.1Snjoly struct acpi_mem *mem; 1311.1Snjoly ACPI_STATUS rv; 1321.1Snjoly 1331.3Sxtraeme rv = acpi_resource_parse(self, aa->aa_node->ad_handle, "_CRS", 1341.1Snjoly &res, &acpi_resource_parse_ops_default); 1351.6Sjruoho 1361.1Snjoly if (ACPI_FAILURE(rv)) 1371.1Snjoly return; 1381.1Snjoly 1391.1Snjoly mem = acpi_res_mem(&res, 0); 1401.6Sjruoho 1411.1Snjoly if (mem == NULL) { 1421.6Sjruoho aprint_error(": failed to find mem resource\n"); 1431.6Sjruoho goto out; 1441.6Sjruoho } 1451.6Sjruoho 1461.6Sjruoho if (mem->ar_length < HPET_MEM_WIDTH) { 1471.6Sjruoho aprint_error(": invalid memory region size\n"); 1481.1Snjoly goto out; 1491.1Snjoly } 1501.1Snjoly 1511.1Snjoly sc->sc_memt = aa->aa_memt; 1521.6Sjruoho 1531.6Sjruoho if (bus_space_map(sc->sc_memt, mem->ar_base, 1541.6Sjruoho mem->ar_length, 0, &sc->sc_memh) != 0) { 1551.6Sjruoho aprint_error(": failed to map mem space\n"); 1561.1Snjoly goto out; 1571.1Snjoly } 1581.1Snjoly 1591.3Sxtraeme hpet_attach_subr(self); 1601.1Snjoly 1611.6Sjruohoout: 1621.1Snjoly acpi_resource_cleanup(&res); 1631.1Snjoly} 164