Date: Tue, 22 Feb 2005 23:08:25 GMT From: John-Mark Gurney <jmg@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 71611 for review Message-ID: <200502222308.j1MN8Po7088356@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=71611 Change 71611 by jmg@jmg_carbon on 2005/02/22 23:07:45 make ahb and apb busses to hang devices off... also use hints to attach devices in their proper location, and specify the resources to use... this should remove the need for the uart change that I put in, so I guess I can remove it... I think epclk is not allocating resources properly, but that can be fixed easily... Affected files ... .. //depot/projects/arm/src/sys/arm/ep93xx/ep93xx.c#6 edit .. //depot/projects/arm/src/sys/arm/ep93xx/ep93xx.h#1 add .. //depot/projects/arm/src/sys/arm/ep93xx/ep93xx_intr.c#1 add .. //depot/projects/arm/src/sys/arm/ep93xx/epclk.c#2 edit .. //depot/projects/arm/src/sys/arm/ep93xx/files.ep93xx#2 edit .. //depot/projects/arm/src/sys/arm/ep93xx/hints.ep93xx#1 add .. //depot/projects/arm/src/sys/arm/ep93xx/std.ep93xx#2 edit .. //depot/projects/arm/src/sys/arm/ep93xx/uart_bus_ep93xx.c#3 edit Differences ... ==== //depot/projects/arm/src/sys/arm/ep93xx/ep93xx.c#6 (text+ko) ==== @@ -66,98 +66,136 @@ #include <arm/ep93xx/ep93xxreg.h> #include <arm/ep93xx/ep93xxvar.h> +#include <arm/ep93xx/ep93xx.h> #include <arm/ep93xx/tsarmreg.h> /* XXX */ -struct eparm_softc { +MALLOC_DEFINE(M_AHPBDEV, "AHB & APB Device", ""); + +struct ahpb_device { + struct resource_list ad_resources; +}; + +struct ahb_softc { struct rman sc_intr_rman; struct rman sc_mem_rman; }; -/* Software copy of the IRQs we have enabled. */ -__volatile u_int32_t vic1_intr_enabled; -__volatile u_int32_t vic2_intr_enabled; +struct apb_softc { + struct rman sc_mem_rman; +}; + +static device_t +ahpb_add_child(device_t dev, const char *name, int unit) +{ + device_t child; + struct ahpb_device *adev; + int start, count; + + child = device_add_child(dev, name, unit); + if (child == NULL) + return (child); + + adev = malloc(sizeof(struct ahpb_device), M_AHPBDEV, M_NOWAIT | M_ZERO); + if (adev == NULL) + return (NULL); + + resource_list_init(&adev->ad_resources); + + device_set_ivars(child, adev); + + start = 0; + count = 0; + resource_int_value(name, unit, "port", &start); + resource_int_value(name, unit, "portsize", &count); + if (start > 0 || count > 0) + bus_set_resource(child, SYS_RES_MEMORY, -1, start, count); -#define VIC1REG(reg) *((volatile u_int32_t*) (EP93XX_AHB_VBASE + \ - EP93XX_AHB_VIC1 + (reg))) -#define VIC2REG(reg) *((volatile u_int32_t*) (EP93XX_AHB_VBASE + \ - EP93XX_AHB_VIC2 + (reg))) + if (resource_int_value(name, unit, "irq", &start) == 0 && start > 0) + bus_set_resource(child, SYS_RES_IRQ, -1, start, 1); -void -arm_unmask_irq(int irq) -{ - KASSERT(irq < VIC_NIRQ * 2, ("irq %d is greater than max", irq)); + if (resource_int_value(name, unit, "ppalloc", &start) == 0 && start > 0) + bus_set_resource(child, SYS_RES_DRQ, -1, start, 1); - if (irq < VIC_NIRQ) { - vic1_intr_enabled |= (1U << irq); - VIC1REG(EP93XX_VIC_IntEnable) = (1U << irq); - } else { - vic2_intr_enabled |= (1U << (irq - VIC_NIRQ)); - VIC2REG(EP93XX_VIC_IntEnable) = - (1U << (irq - VIC_NIRQ)); - } + return (child); } -void -arm_mask_irq(int irq) +static void +ahpb_add_hint_devs(device_t bus) { - KASSERT(irq < VIC_NIRQ * 2, ("irq %d is greater than max", irq)); + char buf[16]; + const char *dname; + int dunit; + int i; - if (irq < VIC_NIRQ) { - vic1_intr_enabled &= ~(1U << irq); - VIC1REG(EP93XX_VIC_IntEnClear) = (1U << irq); - } else { - vic2_intr_enabled &= ~(1U << (irq - VIC_NIRQ)); - VIC2REG(EP93XX_VIC_IntEnClear) = - (1U << (irq - VIC_NIRQ)); + /* + * Add all devices configured to be attached to parent. + */ + snprintf(buf, sizeof(buf), "%s", device_get_name(bus)); + i = 0; + while ((resource_find_match(&i, &dname, &dunit, "at", buf)) == 0) { + if (bootverbose) + printf("adding %s%d on %s\n", dname, dunit, buf); + ahpb_add_child(bus, dname, dunit); } + + } -int -arm_get_next_irq() +static struct resource_list * +ahpb_get_resource_list(device_t dev, device_t child) { - int reg; + struct ahpb_device *adev; + struct resource_list *rl; - if ((reg = VIC1REG(EP93XX_VIC_IRQStatus) & vic1_intr_enabled)) { - return ffs(reg) - 1; - } else if ((reg = VIC2REG(EP93XX_VIC_IRQStatus) & vic2_intr_enabled)) { - return ffs(reg) - 1 + 32; - } + adev = (struct ahpb_device *)device_get_ivars(child); + rl = &adev->ad_resources; - return -1; + return (rl); } -static void -ep93xx_intr_init(void) +static int +ahpb_set_resource(device_t dev, device_t child, int type, int rid, + u_long start, u_long count) { + struct ahpb_device *adev; + struct resource_list *rl; + + adev = (struct ahpb_device *)device_get_ivars(child); + rl = &adev->ad_resources; - vic1_intr_enabled = 0; - vic2_intr_enabled = 0; + if (type != SYS_RES_MEMORY && type != SYS_RES_IRQ && + type != SYS_RES_DRQ) + return (EINVAL); + if (rid < -1) + return (EINVAL); - /* All interrupts should use IRQ not FIQ */ - VIC1REG(EP93XX_VIC_IntSelect) = 0; - VIC2REG(EP93XX_VIC_IntSelect) = 0; + if (rid == -1) + resource_list_add_next(rl, type, start, start + count - 1, + count); + else + resource_list_add(rl, type, rid, start, start + count - 1, + count); - /* Enable IRQs (don't yet use FIQs). */ - enable_interrupts(I32_bit); + return 0; } -int ep93xx_probe(device_t); -void ep93xx_identify(driver_t *, device_t); -int ep93xx_attach(device_t); +int ahb_probe(device_t); +void ahb_identify(driver_t *, device_t); +int ahb_attach(device_t); int -ep93xx_probe(device_t dev) +ahb_probe(device_t dev) { - device_set_desc(dev, "Cirrus Logic EP93xx CPU"); + device_set_desc(dev, "Cirrus Logic EP93xx AHB Bus"); return (0); } void -ep93xx_identify(driver_t *driver, device_t parent) +ahb_identify(driver_t *driver, device_t parent) { - BUS_ADD_CHILD(parent, 0, "eparm", 0); + BUS_ADD_CHILD(parent, 0, "ahb", 0); } struct arm32_dma_range * @@ -181,10 +219,9 @@ * of EP93XX_APB_VBASE + EP93XX_APB_UART1. */ int -ep93xx_attach(device_t dev) +ahb_attach(device_t dev) { - struct eparm_softc *sc; - device_t chld; + struct ahb_softc *sc; sc = device_get_softc(dev); sc->sc_intr_rman.rm_type = RMAN_ARRAY; @@ -194,22 +231,13 @@ if (rman_init(&sc->sc_intr_rman) != 0 || rman_init(&sc->sc_mem_rman) != 0 || rman_manage_region(&sc->sc_intr_rman, 0, NIRQ - 1) != 0 || - rman_manage_region(&sc->sc_mem_rman, EP93XX_AHB_VBASE, - EP93XX_AHB_VBASE + EP93XX_AHB_SIZE - 1) != 0 || - rman_manage_region(&sc->sc_mem_rman, EP93XX_APB_VBASE, - EP93XX_APB_VBASE + EP93XX_APB_SIZE - 1) != 0) - panic("ep93xx_attach(): failed to set up rmans"); + rman_manage_region(&sc->sc_mem_rman, 0, EP93XX_AHB_SIZE - 1) != 0) + panic("ahb_attach(): failed to set up rmans"); ep93xx_intr_init(); - /* XXX - hardcode the device id's? */ - /* XXX - convert to device.hints */ - chld = device_add_child(dev, "uart", -1); - device_set_ivars(chld, (void *)1); - chld = device_add_child(dev, "uart", -1); - device_set_ivars(chld, (void *)2); - - device_add_child(dev, "epclk", -1); + /* add all the deivces per hints */ + ahpb_add_hint_devs(dev); /* kick these off */ bus_generic_probe(dev); @@ -246,12 +274,14 @@ } static struct resource * -ep93xx_alloc_resource(device_t bus, device_t child, int type, int *rid, +ahb_alloc_resource(device_t bus, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { - struct eparm_softc *sc = device_get_softc(bus); + struct ahb_softc *sc = device_get_softc(bus); struct resource *rv; struct rman *rm; + u_long rstart, rcount; + int error; int needactivate = flags & RF_ACTIVE; flags &= ~RF_ACTIVE; @@ -267,18 +297,18 @@ return (NULL); } - /* if non-zero rid, that means it's a specific address */ - if (*rid != 0) - rv = rman_reserve_resource(rm, *rid, *rid + count - 1, count, - flags, child); - else - rv = rman_reserve_resource(rm, start, end, count, flags, child); + error = BUS_GET_RESOURCE(bus, child, type, *rid, &rstart, &rcount); + if (error) + return (NULL); + + rv = rman_reserve_resource(rm, rstart, rstart + rcount - 1, rcount, + flags, child); if (rv == NULL) return (NULL); if (type == SYS_RES_MEMORY) { rman_set_bustag(rv, &ep93xx_bs_tag); - rman_set_bushandle(rv, rman_get_start(rv)); + rman_set_bushandle(rv, EP93XX_AHB_VBASE + rman_get_start(rv)); } if (needactivate) { @@ -292,7 +322,7 @@ } static int -ep93xx_activate_resource(device_t dev, device_t child, int type, int rid, +ahb_activate_resource(device_t dev, device_t child, int type, int rid, struct resource *r) { /* XXX - enable interrupt? */ @@ -301,7 +331,7 @@ } static int -ep93xx_deactivate_resource(device_t dev, device_t child, int type, int rid, +ahb_deactivate_resource(device_t dev, device_t child, int type, int rid, struct resource *r) { /* XXX - disable interrupt? */ @@ -310,7 +340,7 @@ } static int -ep93xx_release_resource(device_t dev, device_t child, int type, int rid, +ahb_release_resource(device_t dev, device_t child, int type, int rid, struct resource *r) { /* not much to do since we use static mappings */ @@ -318,9 +348,8 @@ } static int -ep93xx_setup_intr(device_t dev, device_t child, - struct resource *ires, int flags, driver_intr_t *intr, void *arg, - void **cookiep) +ahb_setup_intr(device_t dev, device_t child, struct resource *ires, + int flags, driver_intr_t *intr, void *arg, void **cookiep) { BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, intr, arg, @@ -329,23 +358,171 @@ return (0); } -static device_method_t ep93xx_methods[] = { - DEVMETHOD(device_probe, ep93xx_probe), - DEVMETHOD(device_attach, ep93xx_attach), - DEVMETHOD(device_identify, ep93xx_identify), - DEVMETHOD(bus_alloc_resource, ep93xx_alloc_resource), - DEVMETHOD(bus_activate_resource, ep93xx_activate_resource), - DEVMETHOD(bus_deactivate_resource, ep93xx_deactivate_resource), - DEVMETHOD(bus_release_resource, ep93xx_release_resource), - DEVMETHOD(bus_setup_intr, ep93xx_setup_intr), + +static int ahb_teardown_intr(device_t dev, device_t child, + struct resource *ires, void *cookie) +{ + + BUS_TEARDOWN_INTR(device_get_parent(dev), child, ires, cookie); + arm_mask_irq(ires->r_start); + + return (0); +} + +static device_method_t ahb_methods[] = { + DEVMETHOD(device_probe, ahb_probe), + DEVMETHOD(device_attach, ahb_attach), + DEVMETHOD(device_identify, ahb_identify), + + DEVMETHOD(bus_get_resource_list, ahpb_get_resource_list), + DEVMETHOD(bus_alloc_resource, ahb_alloc_resource), + DEVMETHOD(bus_release_resource, ahb_release_resource), + DEVMETHOD(bus_set_resource, ahpb_set_resource), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), + DEVMETHOD(bus_activate_resource, ahb_activate_resource), + DEVMETHOD(bus_deactivate_resource, ahb_deactivate_resource), + + DEVMETHOD(bus_setup_intr, ahb_setup_intr), + DEVMETHOD(bus_teardown_intr, ahb_teardown_intr), + {0, 0}, +}; + +static driver_t ahb_driver = { + "ahb", + ahb_methods, + sizeof(struct ahb_softc), +}; +static devclass_t ahb_devclass; + +DRIVER_MODULE(ahb, nexus, ahb_driver, ahb_devclass, 0, 0); + +static int +apb_probe(device_t dev) +{ + + return 0; +} + +static int +apb_attach(device_t dev) +{ + struct apb_softc *sc; + + sc = device_get_softc(dev); + sc->sc_mem_rman.rm_type = RMAN_ARRAY; + sc->sc_mem_rman.rm_descr = "Register Memory"; + if (rman_init(&sc->sc_mem_rman) != 0 || + rman_manage_region(&sc->sc_mem_rman, 0, EP93XX_APB_SIZE - 1) != 0) + panic("apb_attach(): failed to set up rmans"); + + /* add all the deivces per hints */ + ahpb_add_hint_devs(dev); + + /* kick these off */ + bus_generic_probe(dev); + bus_generic_attach(dev); + + return (0); +} + +static struct resource * +apb_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + struct apb_softc *sc = device_get_softc(bus); + struct resource *rv; + struct rman *rm; + u_long rstart, rcount; + int error; + int needactivate = flags & RF_ACTIVE; + + if (type == SYS_RES_IRQ) { + return BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, + rid, start, end, count, flags); + } + + flags &= ~RF_ACTIVE; + + if (type != SYS_RES_MEMORY) + return NULL; + + rm = &sc->sc_mem_rman; + + error = BUS_GET_RESOURCE(bus, child, type, *rid, &rstart, &rcount); + if (error) + return (NULL); + + rv = rman_reserve_resource(rm, rstart, rstart + rcount - 1, rcount, + flags, child); + + if (rv == NULL) + return (NULL); + if (type == SYS_RES_MEMORY) { + /* XXX - should base this off of AHB's tag and handle */ + rman_set_bustag(rv, &ep93xx_bs_tag); + rman_set_bushandle(rv, EP93XX_APB_VBASE + rman_get_start(rv)); + } + + if (needactivate) { + if (bus_activate_resource(child, type, *rid, rv) != 0) { + rman_release_resource(rv); + return (NULL); + } + } + + return (rv); +} + +static int +apb_activate_resource(device_t dev, device_t child, int type, int rid, + struct resource *r) +{ + /* XXX - enable interrupt? */ + /* not much to do since we use static mappings */ + return rman_activate_resource(r); +} + +static int +apb_deactivate_resource(device_t dev, device_t child, int type, int rid, + struct resource *r) +{ + /* XXX - disable interrupt? */ + /* not much to do since we use static mappings */ + return rman_deactivate_resource(r); +} + +static int +apb_release_resource(device_t dev, device_t child, int type, int rid, + struct resource *r) +{ + /* not much to do since we use static mappings */ + return rman_release_resource(r); +} + +static device_method_t apb_methods[] = { + DEVMETHOD(device_probe, apb_probe), + DEVMETHOD(device_attach, apb_attach), + + DEVMETHOD(bus_get_resource_list, ahpb_get_resource_list), + DEVMETHOD(bus_alloc_resource, apb_alloc_resource), + DEVMETHOD(bus_release_resource, apb_release_resource), + DEVMETHOD(bus_set_resource, ahpb_set_resource), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), + DEVMETHOD(bus_activate_resource, apb_activate_resource), + DEVMETHOD(bus_deactivate_resource, apb_deactivate_resource), + + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), {0, 0}, }; -static driver_t ep93xx_driver = { - "eparm", - ep93xx_methods, - sizeof(struct eparm_softc), +static driver_t apb_driver = { + "apb", + apb_methods, + sizeof(struct apb_softc), }; -static devclass_t ep93xx_devclass; +static devclass_t apb_devclass; -DRIVER_MODULE(eparm, nexus, ep93xx_driver, ep93xx_devclass, 0, 0); +DRIVER_MODULE(apb, ahb, apb_driver, apb_devclass, 0, 0); ==== //depot/projects/arm/src/sys/arm/ep93xx/epclk.c#2 (text+ko) ==== @@ -150,7 +150,7 @@ }; static devclass_t epclk_devclass; -DRIVER_MODULE(epclk, eparm, epclk_driver, epclk_devclass, 0, 0); +DRIVER_MODULE(epclk, apb, epclk_driver, epclk_devclass, 0, 0); /* * epclk_intr: * @@ -180,6 +180,7 @@ stathz = profhz = 0; if (hz != 64) panic("HZ must be 64!"); + if (epclk == NULL) panic("epclk hasn't been attached yet!"); /* clear 64Hz interrupt status */ bus_space_write_4(epclk->sc_iot, epclk->sc_teoi_ioh, 0, 1); ==== //depot/projects/arm/src/sys/arm/ep93xx/files.ep93xx#2 (text+ko) ==== @@ -2,6 +2,7 @@ arm/arm/cpufunc_asm_arm9.S standard arm/arm/irq_dispatch.S standard arm/ep93xx/ep93xx.c standard +arm/ep93xx/ep93xx_intr.c standard arm/ep93xx/ep93xx_space.c standard arm/ep93xx/epclk.c standard arm/ep93xx/uart_bus_ep93xx.c optional uart ==== //depot/projects/arm/src/sys/arm/ep93xx/std.ep93xx#2 (text+ko) ==== @@ -1,3 +1,5 @@ #$FreeBSD$ files "../ep93xx/files.ep93xx" cpu CPU_ARM9 + +hints "../ep93xx/hints.ep93xx" ==== //depot/projects/arm/src/sys/arm/ep93xx/uart_bus_ep93xx.c#3 (text+ko) ==== @@ -35,8 +35,6 @@ #include <sys/rman.h> #include <machine/resource.h> -#include <dev/pci/pcivar.h> - #include <dev/uart/uart.h> #include <dev/uart/uart_bus.h> #include <dev/uart/uart_cpu.h> @@ -67,17 +65,23 @@ uart_ep93xx_probe(device_t dev) { struct uart_softc *sc; - int i; + int error; + int unum; + + error = resource_int_value(device_get_name(dev), device_get_unit(dev), + "chan", &unum); + if (error) + return (error); - if ((i = (int)device_get_ivars(dev)) < 1 || i > 2) + if (unum < 1 || unum > 2) return ENXIO; sc = device_get_softc(dev); sc->sc_class = &uart_epuart_class; - sc->sc_bas = EPUARTBAS(i); - sc->sc_irid = i == 1 ? 52 : 54; + sc->sc_bas = EPUARTBAS(unum); /* do proper resource alloc */ + sc->sc_irid = unum == 1 ? 52 : 54; return (uart_bus_probe(dev, sc->sc_bas.regshft, sc->sc_bas.rclk, - sc->sc_bas.bsh, sc->sc_bas.chan, sc->sc_irid)); + 0, sc->sc_bas.chan, 0)); } -DRIVER_MODULE(uart, eparm, uart_ep93xx_driver, uart_devclass, 0, 0); +DRIVER_MODULE(uart, apb, uart_ep93xx_driver, uart_devclass, 0, 0);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200502222308.j1MN8Po7088356>