Module Name: src Committed By: jmcneill Date: Fri Jul 15 00:21:26 UTC 2011
Modified Files: src/sys/dev/pci: cxdtv.c cxdtvvar.h Log Message: add detach support To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/pci/cxdtv.c cvs rdiff -u -r1.1 -r1.2 src/sys/dev/pci/cxdtvvar.h 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/cxdtv.c diff -u src/sys/dev/pci/cxdtv.c:1.2 src/sys/dev/pci/cxdtv.c:1.3 --- src/sys/dev/pci/cxdtv.c:1.2 Thu Jul 14 23:47:45 2011 +++ src/sys/dev/pci/cxdtv.c Fri Jul 15 00:21:26 2011 @@ -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"); Index: src/sys/dev/pci/cxdtvvar.h diff -u src/sys/dev/pci/cxdtvvar.h:1.1 src/sys/dev/pci/cxdtvvar.h:1.2 --- src/sys/dev/pci/cxdtvvar.h:1.1 Mon Jul 11 00:46:04 2011 +++ src/sys/dev/pci/cxdtvvar.h Fri Jul 15 00:21:26 2011 @@ -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;