Index: head/sys/dev/bhnd/bhnd.h =================================================================== --- head/sys/dev/bhnd/bhnd.h +++ head/sys/dev/bhnd/bhnd.h @@ -356,6 +356,8 @@ 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); Index: head/sys/dev/bhnd/bhnd_bus_if.m =================================================================== --- head/sys/dev/bhnd/bhnd_bus_if.m +++ head/sys/dev/bhnd/bhnd_bus_if.m @@ -55,12 +55,6 @@ 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 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: head/sys/dev/bhnd/bhnd_subr.c =================================================================== --- head/sys/dev/bhnd/bhnd_subr.c +++ head/sys/dev/bhnd/bhnd_subr.c @@ -1158,3 +1158,22 @@ 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); +} Index: head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m =================================================================== --- head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m +++ head/sys/dev/bhnd/cores/chipc/bhnd_chipc_if.m @@ -39,6 +39,29 @@ 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 struct chipc_caps * get_caps { device_t dev; -} +} DEFAULT bhnd_chipc_generic_get_caps; /** * Enable hardware access to the SPROM. Index: head/sys/dev/bhnd/cores/chipc/chipc.c =================================================================== --- head/sys/dev/bhnd/cores/chipc/chipc.c +++ head/sys/dev/bhnd/cores/chipc/chipc.c @@ -110,12 +110,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}, @@ -480,12 +481,30 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ 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 @@ /* 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_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 @@ 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 }; Index: head/sys/dev/bhnd/cores/chipc/chipcreg.h =================================================================== --- head/sys/dev/bhnd/cores/chipc/chipcreg.h +++ head/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 */