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 <[email protected]> (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 <[email protected]>
+ * Copyright (c) 2016 Landon Fuller <[email protected]>
  * 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 ***
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to