From owner-svn-src-head@FreeBSD.ORG Thu Mar 5 02:54:31 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 628D0866; Thu, 5 Mar 2015 02:54:31 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4373ABA4; Thu, 5 Mar 2015 02:54:31 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t252sVcC051885; Thu, 5 Mar 2015 02:54:31 GMT (envelope-from loos@FreeBSD.org) Received: (from loos@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t252sVwp051883; Thu, 5 Mar 2015 02:54:31 GMT (envelope-from loos@FreeBSD.org) Message-Id: <201503050254.t252sVwp051883@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: loos set sender to loos@FreeBSD.org using -f From: Luiz Otavio O Souza Date: Thu, 5 Mar 2015 02:54:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r279621 - head/sys/dev/gpio X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Mar 2015 02:54:31 -0000 Author: loos Date: Thu Mar 5 02:54:30 2015 New Revision: 279621 URL: https://svnweb.freebsd.org/changeset/base/279621 Log: Change ofw_gpiobus_destroy_devinfo() to unmap the GPIO pins and then rework the code a little bit to use this function consistently to cleanup all the changes made as part of the probe phase. This fixes an issue where a FDT child node without a matching driver could leave the GPIO pins mapped and prevent the further use of them. Modified: head/sys/dev/gpio/ofw_gpiobus.c Modified: head/sys/dev/gpio/ofw_gpiobus.c ============================================================================== --- head/sys/dev/gpio/ofw_gpiobus.c Thu Mar 5 01:49:58 2015 (r279620) +++ head/sys/dev/gpio/ofw_gpiobus.c Thu Mar 5 02:54:30 2015 (r279621) @@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$"); static struct ofw_gpiobus_devinfo *ofw_gpiobus_setup_devinfo(device_t, device_t, phandle_t); -static void ofw_gpiobus_destroy_devinfo(struct ofw_gpiobus_devinfo *); +static void ofw_gpiobus_destroy_devinfo(device_t, struct ofw_gpiobus_devinfo *); static int ofw_gpiobus_parse_gpios_impl(device_t, phandle_t, char *, struct gpiobus_softc *, struct gpiobus_pin **); @@ -63,7 +63,7 @@ ofw_gpiobus_add_fdt_child(device_t bus, return (NULL); } if (device_probe_and_attach(childdev) != 0) { - ofw_gpiobus_destroy_devinfo(dinfo); + ofw_gpiobus_destroy_devinfo(bus, dinfo); device_delete_child(bus, childdev); return (NULL); } @@ -117,41 +117,50 @@ ofw_gpiobus_setup_devinfo(device_t bus, } /* Parse the gpios property for the child. */ npins = ofw_gpiobus_parse_gpios_impl(child, node, "gpios", sc, &pins); - if (npins <= 0) - goto fail; + if (npins <= 0) { + ofw_bus_gen_destroy_devinfo(&dinfo->opd_obdinfo); + free(dinfo, M_DEVBUF); + return (NULL); + } + /* Initialize the irq resource list. */ + resource_list_init(&dinfo->opd_dinfo.rl); + /* Allocate the child ivars and copy the parsed pin data. */ devi = &dinfo->opd_dinfo; devi->npins = (uint32_t)npins; if (gpiobus_alloc_ivars(devi) != 0) { free(pins, M_DEVBUF); - goto fail; + ofw_gpiobus_destroy_devinfo(bus, dinfo); + return (NULL); } for (i = 0; i < devi->npins; i++) { devi->flags[i] = pins[i].flags; devi->pins[i] = pins[i].pin; } free(pins, M_DEVBUF); - /* And now the interrupt resources. */ - resource_list_init(&dinfo->opd_dinfo.rl); + /* Parse the interrupt resources. */ if (ofw_bus_intr_to_rl(bus, node, &dinfo->opd_dinfo.rl) != 0) { - gpiobus_free_ivars(devi); - goto fail; + ofw_gpiobus_destroy_devinfo(bus, dinfo); + return (NULL); } device_set_ivars(child, dinfo); return (dinfo); - -fail: - ofw_bus_gen_destroy_devinfo(&dinfo->opd_obdinfo); - free(dinfo, M_DEVBUF); - return (NULL); } static void -ofw_gpiobus_destroy_devinfo(struct ofw_gpiobus_devinfo *dinfo) +ofw_gpiobus_destroy_devinfo(device_t bus, struct ofw_gpiobus_devinfo *dinfo) { + int i; struct gpiobus_ivar *devi; + struct gpiobus_softc *sc; + sc = device_get_softc(bus); devi = &dinfo->opd_dinfo; + for (i = 0; i < devi->npins; i++) { + if (devi->pins[i] > sc->sc_npins) + continue; + sc->sc_pins_mapped[devi->pins[i]] = 0; + } gpiobus_free_ivars(devi); resource_list_free(&dinfo->opd_dinfo.rl); ofw_bus_gen_destroy_devinfo(&dinfo->opd_obdinfo);