Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Sep 2014 06:31:15 +0000 (UTC)
From:      Rui Paulo <rpaulo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r272017 - in head/sys: conf dev/alpm dev/amdpm dev/intpm dev/viapm modules/i2c/controllers/alpm modules/i2c/controllers/amdpm modules/i2c/controllers/intpm modules/i2c/controllers/viapm...
Message-ID:  <201409230631.s8N6VFlM085108@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rpaulo
Date: Tue Sep 23 06:31:15 2014
New Revision: 272017
URL: http://svnweb.freebsd.org/changeset/base/272017

Log:
  Move all the power management (SMBus) drivers to their own directory,
  away from sys/pci.

Added:
  head/sys/dev/alpm/
  head/sys/dev/alpm/alpm.c
     - copied unchanged from r272014, head/sys/pci/alpm.c
  head/sys/dev/amdpm/
  head/sys/dev/amdpm/amdpm.c
     - copied unchanged from r272014, head/sys/pci/amdpm.c
  head/sys/dev/intpm/
  head/sys/dev/intpm/intpm.c
     - copied, changed from r272014, head/sys/pci/intpm.c
  head/sys/dev/intpm/intpmreg.h
     - copied unchanged from r272014, head/sys/pci/intpmreg.h
  head/sys/dev/viapm/
  head/sys/dev/viapm/viapm.c
     - copied unchanged from r272014, head/sys/pci/viapm.c
Deleted:
  head/sys/pci/alpm.c
  head/sys/pci/amdpm.c
  head/sys/pci/intpm.c
  head/sys/pci/intpmreg.h
  head/sys/pci/viapm.c
Modified:
  head/sys/conf/files
  head/sys/modules/i2c/controllers/alpm/Makefile
  head/sys/modules/i2c/controllers/amdpm/Makefile
  head/sys/modules/i2c/controllers/intpm/Makefile
  head/sys/modules/i2c/controllers/viapm/Makefile

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Tue Sep 23 05:54:18 2014	(r272016)
+++ head/sys/conf/files	Tue Sep 23 06:31:15 2014	(r272017)
@@ -646,6 +646,7 @@ dev/aic7xxx/aic7xxx_pci.c	optional ahc p
 dev/aic7xxx/aic7xxx_reg_print.c	optional ahc ahc_reg_pretty_print
 dev/alc/if_alc.c		optional alc pci
 dev/ale/if_ale.c		optional ale pci
+dev/alpm/alpm.c			optional alpm pci
 dev/altera/avgen/altera_avgen.c		optional altera_avgen
 dev/altera/avgen/altera_avgen_fdt.c	optional altera_avgen fdt
 dev/altera/avgen/altera_avgen_nexus.c	optional altera_avgen
@@ -654,6 +655,7 @@ dev/altera/sdcard/altera_sdcard_disk.c	o
 dev/altera/sdcard/altera_sdcard_io.c	optional altera_sdcard
 dev/altera/sdcard/altera_sdcard_fdt.c	optional altera_sdcard fdt
 dev/altera/sdcard/altera_sdcard_nexus.c	optional altera_sdcard
+dev/amdpm/amdpm.c		optional amdpm pci | nfpm pci
 dev/amdsmb/amdsmb.c		optional amdsmb pci
 dev/amr/amr.c			optional amr
 dev/amr/amr_cam.c		optional amrp amr
@@ -1484,6 +1486,7 @@ dev/iicbus/s35390a.c		optional s35390a
 dev/iir/iir.c			optional iir
 dev/iir/iir_ctrl.c		optional iir
 dev/iir/iir_pci.c		optional iir pci
+dev/intpm/intpm.c		optional intpm pci
 # XXX Work around clang warning, until maintainer approves fix.
 dev/ips/ips.c			optional ips \
 	compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}"
@@ -2584,7 +2587,7 @@ dev/utopia/idtphy.c		optional utopia
 dev/utopia/suni.c		optional utopia
 dev/utopia/utopia.c		optional utopia
 dev/vge/if_vge.c		optional vge
-
+dev/viapm/viapm.c		optional viapm pci
 dev/vkbd/vkbd.c			optional vkbd
 dev/vr/if_vr.c			optional vr pci
 dev/vt/colors/vt_termcolors.c	optional vt
@@ -3868,10 +3871,6 @@ opencrypto/cryptodeflate.c	optional cryp
 opencrypto/rmd160.c		optional crypto | ipsec
 opencrypto/skipjack.c		optional crypto
 opencrypto/xform.c		optional crypto
-pci/alpm.c			optional alpm pci
-pci/amdpm.c			optional amdpm pci | nfpm pci
-pci/intpm.c			optional intpm pci
-pci/viapm.c			optional viapm pci
 rpc/auth_none.c			optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd
 rpc/auth_unix.c			optional krpc | nfslockd | nfsclient | nfscl | nfsd
 rpc/authunix_prot.c		optional krpc | nfslockd | nfsclient | nfsserver | nfscl | nfsd

Copied: head/sys/dev/alpm/alpm.c (from r272014, head/sys/pci/alpm.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/alpm/alpm.c	Tue Sep 23 06:31:15 2014	(r272017, copy of r272014, head/sys/pci/alpm.c)
@@ -0,0 +1,663 @@
+/*-
+ * Copyright (c) 1998, 1999, 2001 Nicolas Souchu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Power Management support for the Acer M15x3 chipsets
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+
+#include <dev/smbus/smbconf.h>
+#include "smbus_if.h"
+
+#define ALPM_DEBUG(x)	if (alpm_debug) (x)
+
+#ifdef DEBUG
+static int alpm_debug = 1;
+#else
+static int alpm_debug = 0;
+#endif
+
+#define ACER_M1543_PMU_ID	0x710110b9
+
+/*
+ * I/O registers offsets - the base address is programmed via the
+ * SMBBA PCI configuration register
+ */
+#define SMBSTS		0x0	/* SMBus host/slave status register */
+#define SMBCMD		0x1	/* SMBus host/slave command register */
+#define SMBSTART	0x2	/* start to generate programmed cycle */
+#define SMBHADDR	0x3	/* host address register */
+#define SMBHDATA	0x4	/* data A register for host controller */
+#define SMBHDATB	0x5	/* data B register for host controller */
+#define SMBHBLOCK	0x6	/* block register for host controller */
+#define SMBHCMD		0x7	/* command register for host controller */
+
+/* SMBHADDR mask. */
+#define	LSB		0x1	/* XXX: Better name: Read/Write? */
+
+/* SMBSTS masks */
+#define TERMINATE	0x80
+#define BUS_COLLI	0x40
+#define DEVICE_ERR	0x20
+#define SMI_I_STS	0x10
+#define HST_BSY		0x08
+#define IDL_STS		0x04
+#define HSTSLV_STS	0x02
+#define HSTSLV_BSY	0x01
+
+/* SMBCMD masks */
+#define SMB_BLK_CLR	0x80
+#define T_OUT_CMD	0x08
+#define ABORT_HOST	0x04
+
+/* SMBus commands */
+#define SMBQUICK	0x00
+#define SMBSRBYTE	0x10		/* send/receive byte */
+#define SMBWRBYTE	0x20		/* write/read byte */
+#define SMBWRWORD	0x30		/* write/read word */
+#define SMBWRBLOCK	0x40		/* write/read block */
+
+/* PCI configuration registers and masks
+ */
+#define COM		0x4
+#define COM_ENABLE_IO	0x1
+
+#define SMBBA		PCIR_BAR(1)
+
+#define ATPC		0x5b
+#define ATPC_SMBCTRL	0x04 		/* XX linux has this as 0x6 */
+
+#define SMBHSI		0xe0
+#define SMBHSI_SLAVE	0x2
+#define SMBHSI_HOST	0x1
+
+#define SMBHCBC		0xe2
+#define SMBHCBC_CLOCK	0x70
+
+#define SMBCLOCK_149K	0x0
+#define SMBCLOCK_74K	0x20
+#define SMBCLOCK_37K	0x40
+#define SMBCLOCK_223K	0x80
+#define SMBCLOCK_111K	0xa0
+#define SMBCLOCK_55K	0xc0
+
+struct alpm_softc {
+	int base;
+	struct resource *res;
+        bus_space_tag_t smbst;
+        bus_space_handle_t smbsh;
+	device_t smbus;
+	struct mtx lock;
+};
+
+#define	ALPM_LOCK(alpm)		mtx_lock(&(alpm)->lock)
+#define	ALPM_UNLOCK(alpm)	mtx_unlock(&(alpm)->lock)
+#define	ALPM_LOCK_ASSERT(alpm)	mtx_assert(&(alpm)->lock, MA_OWNED)
+
+#define ALPM_SMBINB(alpm,register) \
+	(bus_space_read_1(alpm->smbst, alpm->smbsh, register))
+#define ALPM_SMBOUTB(alpm,register,value) \
+	(bus_space_write_1(alpm->smbst, alpm->smbsh, register, value))
+
+static int	alpm_detach(device_t dev);
+
+static int
+alpm_probe(device_t dev)
+{
+
+	if (pci_get_devid(dev) == ACER_M1543_PMU_ID) {
+		device_set_desc(dev, "AcerLabs M15x3 Power Management Unit");
+
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+alpm_attach(device_t dev)
+{
+	int rid;
+	u_int32_t l;
+	struct alpm_softc *alpm;
+
+	alpm = device_get_softc(dev);
+
+	/* Unlock SMBIO base register access */
+	l = pci_read_config(dev, ATPC, 1);
+	pci_write_config(dev, ATPC, l & ~ATPC_SMBCTRL, 1);
+
+	/*
+	 * XX linux sets clock to 74k, should we?
+	l = pci_read_config(dev, SMBHCBC, 1);
+	l &= 0x1f;
+	l |= SMBCLOCK_74K;
+	pci_write_config(dev, SMBHCBC, l, 1);
+	 */
+
+	if (bootverbose || alpm_debug) {
+		l = pci_read_config(dev, SMBHSI, 1);
+		device_printf(dev, "%s/%s",
+			(l & SMBHSI_HOST) ? "host":"nohost",
+			(l & SMBHSI_SLAVE) ? "slave":"noslave");
+
+		l = pci_read_config(dev, SMBHCBC, 1);
+		switch (l & SMBHCBC_CLOCK) {
+		case SMBCLOCK_149K:
+			printf(" 149K");
+			break;
+		case SMBCLOCK_74K:
+			printf(" 74K");
+			break;
+		case SMBCLOCK_37K:
+			printf(" 37K");
+			break;
+		case SMBCLOCK_223K:
+			printf(" 223K");
+			break;
+		case SMBCLOCK_111K:
+			printf(" 111K");
+			break;
+		case SMBCLOCK_55K:
+			printf(" 55K");
+			break;
+		default:
+			printf("unkown");
+			break;
+		}
+		printf("\n");
+	}
+
+	rid = SMBBA;
+	alpm->res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
+	    RF_ACTIVE);
+
+	if (alpm->res == NULL) {
+		device_printf(dev,"Could not allocate Bus space\n");
+		return (ENXIO);
+	}
+	alpm->smbst = rman_get_bustag(alpm->res);
+	alpm->smbsh = rman_get_bushandle(alpm->res);
+	mtx_init(&alpm->lock, device_get_nameunit(dev), "alpm", MTX_DEF);
+
+	/* attach the smbus */
+	alpm->smbus = device_add_child(dev, "smbus", -1);
+	if (alpm->smbus == NULL) {
+		alpm_detach(dev);
+		return (EINVAL);
+	}
+	bus_generic_attach(dev);
+
+	return (0);
+}
+
+static int
+alpm_detach(device_t dev)
+{
+	struct alpm_softc *alpm = device_get_softc(dev);
+
+	if (alpm->smbus) {
+		device_delete_child(dev, alpm->smbus);
+		alpm->smbus = NULL;
+	}
+	mtx_destroy(&alpm->lock);
+
+	if (alpm->res)
+		bus_release_resource(dev, SYS_RES_IOPORT, SMBBA, alpm->res);
+
+	return (0);
+}
+
+static int
+alpm_callback(device_t dev, int index, void *data)
+{
+	int error = 0;
+
+	switch (index) {
+	case SMB_REQUEST_BUS:
+	case SMB_RELEASE_BUS:
+		/* ok, bus allocation accepted */
+		break;
+	default:
+		error = EINVAL;
+	}
+
+	return (error);
+}
+
+static int
+alpm_clear(struct alpm_softc *sc)
+{
+	ALPM_SMBOUTB(sc, SMBSTS, 0xff);
+	DELAY(10);
+
+	return (0);
+}
+
+#if 0
+static int
+alpm_abort(struct alpm_softc *sc)
+{
+	ALPM_SMBOUTB(sc, SMBCMD, T_OUT_CMD | ABORT_HOST);
+
+	return (0);
+}
+#endif
+
+static int
+alpm_idle(struct alpm_softc *sc)
+{
+	u_char sts;
+
+	sts = ALPM_SMBINB(sc, SMBSTS);
+
+	ALPM_DEBUG(printf("alpm: idle? STS=0x%x\n", sts));
+
+	return (sts & IDL_STS);
+}
+
+/*
+ * Poll the SMBus controller
+ */
+static int
+alpm_wait(struct alpm_softc *sc)
+{
+	int count = 10000;
+	u_char sts = 0;
+	int error;
+
+	/* wait for command to complete and SMBus controller is idle */
+	while (count--) {
+		DELAY(10);
+		sts = ALPM_SMBINB(sc, SMBSTS);
+		if (sts & SMI_I_STS)
+			break;
+	}
+
+	ALPM_DEBUG(printf("alpm: STS=0x%x\n", sts));
+
+	error = SMB_ENOERR;
+
+	if (!count)
+		error |= SMB_ETIMEOUT;
+
+	if (sts & TERMINATE)
+		error |= SMB_EABORT;
+
+	if (sts & BUS_COLLI)
+		error |= SMB_ENOACK;
+
+	if (sts & DEVICE_ERR)
+		error |= SMB_EBUSERR;
+
+	if (error != SMB_ENOERR)
+		alpm_clear(sc);
+
+	return (error);
+}
+
+static int
+alpm_quick(device_t dev, u_char slave, int how)
+{
+	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
+	int error;
+
+	ALPM_LOCK(sc);
+	alpm_clear(sc);
+	if (!alpm_idle(sc)) {
+		ALPM_UNLOCK(sc);
+		return (EBUSY);
+	}
+
+	switch (how) {
+	case SMB_QWRITE:
+		ALPM_DEBUG(printf("alpm: QWRITE to 0x%x", slave));
+		ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
+		break;
+	case SMB_QREAD:
+		ALPM_DEBUG(printf("alpm: QREAD to 0x%x", slave));
+		ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
+		break;
+	default:
+		panic("%s: unknown QUICK command (%x)!", __func__,
+			how);
+	}
+	ALPM_SMBOUTB(sc, SMBCMD, SMBQUICK);
+	ALPM_SMBOUTB(sc, SMBSTART, 0xff);
+
+	error = alpm_wait(sc);
+
+	ALPM_DEBUG(printf(", error=0x%x\n", error));
+	ALPM_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+alpm_sendb(device_t dev, u_char slave, char byte)
+{
+	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
+	int error;
+
+	ALPM_LOCK(sc);
+	alpm_clear(sc);
+	if (!alpm_idle(sc)) {
+		ALPM_UNLOCK(sc);
+		return (SMB_EBUSY);
+	}
+
+	ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
+	ALPM_SMBOUTB(sc, SMBCMD, SMBSRBYTE);
+	ALPM_SMBOUTB(sc, SMBHDATA, byte);
+	ALPM_SMBOUTB(sc, SMBSTART, 0xff);
+
+	error = alpm_wait(sc);
+
+	ALPM_DEBUG(printf("alpm: SENDB to 0x%x, byte=0x%x, error=0x%x\n", slave, byte, error));
+	ALPM_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+alpm_recvb(device_t dev, u_char slave, char *byte)
+{
+	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
+	int error;
+
+	ALPM_LOCK(sc);
+	alpm_clear(sc);
+	if (!alpm_idle(sc)) {
+		ALPM_UNLOCK(sc);
+		return (SMB_EBUSY);
+	}
+
+	ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
+	ALPM_SMBOUTB(sc, SMBCMD, SMBSRBYTE);
+	ALPM_SMBOUTB(sc, SMBSTART, 0xff);
+
+	if ((error = alpm_wait(sc)) == SMB_ENOERR)
+		*byte = ALPM_SMBINB(sc, SMBHDATA);
+
+	ALPM_DEBUG(printf("alpm: RECVB from 0x%x, byte=0x%x, error=0x%x\n", slave, *byte, error));
+	ALPM_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+alpm_writeb(device_t dev, u_char slave, char cmd, char byte)
+{
+	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
+	int error;
+
+	ALPM_LOCK(sc);
+	alpm_clear(sc);
+	if (!alpm_idle(sc)) {
+		ALPM_UNLOCK(sc);
+		return (SMB_EBUSY);
+	}
+
+	ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
+	ALPM_SMBOUTB(sc, SMBCMD, SMBWRBYTE);
+	ALPM_SMBOUTB(sc, SMBHDATA, byte);
+	ALPM_SMBOUTB(sc, SMBHCMD, cmd);
+	ALPM_SMBOUTB(sc, SMBSTART, 0xff);
+
+	error = alpm_wait(sc);
+
+	ALPM_DEBUG(printf("alpm: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error));
+	ALPM_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+alpm_readb(device_t dev, u_char slave, char cmd, char *byte)
+{
+	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
+	int error;
+
+	ALPM_LOCK(sc);
+	alpm_clear(sc);
+	if (!alpm_idle(sc)) {
+		ALPM_UNLOCK(sc);
+		return (SMB_EBUSY);
+	}
+
+	ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
+	ALPM_SMBOUTB(sc, SMBCMD, SMBWRBYTE);
+	ALPM_SMBOUTB(sc, SMBHCMD, cmd);
+	ALPM_SMBOUTB(sc, SMBSTART, 0xff);
+
+	if ((error = alpm_wait(sc)) == SMB_ENOERR)
+		*byte = ALPM_SMBINB(sc, SMBHDATA);
+
+	ALPM_DEBUG(printf("alpm: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, *byte, error));
+	ALPM_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+alpm_writew(device_t dev, u_char slave, char cmd, short word)
+{
+	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
+	int error;
+
+	ALPM_LOCK(sc);
+	alpm_clear(sc);
+	if (!alpm_idle(sc)) {
+		ALPM_UNLOCK(sc);
+		return (SMB_EBUSY);
+	}
+
+	ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
+	ALPM_SMBOUTB(sc, SMBCMD, SMBWRWORD);
+	ALPM_SMBOUTB(sc, SMBHDATA, word & 0x00ff);
+	ALPM_SMBOUTB(sc, SMBHDATB, (word & 0xff00) >> 8);
+	ALPM_SMBOUTB(sc, SMBHCMD, cmd);
+	ALPM_SMBOUTB(sc, SMBSTART, 0xff);
+
+	error = alpm_wait(sc);
+
+	ALPM_DEBUG(printf("alpm: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error));
+	ALPM_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+alpm_readw(device_t dev, u_char slave, char cmd, short *word)
+{
+	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
+	int error;
+	u_char high, low;
+
+	ALPM_LOCK(sc);
+	alpm_clear(sc);
+	if (!alpm_idle(sc)) {
+		ALPM_UNLOCK(sc);
+		return (SMB_EBUSY);
+	}
+
+	ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
+	ALPM_SMBOUTB(sc, SMBCMD, SMBWRWORD);
+	ALPM_SMBOUTB(sc, SMBHCMD, cmd);
+	ALPM_SMBOUTB(sc, SMBSTART, 0xff);
+
+	if ((error = alpm_wait(sc)) == SMB_ENOERR) {
+		low = ALPM_SMBINB(sc, SMBHDATA);
+		high = ALPM_SMBINB(sc, SMBHDATB);
+
+		*word = ((high & 0xff) << 8) | (low & 0xff);
+	}
+
+	ALPM_DEBUG(printf("alpm: READW from 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, *word, error));
+	ALPM_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+alpm_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
+{
+	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
+	u_char i;
+	int error;
+
+	if (count < 1 || count > 32)
+		return (SMB_EINVAL);
+
+	ALPM_LOCK(sc);
+	alpm_clear(sc);
+	if(!alpm_idle(sc)) {
+		ALPM_UNLOCK(sc);
+		return (SMB_EBUSY);
+	}
+
+	ALPM_SMBOUTB(sc, SMBHADDR, slave & ~LSB);
+	
+	/* set the cmd and reset the
+	 * 32-byte long internal buffer */
+	ALPM_SMBOUTB(sc, SMBCMD, SMBWRBLOCK | SMB_BLK_CLR);
+
+	ALPM_SMBOUTB(sc, SMBHDATA, count);
+
+	/* fill the 32-byte internal buffer */
+	for (i = 0; i < count; i++) {
+		ALPM_SMBOUTB(sc, SMBHBLOCK, buf[i]);
+		DELAY(2);
+	}
+	ALPM_SMBOUTB(sc, SMBHCMD, cmd);
+	ALPM_SMBOUTB(sc, SMBSTART, 0xff);
+
+	error = alpm_wait(sc);
+
+	ALPM_DEBUG(printf("alpm: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
+	ALPM_UNLOCK(sc);
+
+	return (error);
+}
+
+static int
+alpm_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
+{
+	struct alpm_softc *sc = (struct alpm_softc *)device_get_softc(dev);
+	u_char data, len, i;
+	int error;
+
+	if (*count < 1 || *count > 32)
+		return (SMB_EINVAL);
+
+	ALPM_LOCK(sc);
+	alpm_clear(sc);
+	if (!alpm_idle(sc)) {
+		ALPM_UNLOCK(sc);
+		return (SMB_EBUSY);
+	}
+
+	ALPM_SMBOUTB(sc, SMBHADDR, slave | LSB);
+	
+	/* set the cmd and reset the
+	 * 32-byte long internal buffer */
+	ALPM_SMBOUTB(sc, SMBCMD, SMBWRBLOCK | SMB_BLK_CLR);
+
+	ALPM_SMBOUTB(sc, SMBHCMD, cmd);
+	ALPM_SMBOUTB(sc, SMBSTART, 0xff);
+
+	if ((error = alpm_wait(sc)) != SMB_ENOERR)
+			goto error;
+
+	len = ALPM_SMBINB(sc, SMBHDATA);
+
+	/* read the 32-byte internal buffer */
+	for (i = 0; i < len; i++) {
+		data = ALPM_SMBINB(sc, SMBHBLOCK);
+		if (i < *count)
+			buf[i] = data;
+		DELAY(2);
+	}
+	*count = len;
+
+error:
+	ALPM_DEBUG(printf("alpm: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error));
+	ALPM_UNLOCK(sc);
+
+	return (error);
+}
+
+static devclass_t alpm_devclass;
+
+static device_method_t alpm_methods[] = {
+	/* device interface */
+	DEVMETHOD(device_probe,		alpm_probe),
+	DEVMETHOD(device_attach,	alpm_attach),
+	DEVMETHOD(device_detach,	alpm_detach),
+	
+	/* smbus interface */
+	DEVMETHOD(smbus_callback,	alpm_callback),
+	DEVMETHOD(smbus_quick,		alpm_quick),
+	DEVMETHOD(smbus_sendb,		alpm_sendb),
+	DEVMETHOD(smbus_recvb,		alpm_recvb),
+	DEVMETHOD(smbus_writeb,		alpm_writeb),
+	DEVMETHOD(smbus_readb,		alpm_readb),
+	DEVMETHOD(smbus_writew,		alpm_writew),
+	DEVMETHOD(smbus_readw,		alpm_readw),
+	DEVMETHOD(smbus_bwrite,		alpm_bwrite),
+	DEVMETHOD(smbus_bread,		alpm_bread),
+	
+	{ 0, 0 }
+};
+
+static driver_t alpm_driver = {
+	"alpm",
+	alpm_methods,
+	sizeof(struct alpm_softc)
+};
+
+DRIVER_MODULE(alpm, pci, alpm_driver, alpm_devclass, 0, 0);
+DRIVER_MODULE(smbus, alpm, smbus_driver, smbus_devclass, 0, 0);
+MODULE_DEPEND(alpm, pci, 1, 1, 1);
+MODULE_DEPEND(alpm, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_VERSION(alpm, 1);

Copied: head/sys/dev/amdpm/amdpm.c (from r272014, head/sys/pci/amdpm.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/amdpm/amdpm.c	Tue Sep 23 06:31:15 2014	(r272017, copy of r272014, head/sys/pci/amdpm.c)
@@ -0,0 +1,668 @@
+/*-
+ * Copyright (c) 2000 Matthew C. Forman
+ *
+ * Based (heavily) on alpm.c which is:
+ *
+ * Copyright (c) 1998, 1999 Nicolas Souchu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Power management function/SMBus function support for the AMD 756 chip.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+
+#include <dev/smbus/smbconf.h>
+#include "smbus_if.h"
+
+#define AMDPM_DEBUG(x)	if (amdpm_debug) (x)
+
+#ifdef DEBUG
+static int amdpm_debug = 1;
+#else
+static int amdpm_debug = 0;
+#endif
+
+#define AMDPM_VENDORID_AMD 0x1022
+#define AMDPM_DEVICEID_AMD756PM 0x740b
+#define AMDPM_DEVICEID_AMD766PM 0x7413
+#define AMDPM_DEVICEID_AMD768PM 0x7443
+#define AMDPM_DEVICEID_AMD8111PM 0x746B
+
+/* nVidia nForce chipset */
+#define AMDPM_VENDORID_NVIDIA 0x10de
+#define AMDPM_DEVICEID_NF_SMB 0x01b4
+
+/* PCI Configuration space registers */
+#define AMDPCI_PMBASE 0x58
+#define NFPCI_PMBASE  0x14
+
+#define AMDPCI_GEN_CONFIG_PM 0x41
+#define AMDPCI_PMIOEN (1<<7)
+
+#define AMDPCI_SCIINT_CONFIG_PM 0x42
+#define AMDPCI_SCISEL_IRQ11 11
+
+#define AMDPCI_REVID 0x08
+
+/*
+ * I/O registers.
+ * Base address programmed via AMDPCI_PMBASE.
+ */
+
+#define AMDSMB_GLOBAL_STATUS (0x00)
+#define AMDSMB_GS_TO_STS (1<<5)
+#define AMDSMB_GS_HCYC_STS (1<<4)
+#define AMDSMB_GS_HST_STS (1<<3)
+#define AMDSMB_GS_PRERR_STS (1<<2)
+#define AMDSMB_GS_COL_STS (1<<1)
+#define AMDSMB_GS_ABRT_STS (1<<0)
+#define AMDSMB_GS_CLEAR_STS (AMDSMB_GS_TO_STS|AMDSMB_GS_HCYC_STS|AMDSMB_GS_PRERR_STS|AMDSMB_GS_COL_STS|AMDSMB_GS_ABRT_STS)
+
+#define AMDSMB_GLOBAL_ENABLE (0x02)
+#define AMDSMB_GE_ABORT (1<<5)
+#define AMDSMB_GE_HCYC_EN (1<<4)
+#define AMDSMB_GE_HOST_STC (1<<3)
+#define AMDSMB_GE_CYC_QUICK 0
+#define AMDSMB_GE_CYC_BYTE 1
+#define AMDSMB_GE_CYC_BDATA 2
+#define AMDSMB_GE_CYC_WDATA 3
+#define AMDSMB_GE_CYC_PROCCALL 4
+#define AMDSMB_GE_CYC_BLOCK 5
+
+#define	LSB		0x1	/* XXX: Better name: Read/Write? */
+
+#define AMDSMB_HSTADDR  (0x04)
+#define AMDSMB_HSTDATA  (0x06)
+#define AMDSMB_HSTCMD   (0x08)
+#define AMDSMB_HSTDFIFO (0x09)
+#define AMDSMB_HSLVDATA (0x0A)
+#define AMDSMB_HSLVDA   (0x0C)
+#define AMDSMB_HSLVDDR  (0x0E)
+#define AMDSMB_SNPADDR  (0x0F)
+
+struct amdpm_softc {
+	int base;
+	int rid;
+	struct resource *res;
+	device_t smbus;
+	struct mtx lock;
+};
+
+#define	AMDPM_LOCK(amdpm)		mtx_lock(&(amdpm)->lock)
+#define	AMDPM_UNLOCK(amdpm)		mtx_unlock(&(amdpm)->lock)
+#define	AMDPM_LOCK_ASSERT(amdpm)	mtx_assert(&(amdpm)->lock, MA_OWNED)
+
+#define AMDPM_SMBINB(amdpm,register) \
+	(bus_read_1(amdpm->res, register))
+#define AMDPM_SMBOUTB(amdpm,register,value) \
+	(bus_write_1(amdpm->res, register, value))
+#define AMDPM_SMBINW(amdpm,register) \
+	(bus_read_2(amdpm->res, register))
+#define AMDPM_SMBOUTW(amdpm,register,value) \
+	(bus_write_2(amdpm->res, register, value))
+
+static int	amdpm_detach(device_t dev);
+
+static int
+amdpm_probe(device_t dev)
+{
+	u_long base;
+	u_int16_t vid;
+	u_int16_t did;
+
+	vid = pci_get_vendor(dev);
+	did = pci_get_device(dev);
+	if ((vid == AMDPM_VENDORID_AMD) &&
+	    ((did == AMDPM_DEVICEID_AMD756PM) ||
+	     (did == AMDPM_DEVICEID_AMD766PM) ||
+	     (did == AMDPM_DEVICEID_AMD768PM) ||
+	     (did == AMDPM_DEVICEID_AMD8111PM))) {
+		device_set_desc(dev, "AMD 756/766/768/8111 Power Management Controller");
+
+		/* 
+		 * We have to do this, since the BIOS won't give us the
+		 * resource info (not mine, anyway).
+		 */
+		base = pci_read_config(dev, AMDPCI_PMBASE, 4);
+		base &= 0xff00;
+		bus_set_resource(dev, SYS_RES_IOPORT, AMDPCI_PMBASE,
+				 base+0xe0, 32);
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	if ((vid == AMDPM_VENDORID_NVIDIA) &&
+	    (did == AMDPM_DEVICEID_NF_SMB)) {
+		device_set_desc(dev, "nForce SMBus Controller");
+
+		/* 
+		* We have to do this, since the BIOS won't give us the
+		* resource info (not mine, anyway).
+		*/
+		base = pci_read_config(dev, NFPCI_PMBASE, 4);
+		base &= 0xff00;
+		bus_set_resource(dev, SYS_RES_IOPORT, NFPCI_PMBASE,
+				 base, 32);
+
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return ENXIO;
+}
+
+static int
+amdpm_attach(device_t dev)
+{
+	struct amdpm_softc *amdpm_sc = device_get_softc(dev);
+	u_char val_b;
+	
+	/* Enable I/O block access */
+	val_b = pci_read_config(dev, AMDPCI_GEN_CONFIG_PM, 1);
+	pci_write_config(dev, AMDPCI_GEN_CONFIG_PM, val_b | AMDPCI_PMIOEN, 1);
+
+	/* Allocate I/O space */
+	if (pci_get_vendor(dev) == AMDPM_VENDORID_AMD)
+		amdpm_sc->rid = AMDPCI_PMBASE;
+	else
+		amdpm_sc->rid = NFPCI_PMBASE;
+	amdpm_sc->res = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
+		&amdpm_sc->rid, RF_ACTIVE);
+	
+	if (amdpm_sc->res == NULL) {
+		device_printf(dev, "could not map i/o space\n");
+		return (ENXIO);
+	}	     
+
+	mtx_init(&amdpm_sc->lock, device_get_nameunit(dev), "amdpm", MTX_DEF);
+
+	/* Allocate a new smbus device */
+	amdpm_sc->smbus = device_add_child(dev, "smbus", -1);
+	if (!amdpm_sc->smbus) {
+		amdpm_detach(dev);
+		return (EINVAL);
+	}
+
+	bus_generic_attach(dev);
+
+	return (0);
+}
+
+static int
+amdpm_detach(device_t dev)
+{
+	struct amdpm_softc *amdpm_sc = device_get_softc(dev);
+
+	if (amdpm_sc->smbus) {
+		device_delete_child(dev, amdpm_sc->smbus);
+		amdpm_sc->smbus = NULL;
+	}
+
+	mtx_destroy(&amdpm_sc->lock);
+	if (amdpm_sc->res)
+		bus_release_resource(dev, SYS_RES_IOPORT, amdpm_sc->rid,
+				     amdpm_sc->res);
+
+	return (0);
+}
+
+static int
+amdpm_callback(device_t dev, int index, void *data)
+{
+	int error = 0;
+
+	switch (index) {
+	case SMB_REQUEST_BUS:
+	case SMB_RELEASE_BUS:
+		break;
+	default:
+		error = EINVAL;
+	}
+
+	return (error);
+}
+
+static int
+amdpm_clear(struct amdpm_softc *sc)
+{
+
+	AMDPM_LOCK_ASSERT(sc);
+	AMDPM_SMBOUTW(sc, AMDSMB_GLOBAL_STATUS, AMDSMB_GS_CLEAR_STS);
+	DELAY(10);
+
+	return (0);
+}
+
+#if 0
+static int
+amdpm_abort(struct amdpm_softc *sc)
+{
+	u_short l;
+	
+	l = AMDPM_SMBINW(sc, AMDSMB_GLOBAL_ENABLE);
+	AMDPM_SMBOUTW(sc, AMDSMB_GLOBAL_ENABLE, l | AMDSMB_GE_ABORT);
+
+	return (0);
+}
+#endif
+

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409230631.s8N6VFlM085108>