Date: Wed, 14 Dec 2005 18:24:15 GMT From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 88185 for review Message-ID: <200512141824.jBEIOFc6082501@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=88185 Change 88185 by imp@imp_Speedy on 2005/12/14 18:23:48 attempt to make the atmelarm bus do real resource allocation. Affected files ... .. //depot/projects/arm/src/sys/arm/at91/at91rm92.c#6 edit .. //depot/projects/arm/src/sys/arm/at91/at91rm92var.h#3 edit Differences ... ==== //depot/projects/arm/src/sys/arm/at91/at91rm92.c#6 (text+ko) ==== @@ -29,6 +29,7 @@ #include <sys/systm.h> #include <sys/bus.h> #include <sys/kernel.h> +#include <sys/malloc.h> #include <sys/module.h> #include <vm/vm.h> @@ -160,7 +161,7 @@ static int at91rm92_probe(device_t dev) { - device_set_desc(dev, "AT91RM9200"); + device_set_desc(dev, "AT91 CPU"); return (0); } @@ -186,6 +187,30 @@ extern void irq_entry(void); +static void +at91rm92_add_child(device_t dev, int prio, const char *name, int unit, + bus_addr_t addr, bus_size_t size, int irq) +{ + device_t kid; + struct at91rm92_ivar *ivar; + + kid = device_add_child_ordered(dev, prio, name, unit); + if (kid == NULL) + return; + ivar = malloc(sizeof(*ivar), M_DEVBUF, M_WAITOK | M_ZERO); + if (ivar == NULL) { + device_delete_child(dev, kid); + return; + } + device_set_ivars(kid, ivar); + resource_list_init(&ivar->resources); + if (irq != -1) + bus_set_resource(kid, SYS_RES_IRQ, 0, irq, 1); + if (addr != 0) + bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size); +} + + static int at91rm92_attach(device_t dev) { @@ -196,14 +221,20 @@ sc->sc_st = &at91rm92_bs_tag; sc->sc_sh = AT91RM92_BASE; sc->dev = dev; - sc->sc_irq_rman.rm_type = RMAN_ARRAY; - sc->sc_irq_rman.rm_descr = "AT91RM92 IRQs"; if (bus_space_subregion(sc->sc_st, sc->sc_sh, AT91RM92_SYS_BASE, AT91RM92_SYS_SIZE, &sc->sc_sys_sh) != 0) panic("Enable to map IRQ registers"); + sc->sc_irq_rman.rm_type = RMAN_ARRAY; + sc->sc_irq_rman.rm_descr = "AT91RM92 IRQs"; + sc->sc_mem_rman.rm_type = RMAN_ARRAY; + sc->sc_mem_rman.rm_descr = "AT91RM92 Memory"; if (rman_init(&sc->sc_irq_rman) != 0 || rman_manage_region(&sc->sc_irq_rman, 1, 31) != 0) panic("at91rm92_attach: failed to set up IRQ rman"); + if (rman_init(&sc->sc_mem_rman) != 0 || + rman_manage_region(&sc->sc_mem_rman, 0xfff00000ul, + 0xfffffffful) != 0) + panic("at91rm92_attach: failed to set up memory rman"); for (i = 0; i < 32; i++) { bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_SVR + @@ -223,7 +254,18 @@ /* Disable and clear all interrupts. */ bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_IDCR, 0xffffffff); bus_space_write_4(sc->sc_st, sc->sc_sys_sh, IC_ICCR, 0xffffffff); - device_add_child(dev, "at91rm92_timer", 0); + + at91rm92_add_child(dev, 0, "at91rm92_timer", 0, 0, 0, 1); + at91rm92_add_child(dev, 10, "uart", 0, AT91RM92_BASE + + AT91RM92_SYS_BASE + DBGU, DBGU_SIZE, 1); // DBGU + at91rm92_add_child(dev, 10, "uart", 1, AT91RM92_BASE + + AT91RM92_USART0_BASE, AT91RM92_USART_SIZE, 6); // USART0 + at91rm92_add_child(dev, 10, "uart", 2, AT91RM92_BASE + + AT91RM92_USART1_BASE, AT91RM92_USART_SIZE, 7); // USART1 + at91rm92_add_child(dev, 10, "uart", 3, AT91RM92_BASE + + AT91RM92_USART2_BASE, AT91RM92_USART_SIZE, 8); // USART2 + at91rm92_add_child(dev, 10, "uart", 4, AT91RM92_BASE + + AT91RM92_USART3_BASE, AT91RM92_USART_SIZE, 9); // USART3 bus_generic_probe(dev); bus_generic_attach(dev); enable_interrupts(I32_bit | F32_bit); @@ -251,11 +293,67 @@ u_long start, u_long end, u_long count, u_int flags) { struct at91rm92_softc *sc = device_get_softc(dev); + struct resource_list_entry *rle; + struct at91rm92_ivar *ivar = device_get_ivars(child); + struct resource_list *rl = &ivar->resources; + + if (device_get_parent(child) != dev) + return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, + type, rid, start, end, count, flags)); - if (type == SYS_RES_IRQ) - return (rman_reserve_resource(&sc->sc_irq_rman, - start, end, count, flags, child)); - return (NULL); + rle = resource_list_find(rl, type, *rid); + if (rle == NULL) + return (NULL); + if (rle->res) + panic("Resource rid %d type %d already in use", *rid, type); + if (start == 0UL && end == ~0UL) { + start = rle->start; + count = ulmax(count, rle->count); + end = ulmax(rle->end, start + count - 1); + } + switch (type) + { + case SYS_RES_IRQ: + rle->res = rman_reserve_resource(&sc->sc_irq_rman, + start, end, count, flags, child); + break; + case SYS_RES_MEMORY: + rle->res = rman_reserve_resource(&sc->sc_mem_rman, + start, end, count, flags, child); + } + if (rle->res) { + rle->start = rman_get_start(rle->res); + rle->end = rman_get_end(rle->res); + rle->count = count; + } + return (rle->res); +} + +static struct resource_list * +at91rm92_get_resource_list(device_t dev, device_t child) +{ + struct at91rm92_ivar *ivar; + + ivar = device_get_ivars(child); + return (&(ivar->resources)); +} + +static int +at91rm92_release_resource(device_t dev, device_t child, int type, + int rid, struct resource *r) +{ + struct resource_list *rl; + struct resource_list_entry *rle; + + rl = at91rm92_get_resource_list(dev, child); + if (rl == NULL) + return (EINVAL); + rle = resource_list_find(rl, type, rid); + if (rle == NULL) + return (EINVAL); + rman_release_resource(r); + rle->res = NULL; + return (0); } static int @@ -287,6 +385,7 @@ at91rm92_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { +#if 0 u_long p; int error; @@ -296,11 +395,34 @@ if (error) return (error); rman_set_bushandle(r, p); - } +#endif return (rman_activate_resource(r)); } +static int +at91rm92_print_child(device_t dev, device_t child) +{ + struct at91rm92_ivar *ivars; + struct resource_list *rl; + int retval = 0; + + ivars = device_get_ivars(child); + rl = &ivars->resources; + + retval += bus_print_child_header(dev, child); + + retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx"); + retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx"); + retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld"); + if (device_get_flags(dev)) + retval += printf(" flags %#x", device_get_flags(dev)); + + retval += bus_print_child_footer(dev, child); + + return (retval); +} + void arm_mask_irq(uintptr_t nb) { @@ -342,12 +464,17 @@ DEVMETHOD(device_probe, at91rm92_probe), DEVMETHOD(device_attach, at91rm92_attach), DEVMETHOD(device_identify, at91rm92_identify), + DEVMETHOD(bus_alloc_resource, at91rm92_alloc_resource), DEVMETHOD(bus_setup_intr, at91rm92_setup_intr), DEVMETHOD(bus_teardown_intr, at91rm92_teardown_intr), - DEVMETHOD(bus_release_resource, bus_generic_release_resource), DEVMETHOD(bus_activate_resource, at91rm92_activate_resource), DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_get_resource_list,at91rm92_get_resource_list), + DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + DEVMETHOD(bus_release_resource, at91rm92_release_resource), + DEVMETHOD(bus_print_child, at91rm92_print_child), {0, 0}, }; ==== //depot/projects/arm/src/sys/arm/at91/at91rm92var.h#3 (text+ko) ==== @@ -35,6 +35,12 @@ bus_space_handle_t sc_sh; bus_space_handle_t sc_sys_sh; struct rman sc_irq_rman; + struct rman sc_mem_rman; +}; + +struct at91rm92_ivar { + struct resource_list resources; }; + #endif /* _AT91RM92VAR_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200512141824.jBEIOFc6082501>