xref: /dragonfly/sys/dev/powermng/amdsmn/amdsmn.c (revision 4970ada5)
18311733cSPierre-Alain TORET /*-
22a07801cSSascha Wildner  * Copyright (c) 2017-2020 Conrad Meyer <cem@FreeBSD.org>
38311733cSPierre-Alain TORET  * All rights reserved.
48311733cSPierre-Alain TORET  *
58311733cSPierre-Alain TORET  * Redistribution and use in source and binary forms, with or without
68311733cSPierre-Alain TORET  * modification, are permitted provided that the following conditions
78311733cSPierre-Alain TORET  * are met:
88311733cSPierre-Alain TORET  * 1. Redistributions of source code must retain the above copyright
98311733cSPierre-Alain TORET  *    notice, this list of conditions and the following disclaimer.
108311733cSPierre-Alain TORET  * 2. Redistributions in binary form must reproduce the above copyright
118311733cSPierre-Alain TORET  *    notice, this list of conditions and the following disclaimer in the
128311733cSPierre-Alain TORET  *    documentation and/or other materials provided with the distribution.
138311733cSPierre-Alain TORET  *
148311733cSPierre-Alain TORET  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
158311733cSPierre-Alain TORET  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
168311733cSPierre-Alain TORET  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
178311733cSPierre-Alain TORET  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
188311733cSPierre-Alain TORET  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
198311733cSPierre-Alain TORET  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
208311733cSPierre-Alain TORET  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
218311733cSPierre-Alain TORET  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
228311733cSPierre-Alain TORET  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
238311733cSPierre-Alain TORET  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
248311733cSPierre-Alain TORET  * POSSIBILITY OF SUCH DAMAGE.
2523be8282SSascha Wildner  *
262a07801cSSascha Wildner  * $FreeBSD: head/sys/dev/amdsmn/amdsmn.c 366136 2020-09-25 04:16:28Z cem $
278311733cSPierre-Alain TORET  */
288311733cSPierre-Alain TORET 
298311733cSPierre-Alain TORET /*
30*4970ada5SMatthew Dillon  * Driver for the AMD Family 15h, 17h, 19h CPU System Management Network.
318311733cSPierre-Alain TORET  */
328311733cSPierre-Alain TORET 
338311733cSPierre-Alain TORET #include <sys/param.h>
348311733cSPierre-Alain TORET #include <sys/bus.h>
358311733cSPierre-Alain TORET #include <sys/conf.h>
368311733cSPierre-Alain TORET #include <sys/lock.h>
378311733cSPierre-Alain TORET #include <sys/kernel.h>
388311733cSPierre-Alain TORET #include <sys/module.h>
398311733cSPierre-Alain TORET #include <sys/mutex.h>
408311733cSPierre-Alain TORET #include <sys/sysctl.h>
418311733cSPierre-Alain TORET #include <sys/systm.h>
428311733cSPierre-Alain TORET 
438311733cSPierre-Alain TORET #include <machine/cpufunc.h>
448311733cSPierre-Alain TORET #include <machine/cputypes.h>
458311733cSPierre-Alain TORET #include <machine/md_var.h>
468311733cSPierre-Alain TORET #include <machine/specialreg.h>
478311733cSPierre-Alain TORET 
488311733cSPierre-Alain TORET #include <bus/pci/pcivar.h>
498311733cSPierre-Alain TORET #include <bus/pci/pci_cfgreg.h>
508311733cSPierre-Alain TORET 
518311733cSPierre-Alain TORET #include <dev/powermng/amdsmn/amdsmn.h>
528311733cSPierre-Alain TORET 
538311733cSPierre-Alain TORET #define	F15H_SMN_ADDR_REG	0xb8
548311733cSPierre-Alain TORET #define	F15H_SMN_DATA_REG	0xbc
55*4970ada5SMatthew Dillon 
568311733cSPierre-Alain TORET #define	F17H_SMN_ADDR_REG	0x60
578311733cSPierre-Alain TORET #define	F17H_SMN_DATA_REG	0x64
588311733cSPierre-Alain TORET 
59*4970ada5SMatthew Dillon #define	F19H_SMN_ADDR_REG	0x60
60*4970ada5SMatthew Dillon #define	F19H_SMN_DATA_REG	0x64
61*4970ada5SMatthew Dillon 
628311733cSPierre-Alain TORET #define	PCI_DEVICE_ID_AMD_15H_M60H_ROOT		0x1576
638311733cSPierre-Alain TORET #define	PCI_DEVICE_ID_AMD_17H_ROOT		0x1450
648311733cSPierre-Alain TORET #define	PCI_DEVICE_ID_AMD_17H_M10H_ROOT		0x15d0
658311733cSPierre-Alain TORET #define	PCI_DEVICE_ID_AMD_17H_M30H_ROOT		0x1480	/* Also M70H. */
662a07801cSSascha Wildner #define	PCI_DEVICE_ID_AMD_17H_M60H_ROOT		0x1630
67*4970ada5SMatthew Dillon #define	PCI_DEVICE_ID_AMD_17H_MA0H_ROOT		0x14b5
68*4970ada5SMatthew Dillon 
69*4970ada5SMatthew Dillon #if 0
70*4970ada5SMatthew Dillon #define	PCI_DEVICE_ID_AMD_19H_M10H_ROOT		0x14b1
71*4970ada5SMatthew Dillon #define	PCI_DEVICE_ID_AMD_19H_M40H_ROOT		0x14b5
72*4970ada5SMatthew Dillon #define	PCI_DEVICE_ID_AMD_19H_M50H_ROOT		0x166e
73*4970ada5SMatthew Dillon #define	PCI_DEVICE_ID_AMD_19H_M60H_ROOT		0x14e4
74*4970ada5SMatthew Dillon #define	PCI_DEVICE_ID_AMD_19H_M70H_ROOT		0x14f4
75*4970ada5SMatthew Dillon #endif
76*4970ada5SMatthew Dillon #define	PCI_DEVICE_ID_AMD_19H_M10H_ROOT		0x14a4
77*4970ada5SMatthew Dillon #define	PCI_DEVICE_ID_AMD_19H_M60H_ROOT		0x14d8
78*4970ada5SMatthew Dillon #define	PCI_DEVICE_ID_AMD_19H_M70H_ROOT		0x14e8
798311733cSPierre-Alain TORET 
808311733cSPierre-Alain TORET struct pciid;
818311733cSPierre-Alain TORET struct amdsmn_softc {
828311733cSPierre-Alain TORET 	struct lock smn_lock;
838311733cSPierre-Alain TORET 	const struct pciid *smn_pciid;
848311733cSPierre-Alain TORET };
858311733cSPierre-Alain TORET 
868311733cSPierre-Alain TORET static const struct pciid {
878311733cSPierre-Alain TORET 	uint16_t	amdsmn_vendorid;
888311733cSPierre-Alain TORET 	uint16_t	amdsmn_deviceid;
898311733cSPierre-Alain TORET 	uint8_t		amdsmn_addr_reg;
908311733cSPierre-Alain TORET 	uint8_t		amdsmn_data_reg;
918311733cSPierre-Alain TORET } amdsmn_ids[] = {
928311733cSPierre-Alain TORET 	{
938311733cSPierre-Alain TORET 		.amdsmn_vendorid = CPU_VENDOR_AMD,
948311733cSPierre-Alain TORET 		.amdsmn_deviceid = PCI_DEVICE_ID_AMD_15H_M60H_ROOT,
958311733cSPierre-Alain TORET 		.amdsmn_addr_reg = F15H_SMN_ADDR_REG,
968311733cSPierre-Alain TORET 		.amdsmn_data_reg = F15H_SMN_DATA_REG,
978311733cSPierre-Alain TORET 	},
988311733cSPierre-Alain TORET 	{
998311733cSPierre-Alain TORET 		.amdsmn_vendorid = CPU_VENDOR_AMD,
1008311733cSPierre-Alain TORET 		.amdsmn_deviceid = PCI_DEVICE_ID_AMD_17H_ROOT,
1018311733cSPierre-Alain TORET 		.amdsmn_addr_reg = F17H_SMN_ADDR_REG,
1028311733cSPierre-Alain TORET 		.amdsmn_data_reg = F17H_SMN_DATA_REG,
1038311733cSPierre-Alain TORET 	},
1048311733cSPierre-Alain TORET 	{
1058311733cSPierre-Alain TORET 		.amdsmn_vendorid = CPU_VENDOR_AMD,
1068311733cSPierre-Alain TORET 		.amdsmn_deviceid = PCI_DEVICE_ID_AMD_17H_M10H_ROOT,
1078311733cSPierre-Alain TORET 		.amdsmn_addr_reg = F17H_SMN_ADDR_REG,
1088311733cSPierre-Alain TORET 		.amdsmn_data_reg = F17H_SMN_DATA_REG,
1098311733cSPierre-Alain TORET 	},
1108311733cSPierre-Alain TORET 	{
1118311733cSPierre-Alain TORET 		.amdsmn_vendorid = CPU_VENDOR_AMD,
1128311733cSPierre-Alain TORET 		.amdsmn_deviceid = PCI_DEVICE_ID_AMD_17H_M30H_ROOT,
1138311733cSPierre-Alain TORET 		.amdsmn_addr_reg = F17H_SMN_ADDR_REG,
1148311733cSPierre-Alain TORET 		.amdsmn_data_reg = F17H_SMN_DATA_REG,
1158311733cSPierre-Alain TORET 	},
1162a07801cSSascha Wildner 	{
1172a07801cSSascha Wildner 		.amdsmn_vendorid = CPU_VENDOR_AMD,
1182a07801cSSascha Wildner 		.amdsmn_deviceid = PCI_DEVICE_ID_AMD_17H_M60H_ROOT,
1192a07801cSSascha Wildner 		.amdsmn_addr_reg = F17H_SMN_ADDR_REG,
1202a07801cSSascha Wildner 		.amdsmn_data_reg = F17H_SMN_DATA_REG,
1212a07801cSSascha Wildner 	},
122*4970ada5SMatthew Dillon 	{
123*4970ada5SMatthew Dillon 		.amdsmn_vendorid = CPU_VENDOR_AMD,
124*4970ada5SMatthew Dillon 		.amdsmn_deviceid = PCI_DEVICE_ID_AMD_17H_MA0H_ROOT,
125*4970ada5SMatthew Dillon 		.amdsmn_addr_reg = F17H_SMN_ADDR_REG,
126*4970ada5SMatthew Dillon 		.amdsmn_data_reg = F17H_SMN_DATA_REG,
127*4970ada5SMatthew Dillon 	},
128*4970ada5SMatthew Dillon 	{
129*4970ada5SMatthew Dillon 		.amdsmn_vendorid = CPU_VENDOR_AMD,
130*4970ada5SMatthew Dillon 		.amdsmn_deviceid = PCI_DEVICE_ID_AMD_19H_M10H_ROOT,
131*4970ada5SMatthew Dillon 		.amdsmn_addr_reg = F19H_SMN_ADDR_REG,
132*4970ada5SMatthew Dillon 		.amdsmn_data_reg = F19H_SMN_DATA_REG,
133*4970ada5SMatthew Dillon 	},
134*4970ada5SMatthew Dillon #if 0
135*4970ada5SMatthew Dillon 	{
136*4970ada5SMatthew Dillon 		.amdsmn_vendorid = CPU_VENDOR_AMD,
137*4970ada5SMatthew Dillon 		.amdsmn_deviceid = PCI_DEVICE_ID_AMD_19H_M40H_ROOT,
138*4970ada5SMatthew Dillon 		.amdsmn_addr_reg = F19H_SMN_ADDR_REG,
139*4970ada5SMatthew Dillon 		.amdsmn_data_reg = F19H_SMN_DATA_REG,
140*4970ada5SMatthew Dillon 	},
141*4970ada5SMatthew Dillon 	{
142*4970ada5SMatthew Dillon 		.amdsmn_vendorid = CPU_VENDOR_AMD,
143*4970ada5SMatthew Dillon 		.amdsmn_deviceid = PCI_DEVICE_ID_AMD_19H_M50H_ROOT,
144*4970ada5SMatthew Dillon 		.amdsmn_addr_reg = F19H_SMN_ADDR_REG,
145*4970ada5SMatthew Dillon 		.amdsmn_data_reg = F19H_SMN_DATA_REG,
146*4970ada5SMatthew Dillon 	},
147*4970ada5SMatthew Dillon #endif
148*4970ada5SMatthew Dillon 	{
149*4970ada5SMatthew Dillon 		.amdsmn_vendorid = CPU_VENDOR_AMD,
150*4970ada5SMatthew Dillon 		.amdsmn_deviceid = PCI_DEVICE_ID_AMD_19H_M60H_ROOT,
151*4970ada5SMatthew Dillon 		.amdsmn_addr_reg = F19H_SMN_ADDR_REG,
152*4970ada5SMatthew Dillon 		.amdsmn_data_reg = F19H_SMN_DATA_REG,
153*4970ada5SMatthew Dillon 	},
154*4970ada5SMatthew Dillon 	{
155*4970ada5SMatthew Dillon 		.amdsmn_vendorid = CPU_VENDOR_AMD,
156*4970ada5SMatthew Dillon 		.amdsmn_deviceid = PCI_DEVICE_ID_AMD_19H_M70H_ROOT,
157*4970ada5SMatthew Dillon 		.amdsmn_addr_reg = F19H_SMN_ADDR_REG,
158*4970ada5SMatthew Dillon 		.amdsmn_data_reg = F19H_SMN_DATA_REG,
159*4970ada5SMatthew Dillon 	},
1608311733cSPierre-Alain TORET };
1618311733cSPierre-Alain TORET 
1628311733cSPierre-Alain TORET /*
1638311733cSPierre-Alain TORET  * Device methods.
1648311733cSPierre-Alain TORET  */
1658311733cSPierre-Alain TORET static void 	amdsmn_identify(driver_t *driver, device_t parent);
1668311733cSPierre-Alain TORET static int	amdsmn_probe(device_t dev);
1678311733cSPierre-Alain TORET static int	amdsmn_attach(device_t dev);
1688311733cSPierre-Alain TORET static int	amdsmn_detach(device_t dev);
1698311733cSPierre-Alain TORET 
1708311733cSPierre-Alain TORET static device_method_t amdsmn_methods[] = {
1718311733cSPierre-Alain TORET 	/* Device interface */
1728311733cSPierre-Alain TORET 	DEVMETHOD(device_identify,	amdsmn_identify),
1738311733cSPierre-Alain TORET 	DEVMETHOD(device_probe,		amdsmn_probe),
1748311733cSPierre-Alain TORET 	DEVMETHOD(device_attach,	amdsmn_attach),
1758311733cSPierre-Alain TORET 	DEVMETHOD(device_detach,	amdsmn_detach),
1768311733cSPierre-Alain TORET 	DEVMETHOD_END
1778311733cSPierre-Alain TORET };
1788311733cSPierre-Alain TORET 
1798311733cSPierre-Alain TORET static driver_t amdsmn_driver = {
1808311733cSPierre-Alain TORET 	"amdsmn",
1818311733cSPierre-Alain TORET 	amdsmn_methods,
1828311733cSPierre-Alain TORET 	sizeof(struct amdsmn_softc),
1838311733cSPierre-Alain TORET };
1848311733cSPierre-Alain TORET 
1858311733cSPierre-Alain TORET static devclass_t amdsmn_devclass;
186*4970ada5SMatthew Dillon DRIVER_MODULE_ORDERED(amdsmn, hostb, amdsmn_driver,
187*4970ada5SMatthew Dillon 			&amdsmn_devclass, NULL, NULL, SI_ORDER_EARLIER);
1888311733cSPierre-Alain TORET MODULE_VERSION(amdsmn, 1);
1898311733cSPierre-Alain TORET #if !defined(__DragonFly__)
1908311733cSPierre-Alain TORET MODULE_PNP_INFO("U16:vendor;U16:device", pci, amdsmn, amdsmn_ids,
1918311733cSPierre-Alain TORET     nitems(amdsmn_ids));
1928311733cSPierre-Alain TORET #endif
1938311733cSPierre-Alain TORET 
1948311733cSPierre-Alain TORET static bool
amdsmn_match(device_t parent,const struct pciid ** pciid_out)1958311733cSPierre-Alain TORET amdsmn_match(device_t parent, const struct pciid **pciid_out)
1968311733cSPierre-Alain TORET {
1978311733cSPierre-Alain TORET 	uint16_t vendor, device;
1988311733cSPierre-Alain TORET 	size_t i;
1998311733cSPierre-Alain TORET 
2008311733cSPierre-Alain TORET 	vendor = pci_get_vendor(parent);
2018311733cSPierre-Alain TORET 	device = pci_get_device(parent);
2028311733cSPierre-Alain TORET 
2038311733cSPierre-Alain TORET 	for (i = 0; i < nitems(amdsmn_ids); i++) {
2048311733cSPierre-Alain TORET 		if (vendor == amdsmn_ids[i].amdsmn_vendorid &&
2058311733cSPierre-Alain TORET 		    device == amdsmn_ids[i].amdsmn_deviceid) {
2068311733cSPierre-Alain TORET 			if (pciid_out != NULL)
2078311733cSPierre-Alain TORET 				*pciid_out = &amdsmn_ids[i];
2088311733cSPierre-Alain TORET 			return (true);
2098311733cSPierre-Alain TORET 		}
2108311733cSPierre-Alain TORET 	}
2118311733cSPierre-Alain TORET 	return (false);
2128311733cSPierre-Alain TORET }
2138311733cSPierre-Alain TORET 
2148311733cSPierre-Alain TORET static void
amdsmn_identify(driver_t * driver,device_t parent)2158311733cSPierre-Alain TORET amdsmn_identify(driver_t *driver, device_t parent)
2168311733cSPierre-Alain TORET {
2178311733cSPierre-Alain TORET 	device_t child;
2188311733cSPierre-Alain TORET 
2198311733cSPierre-Alain TORET 	/* Make sure we're not being doubly invoked. */
2208311733cSPierre-Alain TORET 	if (device_find_child(parent, "amdsmn", -1) != NULL)
2218311733cSPierre-Alain TORET 		return;
2228311733cSPierre-Alain TORET 	if (!amdsmn_match(parent, NULL))
2238311733cSPierre-Alain TORET 		return;
2248311733cSPierre-Alain TORET 
2258311733cSPierre-Alain TORET 	child = device_add_child(parent, "amdsmn", -1);
2268311733cSPierre-Alain TORET 	if (child == NULL)
2278311733cSPierre-Alain TORET 		device_printf(parent, "add amdsmn child failed\n");
2288311733cSPierre-Alain TORET }
2298311733cSPierre-Alain TORET 
2308311733cSPierre-Alain TORET static int
amdsmn_probe(device_t dev)2318311733cSPierre-Alain TORET amdsmn_probe(device_t dev)
2328311733cSPierre-Alain TORET {
2338311733cSPierre-Alain TORET 	uint32_t family;
2348311733cSPierre-Alain TORET 	char buf[64];
2358311733cSPierre-Alain TORET 
2368311733cSPierre-Alain TORET 	if (resource_disabled("amdsmn", 0))
2378311733cSPierre-Alain TORET 		return (ENXIO);
2388311733cSPierre-Alain TORET 	if (!amdsmn_match(device_get_parent(dev), NULL))
2398311733cSPierre-Alain TORET 		return (ENXIO);
2408311733cSPierre-Alain TORET 
2418311733cSPierre-Alain TORET 	family = CPUID_TO_FAMILY(cpu_id);
2428311733cSPierre-Alain TORET 
2438311733cSPierre-Alain TORET 	switch (family) {
2448311733cSPierre-Alain TORET 	case 0x15:
2458311733cSPierre-Alain TORET 	case 0x17:
246d834e1dcSMatthew Dillon 	case 0x19:
2478311733cSPierre-Alain TORET 		break;
2488311733cSPierre-Alain TORET 	default:
2498311733cSPierre-Alain TORET 		return (ENXIO);
2508311733cSPierre-Alain TORET 	}
2518311733cSPierre-Alain TORET 	ksnprintf(buf, sizeof(buf), "AMD Family %xh System Management Network",
2528311733cSPierre-Alain TORET 	    family);
2538311733cSPierre-Alain TORET 	device_set_desc_copy(dev, buf);
2548311733cSPierre-Alain TORET 
2558311733cSPierre-Alain TORET 	return (BUS_PROBE_GENERIC);
2568311733cSPierre-Alain TORET }
2578311733cSPierre-Alain TORET 
2588311733cSPierre-Alain TORET static int
amdsmn_attach(device_t dev)2598311733cSPierre-Alain TORET amdsmn_attach(device_t dev)
2608311733cSPierre-Alain TORET {
2618311733cSPierre-Alain TORET 	struct amdsmn_softc *sc = device_get_softc(dev);
2628311733cSPierre-Alain TORET 
2638311733cSPierre-Alain TORET 	if (!amdsmn_match(device_get_parent(dev), &sc->smn_pciid))
2648311733cSPierre-Alain TORET 		return (ENXIO);
2658311733cSPierre-Alain TORET 
2668311733cSPierre-Alain TORET 	lockinit(&sc->smn_lock, device_get_nameunit(dev), 0, 0);
2678311733cSPierre-Alain TORET 	return (0);
2688311733cSPierre-Alain TORET }
2698311733cSPierre-Alain TORET 
2708311733cSPierre-Alain TORET int
amdsmn_detach(device_t dev)2718311733cSPierre-Alain TORET amdsmn_detach(device_t dev)
2728311733cSPierre-Alain TORET {
2738311733cSPierre-Alain TORET 	struct amdsmn_softc *sc = device_get_softc(dev);
2748311733cSPierre-Alain TORET 
2758311733cSPierre-Alain TORET 	lockuninit(&sc->smn_lock);
2768311733cSPierre-Alain TORET 	return (0);
2778311733cSPierre-Alain TORET }
2788311733cSPierre-Alain TORET 
2798311733cSPierre-Alain TORET int
amdsmn_read(device_t dev,uint32_t addr,uint32_t * value)2808311733cSPierre-Alain TORET amdsmn_read(device_t dev, uint32_t addr, uint32_t *value)
2818311733cSPierre-Alain TORET {
2828311733cSPierre-Alain TORET 	struct amdsmn_softc *sc = device_get_softc(dev);
2838311733cSPierre-Alain TORET 	device_t parent;
2848311733cSPierre-Alain TORET 
2858311733cSPierre-Alain TORET 	parent = device_get_parent(dev);
2868311733cSPierre-Alain TORET 
2878311733cSPierre-Alain TORET 	lockmgr(&sc->smn_lock, LK_EXCLUSIVE);
2888311733cSPierre-Alain TORET 	pci_write_config(parent, sc->smn_pciid->amdsmn_addr_reg, addr, 4);
2898311733cSPierre-Alain TORET 	*value = pci_read_config(parent, sc->smn_pciid->amdsmn_data_reg, 4);
2908311733cSPierre-Alain TORET 	lockmgr(&sc->smn_lock, LK_RELEASE);
2918311733cSPierre-Alain TORET 
2928311733cSPierre-Alain TORET 	return (0);
2938311733cSPierre-Alain TORET }
2948311733cSPierre-Alain TORET 
2958311733cSPierre-Alain TORET int
amdsmn_write(device_t dev,uint32_t addr,uint32_t value)2968311733cSPierre-Alain TORET amdsmn_write(device_t dev, uint32_t addr, uint32_t value)
2978311733cSPierre-Alain TORET {
2988311733cSPierre-Alain TORET 	struct amdsmn_softc *sc = device_get_softc(dev);
2998311733cSPierre-Alain TORET 	device_t parent;
3008311733cSPierre-Alain TORET 
3018311733cSPierre-Alain TORET 	parent = device_get_parent(dev);
3028311733cSPierre-Alain TORET 
3038311733cSPierre-Alain TORET 	lockmgr(&sc->smn_lock, LK_EXCLUSIVE);
3048311733cSPierre-Alain TORET 	pci_write_config(parent, sc->smn_pciid->amdsmn_addr_reg, addr, 4);
3058311733cSPierre-Alain TORET 	pci_write_config(parent, sc->smn_pciid->amdsmn_data_reg, value, 4);
3068311733cSPierre-Alain TORET 	lockmgr(&sc->smn_lock, LK_RELEASE);
3078311733cSPierre-Alain TORET 
3088311733cSPierre-Alain TORET 	return (0);
3098311733cSPierre-Alain TORET }
310