Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Jun 2016 04:33:01 +0000 (UTC)
From:      "Landon J. Fuller" <landonf@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r302189 - in head/sys: dev/bhnd dev/bhnd/cores/chipc mips/broadcom
Message-ID:  <201606250433.u5P4X1G8050443@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: landonf
Date: Sat Jun 25 04:33:00 2016
New Revision: 302189
URL: https://svnweb.freebsd.org/changeset/base/302189

Log:
  bhnd(4): Perform explicit chipc child enumeration.
  
  Replaces use of DEVICE_IDENTIFY with explicit enumeration of chipc
  child devices using the chipc capability structure.
  
  This is a precursor to PMU support, which requires more complex resource
  assignment handling than achievable with the static device name-based
  hints table.
  
  Reviewed by:	Michael Zhilin <mizkha@gmail.com> (Broadcom MIPS support)
  Approved by:	re (gjb), adrian (mentor)
  Differential Revision:	https://reviews.freebsd.org/D6896

Modified:
  head/sys/dev/bhnd/bhnd_bus_if.m
  head/sys/dev/bhnd/bhnd_subr.c
  head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m
  head/sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c
  head/sys/dev/bhnd/cores/chipc/chipc.c
  head/sys/dev/bhnd/cores/chipc/chipc_cfi.c
  head/sys/dev/bhnd/cores/chipc/chipc_private.h
  head/sys/dev/bhnd/cores/chipc/chipc_slicer.c
  head/sys/dev/bhnd/cores/chipc/chipc_slicer.h
  head/sys/dev/bhnd/cores/chipc/chipc_spi.c
  head/sys/dev/bhnd/cores/chipc/chipc_spi.h
  head/sys/dev/bhnd/cores/chipc/chipc_subr.c
  head/sys/dev/bhnd/cores/chipc/chipcreg.h
  head/sys/dev/bhnd/cores/chipc/chipcvar.h
  head/sys/mips/broadcom/uart_bus_chipc.c

Modified: head/sys/dev/bhnd/bhnd_bus_if.m
==============================================================================
--- head/sys/dev/bhnd/bhnd_bus_if.m	Sat Jun 25 02:09:49 2016	(r302188)
+++ head/sys/dev/bhnd/bhnd_bus_if.m	Sat Jun 25 04:33:00 2016	(r302189)
@@ -55,6 +55,12 @@ CODE {
 		panic("bhnd_bus_get_chipid unimplemented");
 	}
 
+	static bhnd_attach_type
+	bhnd_bus_null_get_attach_type(device_t dev, device_t child)
+	{
+		panic("bhnd_bus_get_attach_type unimplemented");
+	}
+
 	static int
 	bhnd_bus_null_read_board_info(device_t dev, device_t child,
 	    struct bhnd_board_info *info)
@@ -197,7 +203,7 @@ METHOD const struct bhnd_chipid * get_ch
 METHOD bhnd_attach_type get_attach_type {
 	device_t dev;
 	device_t child;
-} DEFAULT bhnd_bus_generic_get_attach_type;
+} DEFAULT bhnd_bus_null_get_attach_type;
 
 /**
  * Attempt to read the BHND board identification from the parent bus.

Modified: head/sys/dev/bhnd/bhnd_subr.c
==============================================================================
--- head/sys/dev/bhnd/bhnd_subr.c	Sat Jun 25 02:09:49 2016	(r302188)
+++ head/sys/dev/bhnd/bhnd_subr.c	Sat Jun 25 04:33:00 2016	(r302189)
@@ -1159,21 +1159,3 @@ bhnd_bus_generic_deactivate_resource(dev
 	return (EINVAL);
 };
 
-/**
- * Helper function for implementing BHND_BUS_GET_ATTACH_TYPE().
- *
- * This implementation of BHND_BUS_GET_ATTACH_TYPE() simply calls the
- * BHND_BUS_GET_ATTACH_TYPE() method of the parent of @p dev.
- */
-bhnd_attach_type
-bhnd_bus_generic_get_attach_type(device_t dev, device_t child)
-{
-	/* iterate from cores via bhnd to bridge or SoC */
-	if (device_get_parent(dev) != NULL)
-		return (BHND_BUS_GET_ATTACH_TYPE(device_get_parent(dev),
-		    child));
-
-	panic("bhnd_bus_get_attach_type unimplemented");
-	/* Unreachable */
-	return (BHND_ATTACH_ADAPTER);
-}

Modified: head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m	Sat Jun 25 02:09:49 2016	(r302188)
+++ head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m	Sat Jun 25 04:33:00 2016	(r302189)
@@ -36,32 +36,16 @@ INTERFACE bhnd_chipc;
 #
 
 HEADER {
-	#include <dev/bhnd/nvram/bhnd_nvram.h>
 	/* forward declarations */
 	struct chipc_caps;
-	struct chipc_caps	*bhnd_chipc_generic_get_caps(device_t dev);
 }
 
 CODE {
-
-	/**
-	 * Helper function for implementing BHND_CHIPC_GET_CAPS().
-	 *
-	 * This implementation of BHND_CHIPC_GET_CAPS() simply calls the
-	 * BHND_CHIPC_GET_CAPS() method of the parent of @p dev.
-	 */
-	struct chipc_caps*
-	bhnd_chipc_generic_get_caps(device_t dev)
+	static struct chipc_caps *
+	bhnd_chipc_null_get_caps(device_t dev)
 	{
-	
-		if (device_get_parent(dev) != NULL)
-			return (BHND_CHIPC_GET_CAPS(device_get_parent(dev)));
-	
 		panic("bhnd_chipc_generic_get_caps unimplemented");
-		/* Unreachable */
-		return (NULL);
 	}
-
 }
 
 /**
@@ -91,7 +75,7 @@ METHOD void write_chipctrl {
  */
 METHOD struct chipc_caps * get_caps {
 	device_t dev;
-} DEFAULT bhnd_chipc_generic_get_caps;
+} DEFAULT bhnd_chipc_null_get_caps;
 
 /**
  * Enable hardware access to the SPROM/OTP source.
@@ -114,12 +98,3 @@ METHOD int enable_sprom {
 METHOD void disable_sprom {
 	device_t dev;
 }
-
-/**
- * Return the flash configuration register value
- *
- * @param dev A bhnd(4) ChipCommon device
- */
-METHOD uint32_t get_flash_cfg {
-	device_t dev;
-}

Modified: head/sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c	Sat Jun 25 02:09:49 2016	(r302188)
+++ head/sys/dev/bhnd/cores/chipc/bhnd_sprom_chipc.c	Sat Jun 25 04:33:00 2016	(r302189)
@@ -54,22 +54,6 @@ __FBSDID("$FreeBSD$");
 #define	CHIPC_VALID_SPROM_SRC(_src)	\
 	((_src) == BHND_NVRAM_SRC_SPROM || (_src) == BHND_NVRAM_SRC_OTP)
 
-static void
-chipc_sprom_identify(driver_t *driver, device_t parent)
-{
-	struct chipc_caps *caps;
-	
-	caps = BHND_CHIPC_GET_CAPS(parent);
-	if (!CHIPC_VALID_SPROM_SRC(caps->nvram_src))
-		return;
-
-	if (device_find_child(parent, "bhnd_nvram", 0) != NULL)
-		return;
-
-	if (BUS_ADD_CHILD(parent, 0, "bhnd_nvram", 0) == NULL)
-		device_printf(parent, "add bhnd_nvram failed\n");
-}
-
 static int
 chipc_sprom_probe(device_t dev)
 {
@@ -113,7 +97,6 @@ chipc_sprom_attach(device_t dev)
 
 static device_method_t chipc_sprom_methods[] = {
 	/* Device interface */
-	DEVMETHOD(device_identify,		chipc_sprom_identify),
 	DEVMETHOD(device_probe,			chipc_sprom_probe),
 	DEVMETHOD(device_attach,		chipc_sprom_attach),
 	DEVMETHOD_END

Modified: head/sys/dev/bhnd/cores/chipc/chipc.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc.c	Sat Jun 25 02:09:49 2016	(r302188)
+++ head/sys/dev/bhnd/cores/chipc/chipc.c	Sat Jun 25 04:33:00 2016	(r302189)
@@ -37,25 +37,8 @@ __FBSDID("$FreeBSD$");
  * With the exception of some very early chipsets, the ChipCommon core
  * has been included in all HND SoCs and chipsets based on the siba(4) 
  * and bcma(4) interconnects, providing a common interface to chipset 
- * identification, bus enumeration, UARTs, clocks, watchdog interrupts, GPIO, 
- * flash, etc.
- *
- * The purpose of this driver is memory resource management for ChipCommon drivers
- * like UART, PMU, flash. ChipCommon core has several memory regions.
- *
- * ChipCommon driver has memory resource manager. Driver
- * gets information about BHND core ports/regions and map them
- * into drivers' resources.
- *
- * Here is overview of mapping:
- *
- * ------------------------------------------------------
- * | Port.Region| Purpose				|
- * ------------------------------------------------------
- * |	0.0	| PMU, SPI(0x40), UART(0x300)           |
- * |	1.0	| ?					|
- * |	1.1	| MMIO flash (SPI & CFI)		|
- * ------------------------------------------------------
+ * identification, bus enumeration, UARTs, clocks, watchdog interrupts,
+ * GPIO, flash, etc.
  */
 
 #include <sys/param.h>
@@ -76,6 +59,7 @@ __FBSDID("$FreeBSD$");
 
 #include "chipcreg.h"
 #include "chipcvar.h"
+
 #include "chipc_private.h"
 
 devclass_t bhnd_chipc_devclass;	/**< bhnd(4) chipcommon device class */
@@ -123,49 +107,10 @@ static struct bhnd_device_quirk chipc_qu
 	BHND_DEVICE_QUIRK_END
 };
 
+// FIXME: IRQ shouldn't be hard-coded
+#define	CHIPC_MIPS_IRQ	2
 
-/*
- * Here is resource configuration hints for child devices
- *
- * [Flash] There are 2 flash resources:
- *  - resource ID (rid) = 0: memory-mapped flash memory
- *  - resource ID (rid) = 1: memory-mapped flash registers (i.e for SPI)
- *
- * [UART] Uses IRQ and memory resources:
- *  - resource ID (rid) = 0: memory-mapped registers
- *  - IRQ resource ID (rid) = 0: shared IRQ line for Tx/Rx.
- */
-
-static const struct chipc_hint {
-	const char	*name;
-	int		 unit;
-	int		 type;
-	int		 rid;
-	rman_res_t	 base;		/* relative to parent resource */
-	rman_res_t	 size;
-	u_int		 port;		/* ignored if SYS_RES_IRQ */
-	u_int		 region;
-} chipc_hints[] = {
-	// FIXME: cfg/spi port1.1 mapping on siba(4) SoCs
-	// FIXME: IRQ shouldn't be hardcoded
-	/* device	unit	type		rid	base			size			port,region */
-	{ "bhnd_nvram",	0, SYS_RES_MEMORY,	0,	CHIPC_SPROM_OTP,	CHIPC_SPROM_OTP_SIZE,	0,0 },
-	{ "uart",	0, SYS_RES_MEMORY,	0,	CHIPC_UART0_BASE,	CHIPC_UART_SIZE,	0,0 },
-	{ "uart",	0, SYS_RES_IRQ,		0,	2,			1 },
-	{ "uart",	1, SYS_RES_MEMORY,	0,	CHIPC_UART1_BASE,	CHIPC_UART_SIZE,	0,0 },
-	{ "uart",	1, SYS_RES_IRQ,		0,	2,			1 },
-	{ "spi",	0, SYS_RES_MEMORY,	0,	0,			RM_MAX_END,		1,1 },
-	{ "spi",	0, SYS_RES_MEMORY,	1,	CHIPC_SFLASH_BASE,	CHIPC_SFLASH_SIZE,	0,0 },
-	{ "cfi",	0, SYS_RES_MEMORY,	0,	0,			RM_MAX_END,		1,1},
-	{ "cfi",	0, SYS_RES_MEMORY, 	1,	CHIPC_SFLASH_BASE,	CHIPC_SFLASH_SIZE,	0,0 },
-	{ NULL }
-};
-
-
-static int			 chipc_try_activate_resource(
-				    struct chipc_softc *sc, device_t child,
-				    int type, int rid, struct resource *r,
-				    bool req_direct);
+static int			 chipc_add_children(struct chipc_softc *sc);
 
 static bhnd_nvram_src		 chipc_find_nvram_src(struct chipc_softc *sc,
 				     struct chipc_caps *caps);
@@ -175,6 +120,11 @@ static int			 chipc_read_caps(struct chi
 static bool			 chipc_should_enable_sprom(
 				     struct chipc_softc *sc);
 
+static int			 chipc_try_activate_resource(
+				    struct chipc_softc *sc, device_t child,
+				    int type, int rid, struct resource *r,
+				    bool req_direct);
+
 static int			 chipc_init_rman(struct chipc_softc *sc);
 static void			 chipc_free_rman(struct chipc_softc *sc);
 static struct rman		*chipc_get_rman(struct chipc_softc *sc,
@@ -210,9 +160,6 @@ static int
 chipc_attach(device_t dev)
 {
 	struct chipc_softc		*sc;
-	bhnd_addr_t			 enum_addr;
-	uint32_t			 ccid_reg;
-	uint8_t				 chip_type;
 	int				 error;
 
 	sc = device_get_softc(dev);
@@ -231,7 +178,7 @@ chipc_attach(device_t dev)
 		goto failed;
 	}
 
-	/* Allocate the region containing our core registers */
+	/* Allocate the region containing the chipc register block */
 	if ((sc->core_region = chipc_find_region_by_rid(sc, 0)) == NULL) {
 		error = ENXIO;
 		goto failed;
@@ -242,30 +189,10 @@ chipc_attach(device_t dev)
 	if (error) {
 		sc->core_region = NULL;
 		goto failed;
-	} else {
-		sc->core = sc->core_region->cr_res;
 	}
 
-	/* Fetch our chipset identification data */
-	ccid_reg = bhnd_bus_read_4(sc->core, CHIPC_ID);
-	chip_type = CHIPC_GET_BITS(ccid_reg, CHIPC_ID_BUS);
-
-	switch (chip_type) {
-	case BHND_CHIPTYPE_SIBA:
-		/* enumeration space starts at the ChipCommon register base. */
-		enum_addr = rman_get_start(sc->core->res);
-		break;
-	case BHND_CHIPTYPE_BCMA:
-	case BHND_CHIPTYPE_BCMA_ALT:
-		enum_addr = bhnd_bus_read_4(sc->core, CHIPC_EROMPTR);
-		break;
-	default:
-		device_printf(dev, "unsupported chip type %hhu\n", chip_type);
-		error = ENODEV;
-		goto failed;
-	}
-
-	sc->ccid = bhnd_parse_chipid(ccid_reg, enum_addr);
+	/* Save a direct reference to our chipc registers */
+	sc->core = sc->core_region->cr_res;
 
 	/* Fetch and parse capability register(s) */
 	if ((error = chipc_read_caps(sc, &sc->caps)))
@@ -274,8 +201,10 @@ chipc_attach(device_t dev)
 	if (bootverbose)
 		chipc_print_caps(sc->dev, &sc->caps);
 
-	/* Probe and attach children */
-	bus_generic_probe(dev);
+	/* Attach all supported child devices */
+	if ((error = chipc_add_children(sc)))
+		goto failed;
+
 	if ((error = bus_generic_attach(dev)))
 		goto failed;
 
@@ -313,6 +242,119 @@ chipc_detach(device_t dev)
 	return (0);
 }
 
+static int
+chipc_add_children(struct chipc_softc *sc)
+{
+	device_t	 child;
+	const char	*flash_bus;
+	int		 error;
+
+	/* SPROM/OTP */
+	if (sc->caps.nvram_src == BHND_NVRAM_SRC_SPROM ||
+	    sc->caps.nvram_src == BHND_NVRAM_SRC_OTP)
+	{
+		child = BUS_ADD_CHILD(sc->dev, 0, "bhnd_nvram", -1);
+		if (child == NULL) {
+			device_printf(sc->dev, "failed to add nvram device\n");
+			return (ENXIO);
+		}
+
+		/* Both OTP and external SPROM are mapped at CHIPC_SPROM_OTP */
+		error = chipc_set_resource(sc, child, SYS_RES_MEMORY, 0,
+		    CHIPC_SPROM_OTP, CHIPC_SPROM_OTP_SIZE, 0, 0);
+		if (error)
+			return (error);
+	}
+
+#ifdef notyet
+	/*
+	 * PMU/SLOWCLK/INSTACLK
+	 * 
+	 * On AOB ("Always on Bus") devices, a PMU core (if it exists) is
+	 * enumerated directly by the bhnd(4) bus -- not chipc.
+	 * 
+	 * Otherwise, we always add a PMU child device, and let the
+	 * chipc bhnd_pmu drivers probe for it. If the core supports an
+	 * earlier non-PMU clock/power register interface, one of the instaclk,
+	 * powerctl, or null bhnd_pmu drivers will claim the device.
+	 */
+	if (!sc->caps.aob || (sc->caps.aob && !sc->caps.pmu)) {
+		child = BUS_ADD_CHILD(sc->dev, 0, "bhnd_pmu", -1);
+		if (child == NULL) {
+			device_printf(sc->dev, "failed to add pmu\n");
+			return (ENXIO);
+		}
+
+		/* Associate the applicable register block */
+		error = 0;
+		if (sc->caps.pmu) {
+			error = chipc_set_resource(sc, child, SYS_RES_MEMORY, 0,
+			    CHIPC_PMU, CHIPC_PMU_SIZE, 0, 0);
+		} else if (sc->caps.power_control) {
+			error = chipc_set_resource(sc, child, SYS_RES_MEMORY, 0,
+			    CHIPC_PWRCTL, CHIPC_PWRCTL_SIZE, 0, 0);
+		}
+
+		if (error)
+			return (error);
+		
+	}
+#endif /* notyet */
+
+	/* All remaining devices are SoC-only */
+	if (bhnd_get_attach_type(sc->dev) != BHND_ATTACH_NATIVE)
+		return (0);
+
+	/* UARTs */
+	for (u_int i = 0; i < min(sc->caps.num_uarts, CHIPC_UART_MAX); i++) {
+		child = BUS_ADD_CHILD(sc->dev, 0, "uart", -1);
+		if (child == NULL) {
+			device_printf(sc->dev, "failed to add uart%u\n", i);
+			return (ENXIO);
+		}
+
+		/* Shared IRQ */
+		error = bus_set_resource(child, SYS_RES_IRQ, 0, CHIPC_MIPS_IRQ,
+		    1);
+		if (error) {
+			device_printf(sc->dev, "failed to set uart%u irq %u\n",
+			    i, CHIPC_MIPS_IRQ);
+			return (error);
+		}
+
+		/* UART registers are mapped sequentially */
+		error = chipc_set_resource(sc, child, SYS_RES_MEMORY, 0,
+		    CHIPC_UART(i), CHIPC_UART_SIZE, 0, 0);
+		if (error)
+			return (error);
+	}
+
+	/* Flash */
+	flash_bus = chipc_flash_bus_name(sc->caps.flash_type);
+	if (flash_bus != NULL) {
+		child = BUS_ADD_CHILD(sc->dev, 0, flash_bus, -1);
+		if (child == NULL) {
+			device_printf(sc->dev, "failed to add %s device\n",
+			    flash_bus);
+			return (ENXIO);
+		}
+
+		/* flash memory mapping */
+		error = chipc_set_resource(sc, child, SYS_RES_MEMORY, 0,
+		    0, RM_MAX_END, 1, 1);
+		if (error)
+			return (error);
+
+		/* flashctrl registers */
+		error = chipc_set_resource(sc, child, SYS_RES_MEMORY, 1,
+		    CHIPC_SFLASH_BASE, CHIPC_SFLASH_SIZE, 0, 0);
+		if (error)
+			return (error);
+	}
+
+	return (0);
+}
+
 /**
  * Determine the NVRAM data source for this device.
  * 
@@ -411,7 +453,6 @@ chipc_read_caps(struct chipc_softc *sc, 
 
 	/* Determine flash type and parameters */
 	caps->cfi_width = 0;
-
 	switch (CHIPC_GET_BITS(cap_reg, CHIPC_CAP_FLASH)) {
 	case CHIPC_CAP_SFLASH_ST:
 		caps->flash_type = CHIPC_SFLASH_ST;
@@ -420,6 +461,7 @@ chipc_read_caps(struct chipc_softc *sc, 
 		caps->flash_type = CHIPC_SFLASH_AT;
 		break;
 	case CHIPC_CAP_NFLASH:
+		/* unimplemented */
 		caps->flash_type = CHIPC_NFLASH;
 		break;
 	case CHIPC_CAP_PFLASH:
@@ -548,33 +590,16 @@ chipc_child_location_str(device_t dev, d
 static device_t
 chipc_add_child(device_t dev, u_int order, const char *name, int unit)
 {
+	struct chipc_softc	*sc;
 	struct chipc_devinfo	*dinfo;
-	const struct chipc_hint	*hint;
 	device_t		 child;
-	devclass_t		 child_dc;
-	int			 error;
-	int 			 busrel_unit;
+
+	sc = device_get_softc(dev);
 
 	child = device_add_child_ordered(dev, order, name, unit);
 	if (child == NULL)
 		return (NULL);
 
-	/* system-wide device unit */
-	unit = device_get_unit(child);
-	child_dc = device_get_devclass(child);
-
-	busrel_unit = 0;
-	for (int i = 0; i < unit; i++) {
-		device_t	tmp;
-
-		tmp = devclass_get_device(child_dc, i);
-		if (tmp != NULL && (device_get_parent(tmp) == dev))
-	                busrel_unit++;
-	}
-
-	/* bus-wide device unit (override unit for further hint matching) */
-	unit = busrel_unit;
-
 	dinfo = malloc(sizeof(struct chipc_devinfo), M_BHND, M_NOWAIT);
 	if (dinfo == NULL) {
 		device_delete_child(dev, child);
@@ -584,93 +609,7 @@ chipc_add_child(device_t dev, u_int orde
 	resource_list_init(&dinfo->resources);
 	device_set_ivars(child, dinfo);
 
-	/* Hint matching requires a device name */
-	if (name == NULL)
-		return (child);
-
-	/* Use hint table to set child resources */
-	for (hint = chipc_hints; hint->name != NULL; hint++) {
-		bhnd_addr_t	region_addr;
-		bhnd_size_t	region_size;
-
-		/* Check device name */
-		if (strcmp(hint->name, name) != 0)
-			continue;
-
-		/* Check device unit */
-		if (hint->unit >= 0 && unit != hint->unit)
-			continue;
-
-		switch (hint->type) {
-		case SYS_RES_IRQ:
-			/* Add child resource */
-			error = bus_set_resource(child, hint->type, hint->rid,
-			    hint->base, hint->size);
-			if (error) {
-				device_printf(dev,
-				    "bus_set_resource() failed for %s: %d\n",
-				    device_get_nameunit(child), error);
-				goto failed;
-			}
-			break;
-
-		case SYS_RES_MEMORY:
-			/* Fetch region address and size */
-			error = bhnd_get_region_addr(dev, BHND_PORT_DEVICE,
-			    hint->port, hint->region, &region_addr,
-			    &region_size);
-			if (error) {
-				device_printf(dev,
-				    "lookup of %s%u.%u failed: %d\n",
-				    bhnd_port_type_name(BHND_PORT_DEVICE),
-				    hint->port, hint->region, error);
-				goto failed;
-			}
-
-			/* Verify requested range is mappable */
-			if (hint->base > region_size ||
-			    (hint->size != RM_MAX_END &&
-				(hint->size > region_size ||
-				 region_size - hint->base < hint->size )))
-			{
-				device_printf(dev,
-				    "%s%u.%u region cannot map requested range "
-				        "%#jx+%#jx\n",
-				    bhnd_port_type_name(BHND_PORT_DEVICE),
-				    hint->port, hint->region, hint->base,
-				    hint->size);
-			}
-
-			/*
-			 * Add child resource. If hint doesn't define the end
-			 * of resource window (RX_MAX_END), use end of region.
-			 */
-
-			error = bus_set_resource(child,
-				    hint->type,
-				    hint->rid, region_addr + hint->base,
-				    (hint->size == RM_MAX_END) ?
-					    region_size - hint->base :
-					    hint->size);
-			if (error) {
-				device_printf(dev,
-				    "bus_set_resource() failed for %s: %d\n",
-				    device_get_nameunit(child), error);
-				goto failed;
-			}
-			break;
-		default:
-			device_printf(child, "unknown hint resource type: %d\n",
-			    hint->type);
-			break;
-		}
-	}
-
 	return (child);
-
-failed:
-	device_delete_child(dev, child);
-	return (NULL);
 }
 
 static void
@@ -705,7 +644,7 @@ chipc_rman_init_regions (struct chipc_so
 	u_int			 num_regions;
 	int			 error;
 
-	num_regions = bhnd_get_region_count(sc->dev, port, port);
+	num_regions = bhnd_get_region_count(sc->dev, type, port);
 	for (u_int region = 0; region < num_regions; region++) {
 		/* Allocate new region record */
 		cr = chipc_alloc_region(sc, type, port, region);
@@ -1349,15 +1288,6 @@ chipc_get_caps(device_t dev)
 	return (&sc->caps);
 }
 
-static uint32_t
-chipc_get_flash_cfg(device_t dev)
-{
-	struct chipc_softc	*sc;
-
-	sc = device_get_softc(dev);
-	return (bhnd_bus_read_4(sc->core, CHIPC_FLASH_CFG));
-}
-
 static device_method_t chipc_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,			chipc_probe),
@@ -1399,7 +1329,6 @@ static device_method_t chipc_methods[] =
 	DEVMETHOD(bhnd_chipc_enable_sprom,	chipc_enable_sprom_pins),
 	DEVMETHOD(bhnd_chipc_disable_sprom,	chipc_disable_sprom_pins),
 	DEVMETHOD(bhnd_chipc_get_caps,		chipc_get_caps),
-	DEVMETHOD(bhnd_chipc_get_flash_cfg,	chipc_get_flash_cfg),
 
 	DEVMETHOD_END
 };

Modified: head/sys/dev/bhnd/cores/chipc/chipc_cfi.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc_cfi.c	Sat Jun 25 02:09:49 2016	(r302188)
+++ head/sys/dev/bhnd/cores/chipc/chipc_cfi.c	Sat Jun 25 04:33:00 2016	(r302189)
@@ -40,90 +40,39 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/bus.h>
 
-#include <dev/bhnd/bhnd_debug.h>
 #include <dev/cfi/cfi_var.h>
 
 #include "bhnd_chipc_if.h"
-#include "chipc_slicer.h"
+
 #include "chipcreg.h"
 #include "chipcvar.h"
-
-/*
- * **************************** PROTOTYPES ****************************
- */
-
-static void	chipc_cfi_identify(driver_t *driver, device_t parent);
-static int	chipc_cfi_probe(device_t dev);
-static int	chipc_cfi_attach(device_t dev);
-
-/*
- * **************************** IMPLEMENTATION ************************
- */
-
-static void
-chipc_cfi_identify(driver_t *driver, device_t parent)
-{
-	struct chipc_caps	*caps;
-
-	if (device_find_child(parent, cfi_driver_name, -1) != NULL)
-		return;
-
-	caps = BHND_CHIPC_GET_CAPS(parent);
-	if (caps == NULL)
-		return;
-
-	if (caps->flash_type != CHIPC_PFLASH_CFI)
-		return;
-
-	BUS_ADD_CHILD(parent, 0, cfi_driver_name, -1);
-	return;
-}
+#include "chipc_slicer.h"
 
 static int
 chipc_cfi_probe(device_t dev)
 {
-	int			error;
-	int			enabled;
-	int			byteswap;
-	uint32_t		flash_config;
 	struct cfi_softc	*sc;
+	int			error;
 
 	sc = device_get_softc(dev);
 
-	flash_config = BHND_CHIPC_GET_FLASH_CFG(device_get_parent(dev));
-
-	enabled = (flash_config & CHIPC_CF_EN);
-	byteswap = (flash_config & CHIPC_CF_BS);
-
-	if (enabled == 0)
-		device_disable(dev);
-
-	BHND_DEBUG_DEV(dev, "trying attach flash enabled=%d swapbytes=%d",
-	    enabled, byteswap);
-
 	sc->sc_width = 0;
-	error = cfi_probe(dev);
-	if (error == 0)
-		device_set_desc(dev, "ChipCommon CFI");
+	if ((error = cfi_probe(dev)) > 0)
+		return (error);
+
+	device_set_desc(dev, "Broadcom ChipCommon CFI");
 	return (error);
 }
 
 static int
 chipc_cfi_attach(device_t dev)
 {
-	int	error;
-
-	error = cfi_attach(dev);
-	if (error)
-		return (error);
-
-	flash_register_slicer(chipc_slicer_cfi);
-	return (0);
+	chipc_register_slicer(CHIPC_PFLASH_CFI);
+	return (cfi_attach(dev));
 }
 
 static device_method_t chipc_cfi_methods[] = {
 	/* device interface */
-	DEVMETHOD(device_identify,	chipc_cfi_identify),
 	DEVMETHOD(device_probe,		chipc_cfi_probe),
 	DEVMETHOD(device_attach,	chipc_cfi_attach),
 	DEVMETHOD(device_detach,	cfi_detach),
@@ -138,4 +87,3 @@ static driver_t chipc_cfi_driver = {
 };
 
 DRIVER_MODULE(cfi, bhnd_chipc, chipc_cfi_driver, cfi_devclass, 0, 0);
-

Modified: head/sys/dev/bhnd/cores/chipc/chipc_private.h
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc_private.h	Sat Jun 25 02:09:49 2016	(r302188)
+++ head/sys/dev/bhnd/cores/chipc/chipc_private.h	Sat Jun 25 04:33:00 2016	(r302189)
@@ -55,6 +55,11 @@ int			 chipc_init_child_resource(struct 
 			     struct resource *parent, 
 			     bhnd_size_t offset, bhnd_size_t size);
 
+int			 chipc_set_resource(struct chipc_softc *sc,
+			     device_t child, int type, int rid,
+			     rman_res_t start, rman_res_t count, u_int port,
+			     u_int region);
+
 struct chipc_region	*chipc_alloc_region(struct chipc_softc *sc,
 			     bhnd_port_type type, u_int port,
 			     u_int region);

Modified: head/sys/dev/bhnd/cores/chipc/chipc_slicer.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc_slicer.c	Sat Jun 25 02:09:49 2016	(r302188)
+++ head/sys/dev/bhnd/cores/chipc/chipc_slicer.c	Sat Jun 25 04:33:00 2016	(r302189)
@@ -54,58 +54,88 @@ __FBSDID("$FreeBSD$");
 #include <dev/cfi/cfi_var.h>
 #include "chipc_spi.h"
 
-static int	chipc_slicer_walk(device_t dev, struct resource* res,
+static int	chipc_slicer_walk(device_t dev, struct resource *res,
 		    struct flash_slice *slices, int *nslices);
 
+void
+chipc_register_slicer(chipc_flash flash_type)
+{
+	switch (flash_type) {
+	case CHIPC_SFLASH_AT:
+	case CHIPC_SFLASH_ST:
+		flash_register_slicer(chipc_slicer_spi);
+		break;
+	case CHIPC_PFLASH_CFI:
+		flash_register_slicer(chipc_slicer_cfi);
+		break;
+	default:
+		/* Unsupported */
+		break;
+	}
+}
+
 int
 chipc_slicer_cfi(device_t dev, struct flash_slice *slices, int *nslices)
 {
 	struct cfi_softc	*sc;
+	device_t		 parent;
 
-	if (strcmp("cfi", device_get_name(dev)) != 0)
-		return (0);
+	/* must be CFI flash */
+	if (device_get_devclass(dev) != devclass_find("cfi"))
+		return (ENXIO);
+
+	/* must be attached to chipc */
+	if ((parent = device_get_parent(dev)) == NULL) {
+		BHND_ERROR_DEV(dev, "no found ChipCommon device");
+		return (ENXIO);
+	}
 
-	sc = device_get_softc(dev);
+	if (device_get_devclass(parent) != devclass_find("bhnd_chipc")) {
+		BHND_ERROR_DEV(dev, "no found ChipCommon device");
+		return (ENXIO);
+	}
 
+	sc = device_get_softc(dev);
 	return (chipc_slicer_walk(dev, sc->sc_res, slices, nslices));
 }
 
 int
 chipc_slicer_spi(device_t dev, struct flash_slice *slices, int *nslices)
 {
-	/* flash(mx25l) <- spibus <- chipc_spi */
-	device_t		 spibus;
-	device_t		 chipc_spi;
 	struct chipc_spi_softc	*sc;
+	device_t		 chipc, spi, spibus;
 
 	BHND_DEBUG_DEV(dev, "initting SPI slicer: %s", device_get_name(dev));
 
-	if (strcmp("mx25l", device_get_name(dev)) != 0)
-		return (EINVAL);
-
+	/* must be SPI-attached flash */
 	spibus = device_get_parent(dev);
 	if (spibus == NULL) {
 		BHND_ERROR_DEV(dev, "no found ChipCommon SPI BUS device");
-		return (EINVAL);
+		return (ENXIO);
 	}
 
-	chipc_spi = device_get_parent(spibus);
-	if (chipc_spi == NULL) {
-		BHND_ERROR_DEV(spibus, "no found ChipCommon SPI device");
-		return (EINVAL);
+	spi = device_get_parent(spibus);
+	if (spi == NULL) {
+		BHND_ERROR_DEV(dev, "no found ChipCommon SPI device");
+		return (ENXIO);
 	}
 
-	sc = device_get_softc(chipc_spi);
+	chipc = device_get_parent(spi);
+	if (device_get_devclass(chipc) != devclass_find("bhnd_chipc")) {
+		BHND_ERROR_DEV(dev, "no found ChipCommon device");
+		return (ENXIO);
+	}
 
-	return (chipc_slicer_walk(dev, sc->sc_res, slices, nslices));
+	sc = device_get_softc(spi);
+	return (chipc_slicer_walk(dev, sc->sc_flash_res, slices, nslices));
 }
 
 /*
  * Main processing part
  */
 static int
-chipc_slicer_walk(device_t dev, struct resource* res,
-		struct flash_slice *slices, int *nslices)
+chipc_slicer_walk(device_t dev, struct resource *res,
+    struct flash_slice *slices, int *nslices)
 {
 	uint32_t	 fw_len;
 	uint32_t	 fs_ofs;

Modified: head/sys/dev/bhnd/cores/chipc/chipc_slicer.h
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc_slicer.h	Sat Jun 25 02:09:49 2016	(r302188)
+++ head/sys/dev/bhnd/cores/chipc/chipc_slicer.h	Sat Jun 25 04:33:00 2016	(r302189)
@@ -34,10 +34,13 @@
 
 #include <sys/slicer.h>
 
+#include "chipcvar.h"
+
 #define	TRX_MAGIC 	0x30524448
 #define	CFE_MAGIC 	0x43464531
 #define	NVRAM_MAGIC	0x48534C46
 
+void		chipc_register_slicer(chipc_flash flash_type);
 int		chipc_slicer_spi(device_t dev, struct flash_slice *slices,
 		    int *nslices);
 int		chipc_slicer_cfi(device_t dev, struct flash_slice *slices,

Modified: head/sys/dev/bhnd/cores/chipc/chipc_spi.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc_spi.c	Sat Jun 25 02:09:49 2016	(r302188)
+++ head/sys/dev/bhnd/cores/chipc/chipc_spi.c	Sat Jun 25 04:33:00 2016	(r302189)
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2016 Michael Zhilin <mizhka@gmail.com>
+ * Copyright (c) 2016 Landon Fuller <landonf@FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -41,135 +42,134 @@ __FBSDID("$FreeBSD$");
 #include <machine/bus.h>
 
 #include <dev/bhnd/bhndvar.h>
-/*
- * SPI BUS interface
- */
+
 #include <dev/spibus/spi.h>
 
+#include "bhnd_chipc_if.h"
+
 #include "spibus_if.h"
 
 #include "chipcreg.h"
 #include "chipcvar.h"
-#include "chipc_spi.h"
-#include "bhnd_chipc_if.h"
-
-/*
- * Flash slicer
- */
 #include "chipc_slicer.h"
 
-/*
- * **************************** PROTOTYPES ****************************
- */
+#include "chipc_spi.h"
 
-static void	chipc_spi_identify(driver_t *driver, device_t parent);
 static int	chipc_spi_probe(device_t dev);
 static int	chipc_spi_attach(device_t dev);
+static int	chipc_spi_detach(device_t dev);
 static int	chipc_spi_transfer(device_t dev, device_t child,
 		    struct spi_command *cmd);
 static int	chipc_spi_txrx(struct chipc_spi_softc *sc, uint8_t in,
 		    uint8_t* out);
 static int	chipc_spi_wait(struct chipc_spi_softc *sc);
 
-/*
- * **************************** IMPLEMENTATION ************************
- */
+static int
+chipc_spi_probe(device_t dev)
+{
+	device_set_desc(dev, "Broadcom ChipCommon SPI");
+	return (BUS_PROBE_NOWILDCARD);
+}
 
-static void
-chipc_spi_identify(driver_t *driver, device_t parent)
+static int
+chipc_spi_attach(device_t dev)
 {
-	struct chipc_caps	*caps;
-	device_t	 	 spidev;
-	device_t	 	 spibus;
-	device_t 		 flash;
-	char*		 	 flash_name;
-	int		 	 err;
-
-	flash_name = NULL;
-
-	if (device_find_child(parent, "spi", -1) != NULL)
-		return;
-
-	caps = BHND_CHIPC_GET_CAPS(parent);
-	if (caps == NULL) {
-		BHND_ERROR_DEV(parent, "can't retrieve ChipCommon capabilities");
-		return;
-	}
+	struct chipc_spi_softc	*sc;
+	struct chipc_caps	*ccaps;
+	device_t		 flash_dev;
+	device_t		 spibus;
+	const char		*flash_name;
+	int			 error;
 
-	switch (caps->flash_type) {
-	case CHIPC_SFLASH_AT:
-		flash_name = "at45d";
-		break;
-	case CHIPC_SFLASH_ST:
-		flash_name = "mx25l";
-		break;
-	default:
-		return;
-	}
+	sc = device_get_softc(dev);
 
-	spidev = BUS_ADD_CHILD(parent, 0, "spi", -1);
-	if (spidev == NULL) {
-		BHND_ERROR_DEV(parent, "can't add chipc_spi to ChipCommon");
-		return;
+	/* Allocate SPI controller registers */
+	sc->sc_rid = 1;
+	sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid,
+	    RF_ACTIVE);
+	if (sc->sc_res == NULL) {
+		device_printf(dev, "failed to allocate device registers\n");
+		return (ENXIO);
 	}
 
-	err = device_probe_and_attach(spidev);
-	if (err) {
-		BHND_ERROR_DEV(spidev, "failed attach chipc_spi: %d", err);
-		return;
+	/* Allocate flash shadow region */
+	sc->sc_flash_rid = 0;
+	sc->sc_flash_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+	    &sc->sc_flash_rid, RF_ACTIVE);
+	if (sc->sc_flash_res == NULL) {
+		device_printf(dev, "failed to allocate flash region\n");
+		error = ENXIO;
+		goto failed;
 	}
 
-	spibus = device_find_child(spidev, "spibus", -1);
-	if (spibus == NULL) {
-		BHND_ERROR_DEV(spidev, "can't find spibus under chipc_spi");
-		return;
+	/* 
+	 * Add flash device
+	 * 
+	 * XXX: This should be replaced with a DEVICE_IDENTIFY implementation
+	 * in chipc-specific subclasses of the mx25l and at45d drivers.
+	 */
+	if ((spibus = device_add_child(dev, "spibus", -1)) == NULL) {
+		device_printf(dev, "failed to add spibus\n");
+		error = ENXIO;
+		goto failed;
 	}
 
-	flash = BUS_ADD_CHILD(spibus, 0, flash_name, -1);
-	if (flash == NULL) {
-		BHND_ERROR_DEV(spibus, "can't add %s to spibus", flash_name);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201606250433.u5P4X1G8050443>