Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Teach a couple of i2cbus controllers how to resc...
details: https://anonhg.NetBSD.org/src/rev/dcecd5d22bda
branches: trunk
changeset: 337929:dcecd5d22bda
user: pgoyette <pgoyette%NetBSD.org@localhost>
date: Sun May 03 22:51:11 2015 +0000
description:
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.
diffstat:
sys/dev/pci/ichsmb.c | 48 ++++++++++++++++++++++++++++++++++------
sys/dev/pci/piixpm.c | 60 +++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 90 insertions(+), 18 deletions(-)
diffs (249 lines):
diff -r f4f7d15181c2 -r dcecd5d22bda sys/dev/pci/ichsmb.c
--- a/sys/dev/pci/ichsmb.c Sun May 03 22:40:02 2015 +0000
+++ b/sys/dev/pci/ichsmb.c Sun May 03 22:51:11 2015 +0000
@@ -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 @@
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_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 @@
{
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 @@
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 @@
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;
+}
-out: if (!pmf_device_register(self, NULL, NULL))
- aprint_error_dev(self, "couldn't establish power handler\n");
+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;
+
}
static int
diff -r f4f7d15181c2 -r dcecd5d22bda sys/dev/pci/piixpm.c
--- a/sys/dev/pci/piixpm.c Sun May 03 22:40:02 2015 +0000
+++ b/sys/dev/pci/piixpm.c Sun May 03 22:51:11 2015 +0000
@@ -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 @@
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 @@
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_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 @@
{
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 @@
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 @@
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 @@
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)
{
Home |
Main Index |
Thread Index |
Old Index