Module Name:    src
Committed By:   pgoyette
Date:           Sun May  3 22:51:11 UTC 2015

Modified Files:
        src/sys/dev/pci: ichsmb.c piixpm.c

Log Message:
Teach a couple of i2cbus controllers how to rescan.  This enables
{,un}loading and {at,de}taching of the iic(4) driver/module at a
later time. Tested piixpm on QEMU, and ichsmb on my live server.


To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/sys/dev/pci/ichsmb.c
cvs rdiff -u -r1.45 -r1.46 src/sys/dev/pci/piixpm.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/ichsmb.c
diff -u src/sys/dev/pci/ichsmb.c:1.41 src/sys/dev/pci/ichsmb.c:1.42
--- src/sys/dev/pci/ichsmb.c:1.41	Thu Apr  2 15:32:19 2015
+++ src/sys/dev/pci/ichsmb.c	Sun May  3 22:51:11 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: ichsmb.c,v 1.41 2015/04/02 15:32:19 tnn Exp $	*/
+/*	$NetBSD: ichsmb.c,v 1.42 2015/05/03 22:51:11 pgoyette Exp $	*/
 /*	$OpenBSD: ichiic.c,v 1.18 2007/05/03 09:36:26 dlg Exp $	*/
 
 /*
@@ -22,7 +22,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ichsmb.c,v 1.41 2015/04/02 15:32:19 tnn Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ichsmb.c,v 1.42 2015/05/03 22:51:11 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
@@ -67,10 +67,13 @@ struct ichsmb_softc {
 		int          flags;
 		volatile int error;
 	}			sc_i2c_xfer;
+	device_t		sc_i2c_device;
 };
 
 static int	ichsmb_match(device_t, cfdata_t, void *);
 static void	ichsmb_attach(device_t, device_t, void *);
+static int	ichsmb_rescan(device_t, const char *, const int *);
+static void	ichsmb_chdet(device_t, device_t);
 
 static int	ichsmb_i2c_acquire_bus(void *, int);
 static void	ichsmb_i2c_release_bus(void *, int);
@@ -80,8 +83,8 @@ static int	ichsmb_i2c_exec(void *, i2c_o
 static int	ichsmb_intr(void *);
 
 
-CFATTACH_DECL_NEW(ichsmb, sizeof(struct ichsmb_softc),
-    ichsmb_match, ichsmb_attach, NULL, NULL);
+CFATTACH_DECL3_NEW(ichsmb, sizeof(struct ichsmb_softc),
+    ichsmb_match, ichsmb_attach, NULL, NULL, ichsmb_rescan, ichsmb_chdet, 0);
 
 
 static int
@@ -134,12 +137,12 @@ ichsmb_attach(device_t parent, device_t 
 {
 	struct ichsmb_softc *sc = device_private(self);
 	struct pci_attach_args *pa = aux;
-	struct i2cbus_attach_args iba;
 	pcireg_t conf;
 	bus_size_t iosize;
 	pci_intr_handle_t ih;
 	const char *intrstr = NULL;
 	char intrbuf[PCI_INTRSTR_LEN];
+	int flags;
 
 	sc->sc_dev = self;
 
@@ -181,6 +184,26 @@ ichsmb_attach(device_t parent, device_t 
 			aprint_normal_dev(self, "polling\n");
 	}
 
+	sc->sc_i2c_device = NULL;
+	flags = 0;
+	ichsmb_rescan(self, "i2cbus", &flags);
+
+out:	if (!pmf_device_register(self, NULL, NULL))
+		aprint_error_dev(self, "couldn't establish power handler\n");
+}
+
+static int
+ichsmb_rescan(device_t self, const char *ifattr, const int *flags)
+{
+	struct ichsmb_softc *sc = device_private(self);
+	struct i2cbus_attach_args iba;
+
+	if (!ifattr_match(ifattr, "i2cbus"))
+		return 0;
+
+	if (sc->sc_i2c_device)
+		return 0;
+
 	/* Attach I2C bus */
 	mutex_init(&sc->sc_i2c_mutex, MUTEX_DEFAULT, IPL_NONE);
 	sc->sc_i2c_tag.ic_cookie = sc;
@@ -191,10 +214,19 @@ ichsmb_attach(device_t parent, device_t 
 	memset(&iba, 0, sizeof(iba));
 	iba.iba_type = I2C_TYPE_SMBUS;
 	iba.iba_tag = &sc->sc_i2c_tag;
-	config_found(self, &iba, iicbus_print);
+	sc->sc_i2c_device = config_found_ia(self, ifattr, &iba, iicbus_print);
+
+	return 0;
+}
+
+static void
+ichsmb_chdet(device_t self, device_t child)
+{
+	struct ichsmb_softc *sc = device_private(self);
+
+	if (sc->sc_i2c_device == child)
+		sc->sc_i2c_device = NULL;
 
-out:	if (!pmf_device_register(self, NULL, NULL))
-		aprint_error_dev(self, "couldn't establish power handler\n");
 }
 
 static int

Index: src/sys/dev/pci/piixpm.c
diff -u src/sys/dev/pci/piixpm.c:1.45 src/sys/dev/pci/piixpm.c:1.46
--- src/sys/dev/pci/piixpm.c:1.45	Sun Jun 22 09:48:20 2014
+++ src/sys/dev/pci/piixpm.c	Sun May  3 22:51:11 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: piixpm.c,v 1.45 2014/06/22 09:48:20 hannken Exp $ */
+/* $NetBSD: piixpm.c,v 1.46 2015/05/03 22:51:11 pgoyette Exp $ */
 /*	$OpenBSD: piixpm.c,v 1.20 2006/02/27 08:25:02 grange Exp $	*/
 
 /*
@@ -22,7 +22,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1.45 2014/06/22 09:48:20 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1.46 2015/05/03 22:51:11 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -76,6 +76,8 @@ struct piixpm_softc {
 	pcitag_t		sc_pcitag;
 	pcireg_t		sc_id;
 
+	int			sc_numbusses;
+	device_t		sc_i2c_device[4];
 	struct piixpm_smbus	sc_busses[4];
 	struct i2c_controller	sc_i2c_tags[4];
 
@@ -93,6 +95,8 @@ struct piixpm_softc {
 
 static int	piixpm_match(device_t, cfdata_t, void *);
 static void	piixpm_attach(device_t, device_t, void *);
+static int	piixpm_rescan(device_t, const char *, const int *);
+static void	piixpm_chdet(device_t, device_t);
 
 static bool	piixpm_suspend(device_t, const pmf_qual_t *);
 static bool	piixpm_resume(device_t, const pmf_qual_t *);
@@ -106,8 +110,8 @@ static int	piixpm_i2c_exec(void *, i2c_o
 
 static int	piixpm_intr(void *);
 
-CFATTACH_DECL_NEW(piixpm, sizeof(struct piixpm_softc),
-    piixpm_match, piixpm_attach, NULL, NULL);
+CFATTACH_DECL3_NEW(piixpm, sizeof(struct piixpm_softc),
+    piixpm_match, piixpm_attach, NULL, NULL, piixpm_rescan, piixpm_chdet, 0);
 
 static int
 piixpm_match(device_t parent, cfdata_t match, void *aux)
@@ -150,12 +154,11 @@ piixpm_attach(device_t parent, device_t 
 {
 	struct piixpm_softc *sc = device_private(self);
 	struct pci_attach_args *pa = aux;
-	struct i2cbus_attach_args iba;
 	pcireg_t base, conf;
 	pcireg_t pmmisc;
 	pci_intr_handle_t ih;
 	const char *intrstr = NULL;
-	int i, numbusses = 1;
+	int i, flags;
 	char intrbuf[PCI_INTRSTR_LEN];
 
 	sc->sc_dev = self;
@@ -163,6 +166,7 @@ piixpm_attach(device_t parent, device_t 
 	sc->sc_id = pa->pa_id;
 	sc->sc_pc = pa->pa_pc;
 	sc->sc_pcitag = pa->pa_tag;
+	sc->sc_numbusses = 1;
 
 	pci_aprint_devinfo(pa, NULL);
 
@@ -206,7 +210,7 @@ nopowermanagement:
 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_ATI_SB600_SMB &&
 	    PCI_REVISION(pa->pa_class) >= 0x40) {
 		if (piixpm_sb800_init(sc) == 0) {
-			numbusses = 4;
+			sc->sc_numbusses = 4;
 			goto attach_i2c;
 		}
 		aprint_normal_dev(self, "SMBus disabled\n");
@@ -249,24 +253,60 @@ nopowermanagement:
 	aprint_normal("\n");
 
 attach_i2c:
+	for (i = 0; i < sc->sc_numbusses; i++)
+		sc->sc_i2c_device[i] = NULL;
+
+	flags = 0;
+	piixpm_rescan(self, "i2cbus", &flags);
+}
+
+static int
+piixpm_rescan(device_t self, const char *ifattr, const int *flags)
+{
+	struct piixpm_softc *sc = device_private(self);
+	struct i2cbus_attach_args iba;
+	int i;
+
+	if (!ifattr_match(ifattr, "i2cbus"))
+		return 0;
+
 	/* Attach I2C bus */
 	mutex_init(&sc->sc_i2c_mutex, MUTEX_DEFAULT, IPL_NONE);
 
-	for (i = 0; i < numbusses; i++) {
+	for (i = 0; i < sc->sc_numbusses; i++) {
+		if (sc->sc_i2c_device[i])
+			continue;
 		sc->sc_busses[i].sda = i;
 		sc->sc_busses[i].softc = sc;
 		sc->sc_i2c_tags[i].ic_cookie = &sc->sc_busses[i];
 		sc->sc_i2c_tags[i].ic_acquire_bus = piixpm_i2c_acquire_bus;
 		sc->sc_i2c_tags[i].ic_release_bus = piixpm_i2c_release_bus;
 		sc->sc_i2c_tags[i].ic_exec = piixpm_i2c_exec;
-
 		memset(&iba, 0, sizeof(iba));
 		iba.iba_type = I2C_TYPE_SMBUS;
 		iba.iba_tag = &sc->sc_i2c_tags[i];
-		config_found_ia(self, "i2cbus", &iba, iicbus_print);
+		sc->sc_i2c_device[i] = config_found_ia(self, ifattr, &iba,
+						    iicbus_print);
 	}
+
+	return 0;
 }
 
+static void
+piixpm_chdet(device_t self, device_t child)
+{
+	struct piixpm_softc *sc = device_private(self);
+	int i;
+
+	for (i = 0; i < sc->sc_numbusses; i++) {
+		if (sc->sc_i2c_device[i] == child) {
+			sc->sc_i2c_device[i] = NULL;
+			break;
+		}
+	}
+}
+
+
 static bool
 piixpm_suspend(device_t dv, const pmf_qual_t *qual)
 {

Reply via email to