1c3079787STakanori Watanabe /* 2c3079787STakanori Watanabe * Copyright (c) 2020 Takanori Watanabe 3c3079787STakanori Watanabe * 4c3079787STakanori Watanabe * Redistribution and use in source and binary forms, with or without 5c3079787STakanori Watanabe * modification, are permitted provided that the following conditions 6c3079787STakanori Watanabe * are met: 7c3079787STakanori Watanabe * 1. Redistributions of source code must retain the above copyright 8c3079787STakanori Watanabe * notice, this list of conditions and the following disclaimer. 9c3079787STakanori Watanabe * 2. Redistributions in binary form must reproduce the above copyright 10c3079787STakanori Watanabe * notice, this list of conditions and the following disclaimer in the 11c3079787STakanori Watanabe * documentation and/or other materials provided with the distribution. 12c3079787STakanori Watanabe * 13c3079787STakanori Watanabe * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14c3079787STakanori Watanabe * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15c3079787STakanori Watanabe * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16c3079787STakanori Watanabe * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17c3079787STakanori Watanabe * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18c3079787STakanori Watanabe * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19c3079787STakanori Watanabe * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20c3079787STakanori Watanabe * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21c3079787STakanori Watanabe * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22c3079787STakanori Watanabe * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23c3079787STakanori Watanabe * SUCH DAMAGE. 24c3079787STakanori Watanabe */ 25c3079787STakanori Watanabe 26c3079787STakanori Watanabe #include <sys/cdefs.h> 27c3079787STakanori Watanabe __FBSDID("$FreeBSD$"); 28c3079787STakanori Watanabe 29c3079787STakanori Watanabe #include <sys/param.h> 30c3079787STakanori Watanabe #include <sys/systm.h> 31c3079787STakanori Watanabe #include <sys/kernel.h> 32c3079787STakanori Watanabe #include <sys/module.h> 33c3079787STakanori Watanabe #include <sys/errno.h> 34c3079787STakanori Watanabe #include <sys/lock.h> 35c3079787STakanori Watanabe #include <sys/mutex.h> 36c3079787STakanori Watanabe #include <sys/sysctl.h> 37c3079787STakanori Watanabe #include <sys/syslog.h> 38c3079787STakanori Watanabe #include <sys/bus.h> 39c3079787STakanori Watanabe 40c3079787STakanori Watanabe #include <machine/bus.h> 41c3079787STakanori Watanabe #include <sys/rman.h> 42c3079787STakanori Watanabe #include <machine/resource.h> 43c3079787STakanori Watanabe #include <dev/pci/pcivar.h> 44c3079787STakanori Watanabe #include <dev/pci/pcireg.h> 45c3079787STakanori Watanabe 46c3079787STakanori Watanabe #define PCHTHERM_REG_TEMP 0 47c3079787STakanori Watanabe #define PCHTHERM_REG_TSC 4 48c3079787STakanori Watanabe #define PCHTHERM_REG_TSS 6 49c3079787STakanori Watanabe #define PCHTHERM_REG_TSEL 8 50c3079787STakanori Watanabe #define PCHTHERM_REG_TSREL 0xa 51c3079787STakanori Watanabe #define PCHTHERM_REG_TSMIC 0xc 52c3079787STakanori Watanabe #define PCHTHERM_REG_CTT 0x10 53c3079787STakanori Watanabe #define PCHTHERM_REG_TAHV 0x14 54c3079787STakanori Watanabe #define PCHTHERM_REG_TALV 0x18 55c3079787STakanori Watanabe #define PCHTHERM_REG_TSPM 0x1c 56c3079787STakanori Watanabe #define PCHTHERM_REG_TL 0x40 57c3079787STakanori Watanabe #define PCHTHERM_REG_TL2 0x50 58c3079787STakanori Watanabe #define PCHTHERM_REG_PHL 0x60 59c3079787STakanori Watanabe #define PCHTHERM_REG_PHLC 0x62 60c3079787STakanori Watanabe #define PCHTHERM_REG_TAS 0x80 61c3079787STakanori Watanabe #define PCHTHERM_REG_TSPIEN 0x82 62c3079787STakanori Watanabe #define PCHTHERM_REG_TSGPEN 0x84 63c3079787STakanori Watanabe #define PCHTHERM_REG_TCFD 0xf0 64c3079787STakanori Watanabe #define PCHTHERM_GEN_LOCKDOWN 0x80 65c3079787STakanori Watanabe #define PCHTHERM_GEN_ENABLE 1 66c3079787STakanori Watanabe #define PCHTHERM_TEMP_FACTOR 5 67c3079787STakanori Watanabe #define PCHTHERM_TEMP_ZERO 2231 68c3079787STakanori Watanabe #define PCHTHERM_TEMP_MASK 0x1ff 69c3079787STakanori Watanabe #define PCHTHERM_TL_T0 0 70c3079787STakanori Watanabe #define PCHTHERM_TL_T1 10 71c3079787STakanori Watanabe #define PCHTHERM_TL_T2 20 72c3079787STakanori Watanabe #define PCHTHERM_TEMP_TO_IK(val) (((val) & PCHTHERM_TEMP_MASK) * \ 73c3079787STakanori Watanabe PCHTHERM_TEMP_FACTOR + \ 74c3079787STakanori Watanabe PCHTHERM_TEMP_ZERO) 75c3079787STakanori Watanabe 76c3079787STakanori Watanabe struct pchtherm_softc 77c3079787STakanori Watanabe { 78c3079787STakanori Watanabe int tbarrid; 79c3079787STakanori Watanabe struct resource *tbar; 80c3079787STakanori Watanabe int enable; 81c3079787STakanori Watanabe int ctten; 82c3079787STakanori Watanabe int pmtemp; 83c3079787STakanori Watanabe unsigned int pmtime; 84c3079787STakanori Watanabe }; 85c3079787STakanori Watanabe 86c3079787STakanori Watanabe static const struct pci_device_table pchtherm_devices[] = 87c3079787STakanori Watanabe { 88c3079787STakanori Watanabe { PCI_DEV(0x8086, 0x9c24), 89c3079787STakanori Watanabe PCI_DESCR("Haswell Thermal Subsystem")}, 90c3079787STakanori Watanabe { PCI_DEV(0x8086, 0x8c24), 91c3079787STakanori Watanabe PCI_DESCR("Haswell Thermal Subsystem")}, 92c3079787STakanori Watanabe { PCI_DEV(0x8086, 0x9ca4), 93c3079787STakanori Watanabe PCI_DESCR("Wildcat Point Thermal Subsystem")}, 94c3079787STakanori Watanabe { PCI_DEV(0x8086, 0x9d31), 95c3079787STakanori Watanabe PCI_DESCR("Skylake PCH Thermal Subsystem")}, 96c3079787STakanori Watanabe { PCI_DEV(0x8086, 0xa131), 97c3079787STakanori Watanabe PCI_DESCR("Skylake PCH 100 Thermal Subsystem")}, 98e26b9046STakanori Watanabe { PCI_DEV(0x8086, 0x9df9), 99e26b9046STakanori Watanabe PCI_DESCR("Cannon Lake PCH Thermal Controller")}, 100c3079787STakanori Watanabe }; 101c3079787STakanori Watanabe 102c3079787STakanori Watanabe static int pchtherm_probe(device_t dev) 103c3079787STakanori Watanabe { 104c3079787STakanori Watanabe const struct pci_device_table *tbl; 105c3079787STakanori Watanabe 106c3079787STakanori Watanabe tbl = PCI_MATCH(dev, pchtherm_devices); 107c3079787STakanori Watanabe if (tbl == NULL) 108c3079787STakanori Watanabe return (ENXIO); 109c3079787STakanori Watanabe device_set_desc(dev, tbl->descr); 110c3079787STakanori Watanabe 111c3079787STakanori Watanabe return (BUS_PROBE_DEFAULT); 112c3079787STakanori Watanabe 113c3079787STakanori Watanabe } 114c3079787STakanori Watanabe static int pchtherm_tltemp_sysctl(SYSCTL_HANDLER_ARGS) 115c3079787STakanori Watanabe { 116c3079787STakanori Watanabe struct pchtherm_softc *sc = oidp->oid_arg1; 117c3079787STakanori Watanabe int regshift = oidp->oid_arg2; 118c3079787STakanori Watanabe int temp; 119c3079787STakanori Watanabe 120c3079787STakanori Watanabe temp = bus_read_4(sc->tbar, PCHTHERM_REG_TL); 121c3079787STakanori Watanabe temp >>= regshift; 122c3079787STakanori Watanabe temp = PCHTHERM_TEMP_TO_IK(temp); 123c3079787STakanori Watanabe 124c3079787STakanori Watanabe return sysctl_handle_int(oidp, &temp, 0, req); 125c3079787STakanori Watanabe } 126c3079787STakanori Watanabe static int pchtherm_temp_sysctl(SYSCTL_HANDLER_ARGS) 127c3079787STakanori Watanabe { 128c3079787STakanori Watanabe struct pchtherm_softc *sc = oidp->oid_arg1; 129c3079787STakanori Watanabe int regoff = oidp->oid_arg2; 130c3079787STakanori Watanabe int temp; 131c3079787STakanori Watanabe 132c3079787STakanori Watanabe temp = bus_read_2(sc->tbar, regoff); 133c3079787STakanori Watanabe temp = PCHTHERM_TEMP_TO_IK(temp); 134c3079787STakanori Watanabe 135c3079787STakanori Watanabe return sysctl_handle_int(oidp, &temp, 0, req); 136c3079787STakanori Watanabe } 137c3079787STakanori Watanabe 138c3079787STakanori Watanabe #define FLAG_PRINT(dev, str, val) device_printf \ 139c3079787STakanori Watanabe (dev, str " %s %sable\n", \ 140c3079787STakanori Watanabe ((val) & 0x80)? "Locked" : "", \ 141c3079787STakanori Watanabe ((val) & 0x1)? "En" : "Dis") 142c3079787STakanori Watanabe 143c3079787STakanori Watanabe static int pchtherm_attach(device_t dev) 144c3079787STakanori Watanabe { 145c3079787STakanori Watanabe struct pchtherm_softc *sc = device_get_softc(dev); 146c3079787STakanori Watanabe unsigned int val; 147c3079787STakanori Watanabe int flag; 148c3079787STakanori Watanabe int temp; 149c3079787STakanori Watanabe 150c3079787STakanori Watanabe sc->tbarrid = PCIR_BAR(0); 151c3079787STakanori Watanabe sc->tbar = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 152c3079787STakanori Watanabe &sc->tbarrid, RF_ACTIVE|RF_SHAREABLE); 153c3079787STakanori Watanabe if (sc->tbar == NULL) { 154c3079787STakanori Watanabe return (ENOMEM); 155c3079787STakanori Watanabe } 156c3079787STakanori Watanabe sc->enable = bus_read_1(sc->tbar, PCHTHERM_REG_TSEL); 157c3079787STakanori Watanabe if (!(sc->enable & PCHTHERM_GEN_ENABLE )) { 158c3079787STakanori Watanabe if (sc->enable & PCHTHERM_GEN_LOCKDOWN) { 159c3079787STakanori Watanabe device_printf(dev, "Sensor not available\n"); 160c3079787STakanori Watanabe return 0; 161c3079787STakanori Watanabe } else { 162c3079787STakanori Watanabe device_printf(dev, "Enabling Sensor\n"); 163c3079787STakanori Watanabe bus_write_1(sc->tbar, PCHTHERM_REG_TSEL, 164c3079787STakanori Watanabe PCHTHERM_GEN_ENABLE); 165c3079787STakanori Watanabe sc->enable = bus_read_1(sc->tbar, PCHTHERM_REG_TSEL); 166*5084dde5SMichal Vanco if (!(sc->enable & PCHTHERM_GEN_ENABLE)) { 167c3079787STakanori Watanabe device_printf(dev, "Sensor enable failed\n"); 168c3079787STakanori Watanabe return 0; 169c3079787STakanori Watanabe } 170c3079787STakanori Watanabe } 171c3079787STakanori Watanabe } 172c3079787STakanori Watanabe 173c3079787STakanori Watanabe sc->ctten = bus_read_1(sc->tbar, PCHTHERM_REG_TSC); 174c3079787STakanori Watanabe if (bootverbose) { 175c3079787STakanori Watanabe FLAG_PRINT(dev, "Catastrophic Power Down", sc->ctten); 176c3079787STakanori Watanabe } 177c3079787STakanori Watanabe val = bus_read_1(sc->tbar, PCHTHERM_REG_TSREL); 178c3079787STakanori Watanabe if (bootverbose) { 179c3079787STakanori Watanabe FLAG_PRINT(dev, "SMBus report", val); 180c3079787STakanori Watanabe } 181*5084dde5SMichal Vanco val = bus_read_1(sc->tbar, PCHTHERM_REG_TSMIC); 182c3079787STakanori Watanabe if (bootverbose) { 183c3079787STakanori Watanabe FLAG_PRINT(dev, "SMI on alert", val); 184c3079787STakanori Watanabe } 185c3079787STakanori Watanabe val = bus_read_2(sc->tbar, PCHTHERM_REG_TSPM); 186c3079787STakanori Watanabe flag = val >> 13; 187c3079787STakanori Watanabe if (bootverbose) { 188c3079787STakanori Watanabe device_printf(dev, "TSPM: %b\n", 189c3079787STakanori Watanabe flag, "\20\3Lock\2DTSS0EN\1DSSOC0"); 190c3079787STakanori Watanabe device_printf(dev, "MAX Thermal Sensor Shutdown Time %ds\n", 191c3079787STakanori Watanabe 1<<((val>>9)&7)); 192c3079787STakanori Watanabe } 193c3079787STakanori Watanabe 194c3079787STakanori Watanabe temp = val & PCHTHERM_TEMP_MASK; 195c3079787STakanori Watanabe sc->pmtemp = PCHTHERM_TEMP_TO_IK(temp); 196c3079787STakanori Watanabe sc->pmtime = 1<<((val>>9)&7); 197c3079787STakanori Watanabe SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 198c3079787STakanori Watanabe SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 199c3079787STakanori Watanabe OID_AUTO, "pmtemp", CTLTYPE_INT|CTLFLAG_RD, 200c3079787STakanori Watanabe sc, PCHTHERM_REG_TSPM, pchtherm_temp_sysctl, 201c3079787STakanori Watanabe "IK", "Thermal sensor idle temperature"); 202c3079787STakanori Watanabe SYSCTL_ADD_U32(device_get_sysctl_ctx(dev), 203c3079787STakanori Watanabe SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 204c3079787STakanori Watanabe OID_AUTO, "pmtime", CTLFLAG_RD, 205c3079787STakanori Watanabe &sc->pmtime, 0,"Thermal sensor idle duration"); 206c3079787STakanori Watanabe 207c3079787STakanori Watanabe val = bus_read_4(sc->tbar, PCHTHERM_REG_TL); 208c3079787STakanori Watanabe flag = val>>29; 209c3079787STakanori Watanabe 210c3079787STakanori Watanabe if (bootverbose) { 211c3079787STakanori Watanabe device_printf(dev, "Throttling %b\n", 212c3079787STakanori Watanabe flag, "\20\3Lock\2TT13EN\1TTEN"); 213c3079787STakanori Watanabe } 214c3079787STakanori Watanabe 215c3079787STakanori Watanabe SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 216c3079787STakanori Watanabe SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 217c3079787STakanori Watanabe OID_AUTO, "t0temp", CTLTYPE_INT |CTLFLAG_RD, 218c3079787STakanori Watanabe sc, PCHTHERM_TL_T0, pchtherm_tltemp_sysctl, 219c3079787STakanori Watanabe "IK", "T0 temperature"); 220c3079787STakanori Watanabe 221c3079787STakanori Watanabe SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 222c3079787STakanori Watanabe SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 223c3079787STakanori Watanabe OID_AUTO, "t1temp", CTLTYPE_INT |CTLFLAG_RD, 224c3079787STakanori Watanabe sc, PCHTHERM_TL_T1, pchtherm_tltemp_sysctl, 225c3079787STakanori Watanabe "IK", "T1 temperature"); 226c3079787STakanori Watanabe 227c3079787STakanori Watanabe SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 228c3079787STakanori Watanabe SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 229c3079787STakanori Watanabe OID_AUTO, "t2temp", CTLTYPE_INT |CTLFLAG_RD, 230c3079787STakanori Watanabe sc, PCHTHERM_TL_T2, pchtherm_tltemp_sysctl, 231c3079787STakanori Watanabe "IK", "T2 temperature"); 232c3079787STakanori Watanabe 233c3079787STakanori Watanabe val = bus_read_2(sc->tbar, PCHTHERM_REG_TL2); 234c3079787STakanori Watanabe if (bootverbose) { 235c3079787STakanori Watanabe flag = val >>14; 236c3079787STakanori Watanabe device_printf(dev, "TL2 flag %b\n", 237c3079787STakanori Watanabe flag, "\20\1PMCTEN\2Lock"); 238c3079787STakanori Watanabe } 239c3079787STakanori Watanabe 240c3079787STakanori Watanabe /* If PHL is disable and lockdown, don't export it.*/ 241c3079787STakanori Watanabe val = bus_read_2(sc->tbar, PCHTHERM_REG_PHLC); 242c3079787STakanori Watanabe val <<= 16; 243c3079787STakanori Watanabe val |= bus_read_2(sc->tbar, PCHTHERM_REG_PHL); 244c3079787STakanori Watanabe if ((val & 0x10000) != 0x10000) { 245c3079787STakanori Watanabe SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 246c3079787STakanori Watanabe SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 247c3079787STakanori Watanabe OID_AUTO, "pch_hot_level", 248c3079787STakanori Watanabe CTLTYPE_INT |CTLFLAG_RD, 249c3079787STakanori Watanabe sc, PCHTHERM_REG_PHL, 250c3079787STakanori Watanabe pchtherm_temp_sysctl, "IK", 251c3079787STakanori Watanabe "PCH Hot level Temperature"); 252c3079787STakanori Watanabe } 253c3079787STakanori Watanabe 254c3079787STakanori Watanabe SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 255c3079787STakanori Watanabe SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 256c3079787STakanori Watanabe OID_AUTO, "temperature", CTLTYPE_INT |CTLFLAG_RD, 257c3079787STakanori Watanabe sc, PCHTHERM_REG_TEMP, 258c3079787STakanori Watanabe pchtherm_temp_sysctl, "IK", "Current temperature"); 259c3079787STakanori Watanabe /* 260c3079787STakanori Watanabe * If sensor enable bit is locked down, there is no way to change 261c3079787STakanori Watanabe * alart values effectively. 262c3079787STakanori Watanabe */ 263c3079787STakanori Watanabe if (!(sc->enable & PCHTHERM_GEN_LOCKDOWN) || 264c3079787STakanori Watanabe bus_read_2(sc->tbar, PCHTHERM_REG_TAHV) != 0) { 265c3079787STakanori Watanabe SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 266c3079787STakanori Watanabe SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 267c3079787STakanori Watanabe OID_AUTO, "tahv", CTLTYPE_INT |CTLFLAG_RD, 268c3079787STakanori Watanabe sc, PCHTHERM_REG_TAHV, 269c3079787STakanori Watanabe pchtherm_temp_sysctl, "IK", 270c3079787STakanori Watanabe "Alart High temperature"); 271c3079787STakanori Watanabe } 272c3079787STakanori Watanabe 273c3079787STakanori Watanabe if (!(sc->enable & PCHTHERM_GEN_LOCKDOWN) || 274c3079787STakanori Watanabe bus_read_2(sc->tbar, PCHTHERM_REG_TALV) != 0) { 275c3079787STakanori Watanabe SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 276c3079787STakanori Watanabe SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 277c3079787STakanori Watanabe OID_AUTO, "talv", CTLTYPE_INT |CTLFLAG_RD, 278c3079787STakanori Watanabe sc, PCHTHERM_REG_TALV, 279c3079787STakanori Watanabe pchtherm_temp_sysctl, "IK", 280c3079787STakanori Watanabe "Alart Low temperature"); 281c3079787STakanori Watanabe } 282c3079787STakanori Watanabe if (!(sc->ctten& PCHTHERM_GEN_LOCKDOWN) || 283c3079787STakanori Watanabe sc->ctten& PCHTHERM_GEN_ENABLE) { 284c3079787STakanori Watanabe SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 285c3079787STakanori Watanabe SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 286c3079787STakanori Watanabe OID_AUTO, "ctt", 287c3079787STakanori Watanabe CTLTYPE_INT |CTLFLAG_RD, 288c3079787STakanori Watanabe sc, PCHTHERM_REG_CTT, 289c3079787STakanori Watanabe pchtherm_temp_sysctl, "IK", 290c3079787STakanori Watanabe "Catastrophic Trip Point"); 291c3079787STakanori Watanabe } 292c3079787STakanori Watanabe 293c3079787STakanori Watanabe return 0; 294c3079787STakanori Watanabe } 295c3079787STakanori Watanabe static int pchtherm_detach(device_t dev) 296c3079787STakanori Watanabe { 297c3079787STakanori Watanabe struct pchtherm_softc *sc = device_get_softc(dev); 298c3079787STakanori Watanabe bus_release_resource(dev, SYS_RES_MEMORY, sc->tbarrid, sc->tbar); 299c3079787STakanori Watanabe 300c3079787STakanori Watanabe return 0; 301c3079787STakanori Watanabe } 302c3079787STakanori Watanabe static device_method_t pchtherm_methods[] = 303c3079787STakanori Watanabe { 304c3079787STakanori Watanabe DEVMETHOD(device_probe, pchtherm_probe), 305c3079787STakanori Watanabe DEVMETHOD(device_attach, pchtherm_attach), 306c3079787STakanori Watanabe DEVMETHOD(device_detach, pchtherm_detach), 307c3079787STakanori Watanabe 308c3079787STakanori Watanabe DEVMETHOD_END 309c3079787STakanori Watanabe }; 310c3079787STakanori Watanabe static driver_t pchtherm_driver = { 311c3079787STakanori Watanabe "pchtherm", 312c3079787STakanori Watanabe pchtherm_methods, 313c3079787STakanori Watanabe sizeof(struct pchtherm_softc) 314c3079787STakanori Watanabe }; 315c3079787STakanori Watanabe 316c3079787STakanori Watanabe static devclass_t pchtherm_devclass; 317c3079787STakanori Watanabe DRIVER_MODULE(pchtherm, pci, pchtherm_driver, pchtherm_devclass, 0, 0); 318c3079787STakanori Watanabe PCI_PNP_INFO(pchtherm_devices); 319