Index: sys/dev/bhnd/bhnd_bus_if.m =================================================================== --- sys/dev/bhnd/bhnd_bus_if.m +++ sys/dev/bhnd/bhnd_bus_if.m @@ -56,8 +56,13 @@ } static bhnd_attach_type - bhnd_bus_null_get_attach_type(device_t dev, device_t child) + 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"); } @@ -203,7 +208,7 @@ 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. Index: sys/dev/bhnd/cores/chipc/chipc.c =================================================================== --- sys/dev/bhnd/cores/chipc/chipc.c +++ sys/dev/bhnd/cores/chipc/chipc.c @@ -141,12 +141,13 @@ 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}, @@ -512,11 +513,19 @@ const struct chipc_hint *hint; device_t child; int error; + int dunit; child = device_add_child_ordered(dev, order, name, unit); if (child == NULL) return (NULL); + dunit = device_get_unit(child); + if (dunit < 0) { + device_printf(child, "error: negative device unit: %d\n", dunit); + device_delete_child(dev, child); + return (NULL); + } + dinfo = malloc(sizeof(struct chipc_devinfo), M_BHND, M_NOWAIT); if (dinfo == NULL) { device_delete_child(dev, child); @@ -535,9 +544,14 @@ 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 && dunit != hint->unit) + continue; + switch (hint->type) { case SYS_RES_IRQ: /* Add child resource */ @@ -566,8 +580,9 @@ /* 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 " @@ -577,9 +592,17 @@ 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", @@ -785,8 +808,10 @@ 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); } @@ -852,10 +877,11 @@ 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); @@ -884,6 +910,11 @@ /* 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); } @@ -1278,6 +1309,15 @@ return (bhnd_bus_read_4(sc->core, CHIPC_FLASH_CFG)); } +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), @@ -1320,6 +1360,7 @@ DEVMETHOD(bhnd_chipc_enable_sprom, chipc_enable_sprom_pins), DEVMETHOD(bhnd_chipc_disable_sprom, chipc_disable_sprom_pins), DEVMETHOD(bhnd_chipc_get_flash_cfg, chipc_get_flash_cfg), + DEVMETHOD(bhnd_chipc_get_caps, chipc_get_caps), DEVMETHOD_END }; Index: sys/dev/bhnd/cores/chipc/chipcreg.h =================================================================== --- sys/dev/bhnd/cores/chipc/chipcreg.h +++ sys/dev/bhnd/cores/chipc/chipcreg.h @@ -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 */