Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci add detach support
details: https://anonhg.NetBSD.org/src/rev/9c6802b95f59
branches: trunk
changeset: 767304:9c6802b95f59
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Fri Jul 15 00:21:26 2011 +0000
description:
add detach support
diffstat:
sys/dev/pci/cxdtv.c | 91 +++++++++++++++++++++++++++++++++++++++++++------
sys/dev/pci/cxdtvvar.h | 4 +-
2 files changed, 83 insertions(+), 12 deletions(-)
diffs (175 lines):
diff -r 7c80d6caf3a9 -r 9c6802b95f59 sys/dev/pci/cxdtv.c
--- a/sys/dev/pci/cxdtv.c Thu Jul 14 23:50:12 2011 +0000
+++ b/sys/dev/pci/cxdtv.c Fri Jul 15 00:21:26 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cxdtv.c,v 1.2 2011/07/14 23:47:45 jmcneill Exp $ */
+/* $NetBSD: cxdtv.c,v 1.3 2011/07/15 00:21:26 jmcneill Exp $ */
/*
* Copyright (c) 2008, 2011 Jonathan A. Kollasch
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cxdtv.c,v 1.2 2011/07/14 23:47:45 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cxdtv.c,v 1.3 2011/07/15 00:21:26 jmcneill Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -65,6 +65,7 @@
static int cxdtv_match(struct device *, struct cfdata *, void *);
static void cxdtv_attach(struct device *, struct device *, void *);
static int cxdtv_detach(struct device *, int);
+static void cxdtv_childdet(struct device *, struct device *);
static int cxdtv_intr(void *);
static bool cxdtv_resume(device_t, const pmf_qual_t *);
@@ -90,6 +91,7 @@
static int cxdtv_risc_field(struct cxdtv_softc *, uint32_t *, uint32_t);
static int cxdtv_mpeg_attach(struct cxdtv_softc *);
+static int cxdtv_mpeg_detach(struct cxdtv_softc *, int flags);
static int cxdtv_mpeg_intr(struct cxdtv_softc *);
static int cxdtv_mpeg_reset(struct cxdtv_softc *);
@@ -127,8 +129,8 @@
},
};
-CFATTACH_DECL_NEW(cxdtv, sizeof(struct cxdtv_softc),
- cxdtv_match, cxdtv_attach, cxdtv_detach, NULL);
+CFATTACH_DECL2_NEW(cxdtv, sizeof(struct cxdtv_softc),
+ cxdtv_match, cxdtv_attach, cxdtv_detach, NULL, NULL, cxdtv_childdet);
static int
cxdtv_match(device_t parent, cfdata_t match, void *aux)
@@ -164,6 +166,7 @@
sc = device_private(self);
sc->sc_dev = self;
+ sc->sc_pc = pa->pa_pc;
aprint_naive("\n");
@@ -249,7 +252,33 @@
static int
cxdtv_detach(device_t self, int flags)
{
- return EBUSY;
+ struct cxdtv_softc *sc = device_private(self);
+ int error;
+
+ error = cxdtv_mpeg_detach(sc, flags);
+ if (error)
+ return error;
+
+ if (sc->sc_ih)
+ pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
+
+ if (sc->sc_mems)
+ bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems);
+
+ mutex_destroy(&sc->sc_i2c_buslock);
+ mutex_destroy(&sc->sc_delaylock);
+ cv_destroy(&sc->sc_delaycv);
+
+ return 0;
+}
+
+static void
+cxdtv_childdet(device_t self, device_t child)
+{
+ struct cxdtv_softc *sc = device_private(self);
+
+ if (child == sc->sc_dtvdev)
+ sc->sc_dtvdev = NULL;
}
static bool
@@ -463,6 +492,50 @@
return (sc->sc_dtvdev != NULL);
}
+int
+cxdtv_mpeg_detach(struct cxdtv_softc *sc, int flags)
+{
+ int error = 0;
+
+ if (sc->sc_dtvdev) {
+ error = config_detach(sc->sc_dtvdev, flags);
+ if (error)
+ return error;
+ }
+
+ if (sc->sc_demod) {
+ switch (sc->sc_board->cb_demod) {
+ case CXDTV_DEMOD_NXT2004:
+ nxt2k_close(sc->sc_demod);
+ break;
+ case CXDTV_DEMOD_LG3303:
+ lg3303_close(sc->sc_demod);
+ break;
+ default:
+ break;
+ }
+ sc->sc_demod = NULL;
+ }
+ if (sc->sc_tuner) {
+ switch (sc->sc_board->cb_tuner) {
+ case CXDTV_TUNER_PLL:
+ tvpll_close(sc->sc_tuner);
+ break;
+ default:
+ break;
+ }
+ sc->sc_tuner = NULL;
+ }
+
+ if (sc->sc_riscbuf) {
+ kmem_free(sc->sc_riscbuf, sc->sc_riscbufsz);
+ sc->sc_riscbuf = NULL;
+ sc->sc_riscbufsz = 0;
+ }
+
+ return error;
+}
+
static void
cxdtv_dtv_get_devinfo(void *priv, struct dvb_frontend_info *info)
{
@@ -1076,15 +1149,11 @@
val &= ~1;
bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_GP0_IO, val);
- mutex_enter(&sc->sc_delaylock);
- cv_timedwait(&sc->sc_delaycv, &sc->sc_delaylock, mstohz(10));
- mutex_exit(&sc->sc_delaylock);
+ delay(100000);
val |= 1;
bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_GP0_IO, val);
- mutex_enter(&sc->sc_delaylock);
- cv_timedwait(&sc->sc_delaycv, &sc->sc_delaylock, mstohz(15));
- mutex_exit(&sc->sc_delaylock);
+ delay(200000);
}
MODULE(MODULE_CLASS_DRIVER, cxdtv, "dtv,tvpll,nxt2k,lg3303");
diff -r 7c80d6caf3a9 -r 9c6802b95f59 sys/dev/pci/cxdtvvar.h
--- a/sys/dev/pci/cxdtvvar.h Thu Jul 14 23:50:12 2011 +0000
+++ b/sys/dev/pci/cxdtvvar.h Fri Jul 15 00:21:26 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cxdtvvar.h,v 1.1 2011/07/11 00:46:04 jakllsch Exp $ */
+/* $NetBSD: cxdtvvar.h,v 1.2 2011/07/15 00:21:26 jmcneill Exp $ */
/*
* Copyright (c) 2008, 2011 Jonathan A. Kollasch
@@ -76,6 +76,8 @@
device_t sc_dev;
device_t sc_dtvdev;
+ pci_chipset_tag_t sc_pc;
+
bus_space_tag_t sc_memt;
bus_space_handle_t sc_memh;
bus_size_t sc_mems;
Home |
Main Index |
Thread Index |
Old Index