svn commit: r301408 - in head/sys/dev/bhnd: . cores/chipc

Landon J. Fuller landonf at FreeBSD.org
Sat Jun 4 19:31:08 UTC 2016


Author: landonf
Date: Sat Jun  4 19:31:06 2016
New Revision: 301408
URL: https://svnweb.freebsd.org/changeset/base/301408

Log:
  Fix several MIPS/BCM-blocking bugs in bhnd(4) chipc
  
  - Correct IRQ lines for UART (to fix IRQ lookup in future)
  - Check device unit in resource assignment during chipc_add_child
  - If chipc hint->size is RM_MAX_END, resource end should be same as window end
  - Clear reference from resource list entry to resource in case of resource release
  - Add CHIPC_GET_CAPS implementation
  - Correct chipc flash constants (to be unshifted)
  - Default implementation of get_attach_type should iterate over device tree
  - Add default implementation for BHND_CHIPC_GET_CAPS usable by chipc grandchildren
  
  Submitted by:	Michael Zhilin <mizhka at gmail.com>
  Approved by:	adrian (mentor)
  Differential Revision:	https://reviews.freebsd.org/D6584

Modified:
  head/sys/dev/bhnd/bhnd.h
  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/chipc.c
  head/sys/dev/bhnd/cores/chipc/chipcreg.h

Modified: head/sys/dev/bhnd/bhnd.h
==============================================================================
--- head/sys/dev/bhnd/bhnd.h	Sat Jun  4 19:00:11 2016	(r301407)
+++ head/sys/dev/bhnd/bhnd.h	Sat Jun  4 19:31:06 2016	(r301408)
@@ -356,6 +356,8 @@ int				 bhnd_bus_generic_activate_resour
 int				 bhnd_bus_generic_deactivate_resource (device_t dev,
 				     device_t child, int type, int rid,
 				     struct bhnd_resource *r);
+bhnd_attach_type		 bhnd_bus_generic_get_attach_type(device_t dev,
+				     device_t child);
 
 
 

Modified: head/sys/dev/bhnd/bhnd_bus_if.m
==============================================================================
--- head/sys/dev/bhnd/bhnd_bus_if.m	Sat Jun  4 19:00:11 2016	(r301407)
+++ head/sys/dev/bhnd/bhnd_bus_if.m	Sat Jun  4 19:31:06 2016	(r301408)
@@ -55,12 +55,6 @@ 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)
@@ -203,7 +197,7 @@ METHOD const struct bhnd_chipid * get_ch
 METHOD bhnd_attach_type get_attach_type {
 	device_t dev;
 	device_t child;
-} DEFAULT bhnd_bus_null_get_attach_type;
+} DEFAULT bhnd_bus_generic_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  4 19:00:11 2016	(r301407)
+++ head/sys/dev/bhnd/bhnd_subr.c	Sat Jun  4 19:31:06 2016	(r301408)
@@ -1158,3 +1158,22 @@ 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  4 19:00:11 2016	(r301407)
+++ head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m	Sat Jun  4 19:31:06 2016	(r301408)
@@ -39,6 +39,29 @@ INTERFACE bhnd_chipc;
 HEADER {
 	/* 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)
+	{
+	
+		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);
+	}
+
 }
 
 /**
@@ -77,7 +100,7 @@ METHOD void write_chipctrl {
  */
 METHOD struct chipc_caps * get_caps {
 	device_t dev;
-}
+} DEFAULT bhnd_chipc_generic_get_caps;
 
 /**
  * Enable hardware access to the SPROM.

Modified: head/sys/dev/bhnd/cores/chipc/chipc.c
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc.c	Sat Jun  4 19:00:11 2016	(r301407)
+++ head/sys/dev/bhnd/cores/chipc/chipc.c	Sat Jun  4 19:31:06 2016	(r301408)
@@ -110,12 +110,13 @@ static const struct chipc_hint {
 	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,	0,			RM_MAX_END },
+	{ "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,	0,			RM_MAX_END },
+	{ "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},
@@ -480,12 +481,30 @@ chipc_add_child(device_t dev, u_int orde
 	struct chipc_devinfo	*dinfo;
 	const struct chipc_hint	*hint;
 	device_t		 child;
+	devclass_t		 child_dc;
 	int			 error;
+	int 			 busrel_unit;
 
 	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);
@@ -504,9 +523,14 @@ chipc_add_child(device_t dev, u_int orde
 		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 */
@@ -535,8 +559,9 @@ chipc_add_child(device_t dev, u_int orde
 
 			/* Verify requested range is mappable */
 			if (hint->base > region_size ||
-			    hint->size > region_size ||
-			    region_size - hint->base < hint->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 "
@@ -546,9 +571,17 @@ chipc_add_child(device_t dev, u_int orde
 				    hint->size);
 			}
 
-			/* Add child resource */
-			error = bus_set_resource(child, hint->type,
-			    hint->rid, region_addr + 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",
@@ -754,8 +787,10 @@ chipc_alloc_resource(device_t dev, devic
 		
 		if (rle->res != NULL) {
 			device_printf(dev,
-			    "resource entry %#x type %d for child %s is busy\n",
-			    *rid, type, device_get_nameunit(child));
+			    "resource entry %#x type %d for child %s is busy "
+			    "[%d]\n",
+			    *rid, type, device_get_nameunit(child),
+			    rman_get_flags(rle->res));
 			
 			return (NULL);
 		}
@@ -821,10 +856,11 @@ static int
 chipc_release_resource(device_t dev, device_t child, int type, int rid,
     struct resource *r)
 {
-	struct chipc_softc	*sc;
-	struct chipc_region	*cr;
-	struct rman		*rm;
-	int			 error;
+	struct chipc_softc		*sc;
+	struct chipc_region		*cr;
+	struct rman			*rm;
+	struct resource_list_entry	*rle;
+	int			 	 error;
 
 	sc = device_get_softc(dev);
 
@@ -853,6 +889,11 @@ chipc_release_resource(device_t dev, dev
 	/* Drop allocation reference */
 	chipc_release_region(sc, cr, RF_ALLOCATED);
 
+	/* Clear reference from the resource list entry if exists */
+	rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child), type, rid);
+	if (rle != NULL)
+		rle->res = NULL;
+
 	return (0);
 }
 
@@ -1238,6 +1279,15 @@ chipc_write_chipctrl(device_t dev, uint3
 	CHIPC_UNLOCK(sc);
 }
 
+static struct chipc_caps *
+chipc_get_caps(device_t dev)
+{
+	struct chipc_softc	*sc;
+
+	sc = device_get_softc(dev);
+	return (&sc->caps);
+}
+
 static device_method_t chipc_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,			chipc_probe),
@@ -1279,6 +1329,7 @@ static device_method_t chipc_methods[] =
 	DEVMETHOD(bhnd_chipc_write_chipctrl,	chipc_write_chipctrl),
 	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_END
 };

Modified: head/sys/dev/bhnd/cores/chipc/chipcreg.h
==============================================================================
--- head/sys/dev/bhnd/cores/chipc/chipcreg.h	Sat Jun  4 19:00:11 2016	(r301407)
+++ head/sys/dev/bhnd/cores/chipc/chipcreg.h	Sat Jun  4 19:31:06 2016	(r301408)
@@ -240,11 +240,11 @@
 #define	  CHIPC_CAP_EXTBUS_PROG		0x2		/* ExtBus: ProgIf only */
 #define	CHIPC_CAP_FLASH_MASK		0x00000700	/* Type of flash */
 #define	CHIPC_CAP_FLASH_SHIFT		8
-#define	  CHIPC_CAP_FLASH_NONE		0x000		/* No flash */
-#define	  CHIPC_CAP_SFLASH_ST		0x100		/* ST serial flash */
-#define	  CHIPC_CAP_SFLASH_AT		0x200		/* Atmel serial flash */
-#define	  CHIPC_CAP_NFLASH		0x300		/* NAND flash */
-#define	  CHIPC_CAP_PFLASH		0x700		/* Parallel flash */
+#define	  CHIPC_CAP_FLASH_NONE		0x0		/* No flash */
+#define	  CHIPC_CAP_SFLASH_ST		0x1		/* ST serial flash */
+#define	  CHIPC_CAP_SFLASH_AT		0x2		/* Atmel serial flash */
+#define	  CHIPC_CAP_NFLASH		0x3		/* NAND flash */
+#define	  CHIPC_CAP_PFLASH		0x7		/* Parallel flash */
 #define	CHIPC_CAP_PLL_MASK		0x00038000	/* Type of PLL */
 #define	CHIPC_CAP_PLL_SHIFT		15
 #define	CHIPC_CAP_PWR_CTL		0x00040000	/* Power control */


More information about the svn-src-head mailing list