viapm.c revision 272017
1259698Sdim/*-
2259698Sdim * Copyright (c) 2001 Alcove - Nicolas Souchu
3259698Sdim * All rights reserved.
4259698Sdim *
5259698Sdim * Redistribution and use in source and binary forms, with or without
6259698Sdim * modification, are permitted provided that the following conditions
7259698Sdim * are met:
8259698Sdim * 1. Redistributions of source code must retain the above copyright
9259698Sdim *    notice, this list of conditions and the following disclaimer.
10259698Sdim * 2. Redistributions in binary form must reproduce the above copyright
11259698Sdim *    notice, this list of conditions and the following disclaimer in the
12259698Sdim *    documentation and/or other materials provided with the distribution.
13259698Sdim *
14259698Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15259698Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16259698Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17259698Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18259698Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19259698Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20259698Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21259698Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22259698Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23259698Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24259698Sdim * SUCH DAMAGE.
25259698Sdim */
26259698Sdim
27259698Sdim#include <sys/cdefs.h>
28259698Sdim__FBSDID("$FreeBSD: head/sys/dev/viapm/viapm.c 272017 2014-09-23 06:31:15Z rpaulo $");
29259698Sdim
30259698Sdim#include "opt_isa.h"
31259698Sdim
32259698Sdim#include <sys/param.h>
33259698Sdim#include <sys/bus.h>
34259698Sdim#include <sys/kernel.h>
35259698Sdim#include <sys/lock.h>
36259698Sdim#include <sys/module.h>
37259698Sdim#include <sys/mutex.h>
38259698Sdim#include <sys/systm.h>
39259698Sdim
40259698Sdim#include <machine/bus.h>
41259698Sdim#include <machine/resource.h>
42259698Sdim#include <sys/rman.h>
43259698Sdim
44259698Sdim#ifdef DEV_ISA
45259698Sdim#include <isa/isavar.h>
46259698Sdim#include <isa/isa_common.h>
47259698Sdim#endif
48259698Sdim#include <dev/pci/pcivar.h>
49259698Sdim#include <dev/pci/pcireg.h>
50259698Sdim
51259698Sdim#include <dev/iicbus/iiconf.h>
52259698Sdim
53259698Sdim#include <dev/smbus/smbconf.h>
54259698Sdim
55259698Sdim#include "iicbb_if.h"
56259698Sdim#include "smbus_if.h"
57259698Sdim
58259698Sdim#define VIAPM_DEBUG(x)	if (viapm_debug) (x)
59259698Sdim
60259698Sdim#ifdef DEBUG
61259698Sdimstatic int viapm_debug = 1;
62259698Sdim#else
63259698Sdimstatic int viapm_debug = 0;
64259698Sdim#endif
65259698Sdim
66259698Sdim#define VIA_586B_PMU_ID		0x30401106
67259698Sdim#define VIA_596A_PMU_ID		0x30501106
68259698Sdim#define VIA_596B_PMU_ID		0x30511106
69259698Sdim#define VIA_686A_PMU_ID		0x30571106
70259698Sdim#define VIA_8233_PMU_ID		0x30741106
71259698Sdim#define	VIA_8233A_PMU_ID	0x31471106
72259698Sdim#define	VIA_8235_PMU_ID		0x31771106
73259698Sdim#define	VIA_8237_PMU_ID		0x32271106
74259698Sdim#define	VIA_CX700_PMU_ID	0x83241106
75259698Sdim
76259698Sdim#define VIAPM_INB(port) \
77259698Sdim	((u_char)bus_read_1(viapm->iores, port))
78259698Sdim#define VIAPM_OUTB(port,val) \
79259698Sdim	(bus_write_1(viapm->iores, port, (u_char)(val)))
80259698Sdim
81259698Sdim#define VIAPM_TYP_UNKNOWN	0
82259698Sdim#define VIAPM_TYP_586B_3040E	1
83259698Sdim#define VIAPM_TYP_586B_3040F	2
84259698Sdim#define VIAPM_TYP_596B		3
85259698Sdim#define VIAPM_TYP_686A		4
86259698Sdim#define VIAPM_TYP_8233		5
87259698Sdim
88259698Sdim#define	VIAPM_LOCK(sc)		mtx_lock(&(sc)->lock)
89259698Sdim#define	VIAPM_UNLOCK(sc)	mtx_unlock(&(sc)->lock)
90259698Sdim#define	VIAPM_LOCK_ASSERT(sc)	mtx_assert(&(sc)->lock, MA_OWNED)
91259698Sdim
92259698Sdimstruct viapm_softc {
93259698Sdim	int type;
94259698Sdim	u_int32_t base;
95259698Sdim	int iorid;
96259698Sdim	int irqrid;
97259698Sdim	struct resource *iores;
98259698Sdim	struct resource *irqres;
99259698Sdim	void *irqih;
100259698Sdim	device_t iicbb;
101259698Sdim	device_t smbus;
102259698Sdim	struct mtx lock;
103259698Sdim};
104259698Sdim
105259698Sdimstatic devclass_t viapm_devclass;
106259698Sdimstatic devclass_t viapropm_devclass;
107259698Sdim
108259698Sdim/*
109259698Sdim * VT82C586B definitions
110259698Sdim */
111259698Sdim
112259698Sdim#define VIAPM_586B_REVID	0x08
113259698Sdim
114259698Sdim#define VIAPM_586B_3040E_BASE	0x20
115259698Sdim#define VIAPM_586B_3040E_ACTIV	0x4		/* 16 bits */
116259698Sdim
117259698Sdim#define VIAPM_586B_3040F_BASE	0x48
118259698Sdim#define VIAPM_586B_3040F_ACTIV	0x41		/* 8 bits */
119259698Sdim
120259698Sdim#define VIAPM_586B_OEM_REV_E	0x00
121259698Sdim#define VIAPM_586B_OEM_REV_F	0x01
122259698Sdim#define VIAPM_586B_PROD_REV_A	0x10
123259698Sdim
124259698Sdim#define VIAPM_586B_BA_MASK	0x0000ff00
125259698Sdim
126259698Sdim#define GPIO_DIR	0x40
127259698Sdim#define GPIO_VAL	0x42
128259698Sdim#define EXTSMI_VAL	0x44
129259698Sdim
130259698Sdim#define VIAPM_SCL	0x02			/* GPIO1_VAL */
131259698Sdim#define VIAPM_SDA	0x04			/* GPIO2_VAL */
132259698Sdim
133259698Sdim/*
134259698Sdim * VIAPRO common definitions
135259698Sdim */
136259698Sdim
137259698Sdim#define VIAPM_PRO_BA_MASK	0x0000fff0
138259698Sdim#define VIAPM_PRO_SMBCTRL	0xd2
139259698Sdim#define VIAPM_PRO_REVID		0xd6
140259698Sdim
141259698Sdim/*
142259698Sdim * VT82C686A definitions
143259698Sdim */
144259698Sdim
145259698Sdim#define VIAPM_PRO_BASE		0x90
146259698Sdim
147259698Sdim#define SMBHST			0x0
148259698Sdim#define SMBHSL			0x1
149259698Sdim#define SMBHCTRL		0x2
150259698Sdim#define SMBHCMD			0x3
151259698Sdim#define SMBHADDR		0x4
152259698Sdim#define SMBHDATA0		0x5
153259698Sdim#define SMBHDATA1		0x6
154259698Sdim#define SMBHBLOCK		0x7
155259698Sdim
156259698Sdim#define SMBSST			0x1
157259698Sdim#define SMBSCTRL		0x8
158259698Sdim#define SMBSSDWCMD		0x9
159259698Sdim#define SMBSEVENT		0xa
160259698Sdim#define SMBSDATA		0xc
161259698Sdim
162259698Sdim#define SMBHST_RESERVED		0xef	/* reserved bits */
163259698Sdim#define SMBHST_FAILED		0x10	/* failed bus transaction */
164259698Sdim#define SMBHST_COLLID		0x08	/* bus collision */
165259698Sdim#define SMBHST_ERROR		0x04	/* device error */
166259698Sdim#define SMBHST_INTR		0x02	/* command completed */
167259698Sdim#define SMBHST_BUSY		0x01	/* host busy */
168259698Sdim
169259698Sdim#define SMBHCTRL_START		0x40	/* start command */
170259698Sdim#define SMBHCTRL_PROTO		0x1c	/* command protocol mask */
171259698Sdim#define SMBHCTRL_QUICK		0x00
172259698Sdim#define SMBHCTRL_SENDRECV	0x04
173259698Sdim#define SMBHCTRL_BYTE		0x08
174259698Sdim#define SMBHCTRL_WORD		0x0c
175259698Sdim#define SMBHCTRL_BLOCK		0x14
176259698Sdim#define SMBHCTRL_KILL		0x02	/* stop the current transaction */
177259698Sdim#define SMBHCTRL_ENABLE		0x01	/* enable interrupts */
178259698Sdim
179259698Sdim#define SMBSCTRL_ENABLE		0x01	/* enable slave */
180259698Sdim
181259698Sdim
182259698Sdim/*
183259698Sdim * VIA8233 definitions
184259698Sdim */
185259698Sdim
186259698Sdim#define VIAPM_8233_BASE		0xD0
187259698Sdim
188259698Sdimstatic int
189259698Sdimviapm_586b_probe(device_t dev)
190259698Sdim{
191259698Sdim	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
192259698Sdim	u_int32_t l;
193259698Sdim	u_int16_t s;
194259698Sdim	u_int8_t c;
195259698Sdim
196259698Sdim	switch (pci_get_devid(dev)) {
197259698Sdim	case VIA_586B_PMU_ID:
198259698Sdim
199259698Sdim		bzero(viapm, sizeof(struct viapm_softc));
200259698Sdim
201259698Sdim		l = pci_read_config(dev, VIAPM_586B_REVID, 1);
202259698Sdim		switch (l) {
203259698Sdim		case VIAPM_586B_OEM_REV_E:
204259698Sdim			viapm->type = VIAPM_TYP_586B_3040E;
205259698Sdim			viapm->iorid = VIAPM_586B_3040E_BASE;
206259698Sdim
207259698Sdim			/* Activate IO block access */
208259698Sdim			s = pci_read_config(dev, VIAPM_586B_3040E_ACTIV, 2);
209259698Sdim			pci_write_config(dev, VIAPM_586B_3040E_ACTIV, s | 0x1, 2);
210259698Sdim			break;
211259698Sdim
212259698Sdim		case VIAPM_586B_OEM_REV_F:
213259698Sdim		case VIAPM_586B_PROD_REV_A:
214259698Sdim		default:
215259698Sdim			viapm->type = VIAPM_TYP_586B_3040F;
216259698Sdim			viapm->iorid = VIAPM_586B_3040F_BASE;
217259698Sdim
218259698Sdim			/* Activate IO block access */
219259698Sdim			c = pci_read_config(dev, VIAPM_586B_3040F_ACTIV, 1);
220259698Sdim			pci_write_config(dev, VIAPM_586B_3040F_ACTIV, c | 0x80, 1);
221259698Sdim			break;
222259698Sdim		}
223259698Sdim
224259698Sdim		viapm->base = pci_read_config(dev, viapm->iorid, 4) &
225259698Sdim				VIAPM_586B_BA_MASK;
226259698Sdim
227259698Sdim		/*
228259698Sdim		 * We have to set the I/O resources by hand because it is
229259698Sdim		 * described outside the viapmope of the traditional maps
230259698Sdim		 */
231259698Sdim		if (bus_set_resource(dev, SYS_RES_IOPORT, viapm->iorid,
232259698Sdim							viapm->base, 256)) {
233259698Sdim			device_printf(dev, "could not set bus resource\n");
234259698Sdim			return ENXIO;
235259698Sdim		}
236259698Sdim		device_set_desc(dev, "VIA VT82C586B Power Management Unit");
237259698Sdim		return (BUS_PROBE_DEFAULT);
238259698Sdim
239259698Sdim	default:
240259698Sdim		break;
241259698Sdim	}
242259698Sdim
243259698Sdim	return ENXIO;
244259698Sdim}
245259698Sdim
246259698Sdim
247259698Sdimstatic int
248259698Sdimviapm_pro_probe(device_t dev)
249259698Sdim{
250259698Sdim	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
251259698Sdim#ifdef VIAPM_BASE_ADDR
252259698Sdim	u_int32_t l;
253259698Sdim#endif
254259698Sdim	u_int32_t base_cfgreg;
255259698Sdim	char *desc;
256259698Sdim
257259698Sdim	switch (pci_get_devid(dev)) {
258259698Sdim	case VIA_596A_PMU_ID:
259259698Sdim		desc = "VIA VT82C596A Power Management Unit";
260259698Sdim		viapm->type = VIAPM_TYP_596B;
261259698Sdim		base_cfgreg = VIAPM_PRO_BASE;
262259698Sdim		goto viapro;
263259698Sdim
264259698Sdim	case VIA_596B_PMU_ID:
265259698Sdim		desc = "VIA VT82C596B Power Management Unit";
266259698Sdim		viapm->type = VIAPM_TYP_596B;
267259698Sdim		base_cfgreg = VIAPM_PRO_BASE;
268259698Sdim		goto viapro;
269259698Sdim
270259698Sdim	case VIA_686A_PMU_ID:
271259698Sdim		desc = "VIA VT82C686A Power Management Unit";
272259698Sdim		viapm->type = VIAPM_TYP_686A;
273259698Sdim		base_cfgreg = VIAPM_PRO_BASE;
274259698Sdim		goto viapro;
275259698Sdim
276259698Sdim	case VIA_8233_PMU_ID:
277259698Sdim	case VIA_8233A_PMU_ID:
278259698Sdim		desc = "VIA VT8233 Power Management Unit";
279259698Sdim		viapm->type = VIAPM_TYP_UNKNOWN;
280259698Sdim		base_cfgreg = VIAPM_8233_BASE;
281259698Sdim		goto viapro;
282259698Sdim
283259698Sdim	case VIA_8235_PMU_ID:
284259698Sdim		desc = "VIA VT8235 Power Management Unit";
285259698Sdim		viapm->type = VIAPM_TYP_UNKNOWN;
286259698Sdim		base_cfgreg = VIAPM_8233_BASE;
287259698Sdim		goto viapro;
288259698Sdim
289259698Sdim	case VIA_8237_PMU_ID:
290259698Sdim		desc = "VIA VT8237 Power Management Unit";
291259698Sdim		viapm->type = VIAPM_TYP_UNKNOWN;
292259698Sdim		base_cfgreg = VIAPM_8233_BASE;
293259698Sdim		goto viapro;
294259698Sdim
295259698Sdim	case VIA_CX700_PMU_ID:
296259698Sdim		desc = "VIA CX700 Power Management Unit";
297259698Sdim		viapm->type = VIAPM_TYP_UNKNOWN;
298259698Sdim		base_cfgreg = VIAPM_8233_BASE;
299259698Sdim		goto viapro;
300259698Sdim
301259698Sdim	viapro:
302259698Sdim
303259698Sdim#ifdef VIAPM_BASE_ADDR
304259698Sdim		/* force VIAPM I/O base address */
305259698Sdim
306259698Sdim		/* enable the SMBus controller function */
307259698Sdim		l = pci_read_config(dev, VIAPM_PRO_SMBCTRL, 1);
308259698Sdim		pci_write_config(dev, VIAPM_PRO_SMBCTRL, l | 1, 1);
309259698Sdim
310259698Sdim		/* write the base address */
311259698Sdim		pci_write_config(dev, base_cfgreg,
312259698Sdim				 VIAPM_BASE_ADDR & VIAPM_PRO_BA_MASK, 4);
313259698Sdim#endif
314259698Sdim
315259698Sdim		viapm->base = pci_read_config(dev, base_cfgreg, 4) & VIAPM_PRO_BA_MASK;
316259698Sdim
317259698Sdim		/*
318259698Sdim		 * We have to set the I/O resources by hand because it is
319259698Sdim		 * described outside the viapmope of the traditional maps
320259698Sdim		 */
321259698Sdim		viapm->iorid = base_cfgreg;
322259698Sdim		if (bus_set_resource(dev, SYS_RES_IOPORT, viapm->iorid,
323259698Sdim				     viapm->base, 16)) {
324259698Sdim			device_printf(dev, "could not set bus resource 0x%x\n",
325259698Sdim					viapm->base);
326259698Sdim			return ENXIO;
327259698Sdim		}
328259698Sdim
329259698Sdim		if (bootverbose) {
330259698Sdim			device_printf(dev, "SMBus I/O base at 0x%x\n", viapm->base);
331259698Sdim		}
332259698Sdim
333259698Sdim		device_set_desc(dev, desc);
334259698Sdim		return (BUS_PROBE_DEFAULT);
335259698Sdim
336259698Sdim	default:
337259698Sdim		break;
338259698Sdim	}
339259698Sdim
340259698Sdim	return ENXIO;
341259698Sdim}
342259698Sdim
343259698Sdimstatic int
344259698Sdimviapm_pro_attach(device_t dev)
345259698Sdim{
346259698Sdim	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
347259698Sdim	u_int32_t l;
348259698Sdim
349259698Sdim	mtx_init(&viapm->lock, device_get_nameunit(dev), "viapm", MTX_DEF);
350259698Sdim	if (!(viapm->iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
351259698Sdim		&viapm->iorid, RF_ACTIVE))) {
352259698Sdim		device_printf(dev, "could not allocate bus space\n");
353259698Sdim		goto error;
354259698Sdim	}
355259698Sdim
356259698Sdim#ifdef notyet
357259698Sdim	/* force irq 9 */
358259698Sdim	l = pci_read_config(dev, VIAPM_PRO_SMBCTRL, 1);
359259698Sdim	pci_write_config(dev, VIAPM_PRO_SMBCTRL, l | 0x80, 1);
360259698Sdim
361259698Sdim	viapm->irqrid = 0;
362259698Sdim	if (!(viapm->irqres = bus_alloc_resource(dev, SYS_RES_IRQ,
363259698Sdim				&viapm->irqrid, 9, 9, 1,
364259698Sdim				RF_SHAREABLE | RF_ACTIVE))) {
365259698Sdim		device_printf(dev, "could not allocate irq\n");
366259698Sdim		goto error;
367259698Sdim	}
368259698Sdim
369259698Sdim	if (bus_setup_intr(dev, viapm->irqres, INTR_TYPE_MISC | INTR_MPSAFE,
370259698Sdim			(driver_intr_t *) viasmb_intr, viapm, &viapm->irqih)) {
371259698Sdim		device_printf(dev, "could not setup irq\n");
372259698Sdim		goto error;
373259698Sdim	}
374259698Sdim#endif
375259698Sdim
376259698Sdim	if (bootverbose) {
377259698Sdim		l = pci_read_config(dev, VIAPM_PRO_REVID, 1);
378259698Sdim		device_printf(dev, "SMBus revision code 0x%x\n", l);
379259698Sdim	}
380259698Sdim
381259698Sdim	viapm->smbus = device_add_child(dev, "smbus", -1);
382259698Sdim
383259698Sdim	/* probe and attach the smbus */
384259698Sdim	bus_generic_attach(dev);
385259698Sdim
386259698Sdim	/* disable slave function */
387259698Sdim	VIAPM_OUTB(SMBSCTRL, VIAPM_INB(SMBSCTRL) & ~SMBSCTRL_ENABLE);
388259698Sdim
389259698Sdim	/* enable the SMBus controller function */
390259698Sdim	l = pci_read_config(dev, VIAPM_PRO_SMBCTRL, 1);
391259698Sdim	pci_write_config(dev, VIAPM_PRO_SMBCTRL, l | 1, 1);
392259698Sdim
393259698Sdim#ifdef notyet
394259698Sdim	/* enable interrupts */
395259698Sdim	VIAPM_OUTB(SMBHCTRL, VIAPM_INB(SMBHCTRL) | SMBHCTRL_ENABLE);
396259698Sdim#endif
397259698Sdim
398259698Sdim#ifdef DEV_ISA
399259698Sdim	/* If this device is a PCI-ISA bridge, then attach an ISA bus. */
400259698Sdim	if ((pci_get_class(dev) == PCIC_BRIDGE) &&
401259698Sdim	    (pci_get_subclass(dev) == PCIS_BRIDGE_ISA))
402259698Sdim		isab_attach(dev);
403259698Sdim#endif
404259698Sdim	return 0;
405259698Sdim
406259698Sdimerror:
407259698Sdim	if (viapm->iores)
408259698Sdim		bus_release_resource(dev, SYS_RES_IOPORT, viapm->iorid, viapm->iores);
409259698Sdim#ifdef notyet
410259698Sdim	if (viapm->irqres)
411259698Sdim		bus_release_resource(dev, SYS_RES_IRQ, viapm->irqrid, viapm->irqres);
412259698Sdim#endif
413259698Sdim	mtx_destroy(&viapm->lock);
414259698Sdim
415259698Sdim	return ENXIO;
416259698Sdim}
417259698Sdim
418259698Sdimstatic int
419259698Sdimviapm_586b_attach(device_t dev)
420259698Sdim{
421259698Sdim	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
422259698Sdim
423259698Sdim	mtx_init(&viapm->lock, device_get_nameunit(dev), "viapm", MTX_DEF);
424259698Sdim	if (!(viapm->iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
425259698Sdim		&viapm->iorid, RF_ACTIVE | RF_SHAREABLE))) {
426259698Sdim		device_printf(dev, "could not allocate bus resource\n");
427259698Sdim		goto error;
428259698Sdim	}
429259698Sdim
430259698Sdim	VIAPM_OUTB(GPIO_DIR, VIAPM_INB(GPIO_DIR) | VIAPM_SCL | VIAPM_SDA);
431259698Sdim
432259698Sdim	/* add generic bit-banging code */
433259698Sdim	if (!(viapm->iicbb = device_add_child(dev, "iicbb", -1)))
434259698Sdim		goto error;
435259698Sdim
436259698Sdim	bus_generic_attach(dev);
437259698Sdim
438259698Sdim	return 0;
439259698Sdim
440259698Sdimerror:
441259698Sdim	if (viapm->iores)
442259698Sdim		bus_release_resource(dev, SYS_RES_IOPORT,
443259698Sdim					viapm->iorid, viapm->iores);
444259698Sdim	mtx_destroy(&viapm->lock);
445259698Sdim	return ENXIO;
446259698Sdim}
447259698Sdim
448259698Sdimstatic int
449259698Sdimviapm_586b_detach(device_t dev)
450259698Sdim{
451259698Sdim	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
452259698Sdim
453259698Sdim	bus_generic_detach(dev);
454259698Sdim	if (viapm->iicbb) {
455259698Sdim		device_delete_child(dev, viapm->iicbb);
456259698Sdim	}
457259698Sdim
458259698Sdim	if (viapm->iores)
459259698Sdim		bus_release_resource(dev, SYS_RES_IOPORT, viapm->iorid,
460259698Sdim		    viapm->iores);
461259698Sdim	mtx_destroy(&viapm->lock);
462259698Sdim
463259698Sdim	return 0;
464259698Sdim}
465259698Sdim
466259698Sdimstatic int
467259698Sdimviapm_pro_detach(device_t dev)
468259698Sdim{
469259698Sdim	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
470259698Sdim
471259698Sdim	bus_generic_detach(dev);
472259698Sdim	if (viapm->smbus) {
473259698Sdim		device_delete_child(dev, viapm->smbus);
474259698Sdim	}
475259698Sdim
476259698Sdim	bus_release_resource(dev, SYS_RES_IOPORT, viapm->iorid, viapm->iores);
477259698Sdim
478259698Sdim#ifdef notyet
479259698Sdim	bus_release_resource(dev, SYS_RES_IRQ, viapm->irqrid, viapm->irqres);
480259698Sdim#endif
481259698Sdim	mtx_destroy(&viapm->lock);
482259698Sdim
483259698Sdim	return 0;
484259698Sdim}
485259698Sdim
486259698Sdimstatic int
487259698Sdimviabb_callback(device_t dev, int index, caddr_t data)
488259698Sdim{
489259698Sdim	return 0;
490259698Sdim}
491259698Sdim
492259698Sdimstatic void
493259698Sdimviabb_setscl(device_t dev, int ctrl)
494259698Sdim{
495259698Sdim	struct viapm_softc *viapm = device_get_softc(dev);
496259698Sdim	u_char val;
497259698Sdim
498259698Sdim	VIAPM_LOCK(viapm);
499259698Sdim	val = VIAPM_INB(GPIO_VAL);
500259698Sdim
501259698Sdim	if (ctrl)
502259698Sdim		val |= VIAPM_SCL;
503259698Sdim	else
504259698Sdim		val &= ~VIAPM_SCL;
505259698Sdim
506259698Sdim	VIAPM_OUTB(GPIO_VAL, val);
507259698Sdim	VIAPM_UNLOCK(viapm);
508259698Sdim
509259698Sdim	return;
510259698Sdim}
511259698Sdim
512259698Sdimstatic void
513259698Sdimviabb_setsda(device_t dev, int data)
514259698Sdim{
515259698Sdim	struct viapm_softc *viapm = device_get_softc(dev);
516259698Sdim	u_char val;
517259698Sdim
518259698Sdim	VIAPM_LOCK(viapm);
519259698Sdim	val = VIAPM_INB(GPIO_VAL);
520259698Sdim
521259698Sdim	if (data)
522259698Sdim		val |= VIAPM_SDA;
523259698Sdim	else
524259698Sdim		val &= ~VIAPM_SDA;
525259698Sdim
526259698Sdim	VIAPM_OUTB(GPIO_VAL, val);
527259698Sdim	VIAPM_UNLOCK(viapm);
528259698Sdim
529259698Sdim	return;
530259698Sdim}
531259698Sdim
532259698Sdimstatic int
533259698Sdimviabb_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
534259698Sdim{
535259698Sdim	/* reset bus */
536259698Sdim	viabb_setsda(dev, 1);
537259698Sdim	viabb_setscl(dev, 1);
538259698Sdim
539259698Sdim	return (IIC_ENOADDR);
540259698Sdim}
541259698Sdim
542259698Sdimstatic int
543259698Sdimviabb_getscl(device_t dev)
544259698Sdim{
545259698Sdim	struct viapm_softc *viapm = device_get_softc(dev);
546259698Sdim	u_char val;
547259698Sdim
548259698Sdim	VIAPM_LOCK(viapm);
549259698Sdim	val = VIAPM_INB(EXTSMI_VAL);
550259698Sdim	VIAPM_UNLOCK(viapm);
551259698Sdim	return ((val & VIAPM_SCL) != 0);
552259698Sdim}
553259698Sdim
554259698Sdimstatic int
555259698Sdimviabb_getsda(device_t dev)
556259698Sdim{
557259698Sdim	struct viapm_softc *viapm = device_get_softc(dev);
558259698Sdim	u_char val;
559259698Sdim
560259698Sdim	VIAPM_LOCK(viapm);
561259698Sdim	val = VIAPM_INB(EXTSMI_VAL);
562259698Sdim	VIAPM_UNLOCK(viapm);
563259698Sdim	return ((val & VIAPM_SDA) != 0);
564259698Sdim}
565259698Sdim
566259698Sdimstatic int
567259698Sdimviapm_abort(struct viapm_softc *viapm)
568259698Sdim{
569259698Sdim	VIAPM_OUTB(SMBHCTRL, SMBHCTRL_KILL);
570259698Sdim	DELAY(10);
571259698Sdim
572259698Sdim	return (0);
573259698Sdim}
574259698Sdim
575259698Sdimstatic int
576259698Sdimviapm_clear(struct viapm_softc *viapm)
577259698Sdim{
578259698Sdim	VIAPM_OUTB(SMBHST, SMBHST_FAILED | SMBHST_COLLID |
579259698Sdim		SMBHST_ERROR | SMBHST_INTR);
580259698Sdim	DELAY(10);
581259698Sdim
582259698Sdim	return (0);
583259698Sdim}
584259698Sdim
585259698Sdimstatic int
586259698Sdimviapm_busy(struct viapm_softc *viapm)
587259698Sdim{
588259698Sdim	u_char sts;
589259698Sdim
590259698Sdim	sts = VIAPM_INB(SMBHST);
591259698Sdim
592259698Sdim	VIAPM_DEBUG(printf("viapm: idle? STS=0x%x\n", sts));
593259698Sdim
594259698Sdim	return (sts & SMBHST_BUSY);
595259698Sdim}
596259698Sdim
597259698Sdim/*
598259698Sdim * Poll the SMBus controller
599259698Sdim */
600259698Sdimstatic int
601259698Sdimviapm_wait(struct viapm_softc *viapm)
602259698Sdim{
603259698Sdim	int count = 10000;
604259698Sdim	u_char sts = 0;
605259698Sdim	int error;
606259698Sdim
607259698Sdim	VIAPM_LOCK_ASSERT(viapm);
608259698Sdim
609259698Sdim	/* wait for command to complete and SMBus controller is idle */
610259698Sdim	while(count--) {
611259698Sdim		DELAY(10);
612259698Sdim		sts = VIAPM_INB(SMBHST);
613259698Sdim
614259698Sdim		/* check if the controller is processing a command */
615259698Sdim		if (!(sts & SMBHST_BUSY) && (sts & SMBHST_INTR))
616259698Sdim			break;
617259698Sdim	}
618259698Sdim
619259698Sdim	VIAPM_DEBUG(printf("viapm: SMBHST=0x%x\n", sts));
620259698Sdim
621259698Sdim	error = SMB_ENOERR;
622259698Sdim
623259698Sdim	if (!count)
624259698Sdim		error |= SMB_ETIMEOUT;
625259698Sdim
626259698Sdim	if (sts & SMBHST_FAILED)
627259698Sdim		error |= SMB_EABORT;
628259698Sdim
629259698Sdim	if (sts & SMBHST_COLLID)
630259698Sdim		error |= SMB_ENOACK;
631259698Sdim
632259698Sdim	if (sts & SMBHST_ERROR)
633259698Sdim		error |= SMB_EBUSERR;
634259698Sdim
635259698Sdim	if (error != SMB_ENOERR)
636259698Sdim		viapm_abort(viapm);
637259698Sdim
638259698Sdim	viapm_clear(viapm);
639259698Sdim
640259698Sdim	return (error);
641259698Sdim}
642259698Sdim
643259698Sdimstatic int
644259698Sdimviasmb_callback(device_t dev, int index, void *data)
645259698Sdim{
646259698Sdim	int error = 0;
647259698Sdim
648259698Sdim	switch (index) {
649259698Sdim	case SMB_REQUEST_BUS:
650259698Sdim	case SMB_RELEASE_BUS:
651259698Sdim		/* ok, bus allocation accepted */
652259698Sdim		break;
653259698Sdim	default:
654259698Sdim		error = EINVAL;
655259698Sdim	}
656259698Sdim
657259698Sdim	return (error);
658259698Sdim}
659259698Sdim
660259698Sdimstatic int
661259698Sdimviasmb_quick(device_t dev, u_char slave, int how)
662259698Sdim{
663259698Sdim	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
664259698Sdim	int error;
665259698Sdim
666259698Sdim	VIAPM_LOCK(viapm);
667259698Sdim	viapm_clear(viapm);
668259698Sdim	if (viapm_busy(viapm)) {
669259698Sdim		VIAPM_UNLOCK(viapm);
670259698Sdim		return (SMB_EBUSY);
671259698Sdim	}
672259698Sdim
673259698Sdim	switch (how) {
674259698Sdim	case SMB_QWRITE:
675259698Sdim		VIAPM_DEBUG(printf("viapm: QWRITE to 0x%x", slave));
676259698Sdim		VIAPM_OUTB(SMBHADDR, slave & ~LSB);
677259698Sdim		break;
678259698Sdim	case SMB_QREAD:
679259698Sdim		VIAPM_DEBUG(printf("viapm: QREAD to 0x%x", slave));
680259698Sdim		VIAPM_OUTB(SMBHADDR, slave | LSB);
681259698Sdim		break;
682259698Sdim	default:
683259698Sdim		panic("%s: unknown QUICK command (%x)!", __func__, how);
684259698Sdim	}
685259698Sdim
686259698Sdim	VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_QUICK);
687259698Sdim
688259698Sdim	error = viapm_wait(viapm);
689259698Sdim	VIAPM_UNLOCK(viapm);
690259698Sdim
691259698Sdim	return (error);
692259698Sdim}
693259698Sdim
694259698Sdimstatic int
695259698Sdimviasmb_sendb(device_t dev, u_char slave, char byte)
696259698Sdim{
697259698Sdim	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
698259698Sdim	int error;
699259698Sdim
700259698Sdim	VIAPM_LOCK(viapm);
701259698Sdim	viapm_clear(viapm);
702259698Sdim	if (viapm_busy(viapm)) {
703259698Sdim		VIAPM_UNLOCK(viapm);
704259698Sdim		return (SMB_EBUSY);
705259698Sdim	}
706259698Sdim
707259698Sdim	VIAPM_OUTB(SMBHADDR, slave & ~ LSB);
708259698Sdim	VIAPM_OUTB(SMBHCMD, byte);
709259698Sdim
710259698Sdim	VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_SENDRECV);
711259698Sdim
712259698Sdim	error = viapm_wait(viapm);
713259698Sdim
714259698Sdim	VIAPM_DEBUG(printf("viapm: SENDB to 0x%x, byte=0x%x, error=0x%x\n", slave, byte, error));
715259698Sdim	VIAPM_UNLOCK(viapm);
716259698Sdim
717259698Sdim	return (error);
718259698Sdim}
719259698Sdim
720259698Sdimstatic int
721259698Sdimviasmb_recvb(device_t dev, u_char slave, char *byte)
722259698Sdim{
723259698Sdim	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
724259698Sdim	int error;
725259698Sdim
726259698Sdim	VIAPM_LOCK(viapm);
727259698Sdim	viapm_clear(viapm);
728259698Sdim	if (viapm_busy(viapm)) {
729259698Sdim		VIAPM_UNLOCK(viapm);
730259698Sdim		return (SMB_EBUSY);
731259698Sdim	}
732259698Sdim
733259698Sdim	VIAPM_OUTB(SMBHADDR, slave | LSB);
734259698Sdim
735259698Sdim	VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_SENDRECV);
736259698Sdim
737259698Sdim	if ((error = viapm_wait(viapm)) == SMB_ENOERR)
738259698Sdim		*byte = VIAPM_INB(SMBHDATA0);
739259698Sdim
740259698Sdim	VIAPM_DEBUG(printf("viapm: RECVB from 0x%x, byte=0x%x, error=0x%x\n", slave, *byte, error));
741259698Sdim	VIAPM_UNLOCK(viapm);
742259698Sdim
743259698Sdim	return (error);
744259698Sdim}
745259698Sdim
746259698Sdimstatic int
747259698Sdimviasmb_writeb(device_t dev, u_char slave, char cmd, char byte)
748259698Sdim{
749259698Sdim	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
750259698Sdim	int error;
751259698Sdim
752259698Sdim	VIAPM_LOCK(viapm);
753259698Sdim	viapm_clear(viapm);
754259698Sdim	if (viapm_busy(viapm)) {
755259698Sdim		VIAPM_UNLOCK(viapm);
756259698Sdim		return (SMB_EBUSY);
757259698Sdim	}
758259698Sdim
759259698Sdim	VIAPM_OUTB(SMBHADDR, slave & ~ LSB);
760259698Sdim	VIAPM_OUTB(SMBHCMD, cmd);
761259698Sdim	VIAPM_OUTB(SMBHDATA0, byte);
762259698Sdim
763259698Sdim	VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BYTE);
764259698Sdim
765259698Sdim	error = viapm_wait(viapm);
766259698Sdim
767259698Sdim	VIAPM_DEBUG(printf("viapm: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error));
768259698Sdim	VIAPM_UNLOCK(viapm);
769259698Sdim
770259698Sdim	return (error);
771259698Sdim}
772259698Sdim
773259698Sdimstatic int
774259698Sdimviasmb_readb(device_t dev, u_char slave, char cmd, char *byte)
775259698Sdim{
776259698Sdim	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
777259698Sdim	int error;
778259698Sdim
779259698Sdim	VIAPM_LOCK(viapm);
780259698Sdim	viapm_clear(viapm);
781259698Sdim	if (viapm_busy(viapm)) {
782259698Sdim		VIAPM_UNLOCK(viapm);
783259698Sdim		return (SMB_EBUSY);
784259698Sdim	}
785259698Sdim
786259698Sdim	VIAPM_OUTB(SMBHADDR, slave | LSB);
787259698Sdim	VIAPM_OUTB(SMBHCMD, cmd);
788259698Sdim
789259698Sdim	VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BYTE);
790259698Sdim
791259698Sdim	if ((error = viapm_wait(viapm)) == SMB_ENOERR)
792259698Sdim		*byte = VIAPM_INB(SMBHDATA0);
793259698Sdim
794259698Sdim	VIAPM_DEBUG(printf("viapm: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, *byte, error));
795	VIAPM_UNLOCK(viapm);
796
797	return (error);
798}
799
800static int
801viasmb_writew(device_t dev, u_char slave, char cmd, short word)
802{
803	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
804	int error;
805
806	VIAPM_LOCK(viapm);
807	viapm_clear(viapm);
808	if (viapm_busy(viapm)) {
809		VIAPM_UNLOCK(viapm);
810		return (SMB_EBUSY);
811	}
812
813	VIAPM_OUTB(SMBHADDR, slave & ~ LSB);
814	VIAPM_OUTB(SMBHCMD, cmd);
815	VIAPM_OUTB(SMBHDATA0, word & 0x00ff);
816	VIAPM_OUTB(SMBHDATA1, (word & 0xff00) >> 8);
817
818	VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_WORD);
819
820	error = viapm_wait(viapm);
821
822	VIAPM_DEBUG(printf("viapm: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error));
823	VIAPM_UNLOCK(viapm);
824
825	return (error);
826}
827
828static int
829viasmb_readw(device_t dev, u_char slave, char cmd, short *word)
830{
831	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
832	int error;
833	u_char high, low;
834
835	VIAPM_LOCK(viapm);
836	viapm_clear(viapm);
837	if (viapm_busy(viapm)) {
838		VIAPM_UNLOCK(viapm);
839		return (SMB_EBUSY);
840	}
841
842	VIAPM_OUTB(SMBHADDR, slave | LSB);
843	VIAPM_OUTB(SMBHCMD, cmd);
844
845	VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_WORD);
846
847	if ((error = viapm_wait(viapm)) == SMB_ENOERR) {
848		low = VIAPM_INB(SMBHDATA0);
849		high = VIAPM_INB(SMBHDATA1);
850
851		*word = ((high & 0xff) << 8) | (low & 0xff);
852	}
853
854	VIAPM_DEBUG(printf("viapm: READW from 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, *word, error));
855	VIAPM_UNLOCK(viapm);
856
857	return (error);
858}
859
860static int
861viasmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
862{
863	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
864	u_char i;
865	int error;
866
867	if (count < 1 || count > 32)
868		return (SMB_EINVAL);
869
870	VIAPM_LOCK(viapm);
871	viapm_clear(viapm);
872	if (viapm_busy(viapm)) {
873		VIAPM_UNLOCK(viapm);
874		return (SMB_EBUSY);
875	}
876
877	VIAPM_OUTB(SMBHADDR, slave & ~LSB);
878	VIAPM_OUTB(SMBHCMD, cmd);
879	VIAPM_OUTB(SMBHDATA0, count);
880	i = VIAPM_INB(SMBHCTRL);
881
882	/* fill the 32-byte internal buffer */
883	for (i = 0; i < count; i++) {
884		VIAPM_OUTB(SMBHBLOCK, buf[i]);
885		DELAY(2);
886	}
887	VIAPM_OUTB(SMBHCMD, cmd);
888	VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BLOCK);
889
890	error = viapm_wait(viapm);
891
892	VIAPM_DEBUG(printf("viapm: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
893	VIAPM_UNLOCK(viapm);
894
895	return (error);
896
897}
898
899static int
900viasmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
901{
902	struct viapm_softc *viapm = (struct viapm_softc *)device_get_softc(dev);
903	u_char data, len, i;
904	int error;
905
906	if (*count < 1 || *count > 32)
907		return (SMB_EINVAL);
908
909	VIAPM_LOCK(viapm);
910	viapm_clear(viapm);
911	if (viapm_busy(viapm)) {
912		VIAPM_UNLOCK(viapm);
913		return (SMB_EBUSY);
914	}
915
916	VIAPM_OUTB(SMBHADDR, slave | LSB);
917	VIAPM_OUTB(SMBHCMD, cmd);
918	VIAPM_OUTB(SMBHCTRL, SMBHCTRL_START | SMBHCTRL_BLOCK);
919
920	if ((error = viapm_wait(viapm)) != SMB_ENOERR)
921		goto error;
922
923	len = VIAPM_INB(SMBHDATA0);
924	i = VIAPM_INB(SMBHCTRL); 		/* reset counter */
925
926	/* read the 32-byte internal buffer */
927	for (i = 0; i < len; i++) {
928		data = VIAPM_INB(SMBHBLOCK);
929		if (i < *count)
930			buf[i] = data;
931		DELAY(2);
932	}
933	*count = len;
934
935error:
936	VIAPM_DEBUG(printf("viapm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error));
937	VIAPM_UNLOCK(viapm);
938
939	return (error);
940}
941
942static device_method_t viapm_methods[] = {
943	/* device interface */
944	DEVMETHOD(device_probe,		viapm_586b_probe),
945	DEVMETHOD(device_attach,	viapm_586b_attach),
946	DEVMETHOD(device_detach,	viapm_586b_detach),
947
948	/* iicbb interface */
949	DEVMETHOD(iicbb_callback,	viabb_callback),
950	DEVMETHOD(iicbb_setscl,		viabb_setscl),
951	DEVMETHOD(iicbb_setsda,		viabb_setsda),
952	DEVMETHOD(iicbb_getscl,		viabb_getscl),
953	DEVMETHOD(iicbb_getsda,		viabb_getsda),
954	DEVMETHOD(iicbb_reset,		viabb_reset),
955
956	/* Bus interface */
957	DEVMETHOD(bus_alloc_resource,	bus_generic_alloc_resource),
958	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
959	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
960	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
961	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
962	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
963
964	DEVMETHOD_END
965};
966
967static driver_t viapm_driver = {
968	"viapm",
969	viapm_methods,
970	sizeof(struct viapm_softc),
971};
972
973static device_method_t viapropm_methods[] = {
974	/* device interface */
975	DEVMETHOD(device_probe,		viapm_pro_probe),
976	DEVMETHOD(device_attach,	viapm_pro_attach),
977	DEVMETHOD(device_detach,	viapm_pro_detach),
978
979	/* smbus interface */
980	DEVMETHOD(smbus_callback,	viasmb_callback),
981	DEVMETHOD(smbus_quick,		viasmb_quick),
982	DEVMETHOD(smbus_sendb,		viasmb_sendb),
983	DEVMETHOD(smbus_recvb,		viasmb_recvb),
984	DEVMETHOD(smbus_writeb,		viasmb_writeb),
985	DEVMETHOD(smbus_readb,		viasmb_readb),
986	DEVMETHOD(smbus_writew,		viasmb_writew),
987	DEVMETHOD(smbus_readw,		viasmb_readw),
988	DEVMETHOD(smbus_bwrite,		viasmb_bwrite),
989	DEVMETHOD(smbus_bread,		viasmb_bread),
990
991	/* Bus interface */
992	DEVMETHOD(bus_alloc_resource,	bus_generic_alloc_resource),
993	DEVMETHOD(bus_release_resource,	bus_generic_release_resource),
994	DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
995	DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
996	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
997	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
998
999	DEVMETHOD_END
1000};
1001
1002static driver_t viapropm_driver = {
1003	"viapropm",
1004	viapropm_methods,
1005	sizeof(struct viapm_softc),
1006};
1007
1008DRIVER_MODULE(viapm, pci, viapm_driver, viapm_devclass, 0, 0);
1009DRIVER_MODULE(viapropm, pci, viapropm_driver, viapropm_devclass, 0, 0);
1010DRIVER_MODULE(iicbb, viapm, iicbb_driver, iicbb_devclass, 0, 0);
1011DRIVER_MODULE(smbus, viapropm, smbus_driver, smbus_devclass, 0, 0);
1012
1013MODULE_DEPEND(viapm, pci, 1, 1, 1);
1014MODULE_DEPEND(viapropm, pci, 1, 1, 1);
1015MODULE_DEPEND(viapm, iicbb, IICBB_MINVER, IICBB_PREFVER, IICBB_MAXVER);
1016MODULE_DEPEND(viapropm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
1017MODULE_VERSION(viapm, 1);
1018
1019#ifdef DEV_ISA
1020DRIVER_MODULE(isa, viapm, isa_driver, isa_devclass, 0, 0);
1021DRIVER_MODULE(isa, viapropm, isa_driver, isa_devclass, 0, 0);
1022MODULE_DEPEND(viapm, isa, 1, 1, 1);
1023MODULE_DEPEND(viapropm, isa, 1, 1, 1);
1024#endif
1025