The branch main has been updated by andrew:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=b71ef90ec28fdb731733afde495ac74ae59d6196

commit b71ef90ec28fdb731733afde495ac74ae59d6196
Author:     Andrew Turner <[email protected]>
AuthorDate: 2023-03-14 09:27:23 +0000
Commit:     Andrew Turner <[email protected]>
CommitDate: 2023-03-15 11:34:31 +0000

    Keep per-timer interrupt data together
    
    Eliminate a redundant resource array allow possible use by bhyve later.
    
    Reviewed by:    kevans
    Sponsored by:   Arm Ltd
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D37424
---
 sys/arm/arm/generic_timer.c | 118 +++++++++++++++++++++++---------------------
 1 file changed, 63 insertions(+), 55 deletions(-)

diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
index 0b48841c9960..36747441ec88 100644
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -97,9 +97,16 @@ __FBSDID("$FreeBSD$");
 #define        GT_CNTKCTL_PL0VCTEN     (1 << 1) /* PL0 CNTVCT and CNTFRQ 
access */
 #define        GT_CNTKCTL_PL0PCTEN     (1 << 0) /* PL0 CNTPCT and CNTFRQ 
access */
 
+struct arm_tmr_softc;
+
+struct arm_tmr_irq {
+       struct resource *res;
+       void            *ihl;
+       int              rid;
+};
+
 struct arm_tmr_softc {
-       struct resource         *res[GT_IRQ_COUNT];
-       void                    *ihl[GT_IRQ_COUNT];
+       struct arm_tmr_irq      irqs[GT_IRQ_COUNT];
        uint64_t                (*get_cntxct)(bool);
        uint32_t                clkfreq;
        struct eventtimer       et;
@@ -108,16 +115,6 @@ struct arm_tmr_softc {
 
 static struct arm_tmr_softc *arm_tmr_sc = NULL;
 
-#ifdef DEV_ACPI
-static struct resource_spec timer_acpi_spec[] = {
-       { SYS_RES_IRQ,  GT_PHYS_SECURE,         RF_ACTIVE | RF_OPTIONAL },
-       { SYS_RES_IRQ,  GT_PHYS_NONSECURE,      RF_ACTIVE },
-       { SYS_RES_IRQ,  GT_VIRT,                RF_ACTIVE },
-       { SYS_RES_IRQ,  GT_HYP_PHYS,            RF_ACTIVE | RF_OPTIONAL },
-       { -1, 0 }
-};
-#endif
-
 static const struct arm_tmr_irq_defs {
        int idx;
        const char *name;
@@ -402,6 +399,29 @@ arm_tmr_intr(void *arg)
        return (FILTER_HANDLED);
 }
 
+static int
+arm_tmr_attach_irq(device_t dev, struct arm_tmr_softc *sc,
+    const struct arm_tmr_irq_defs *irq_def, int rid, int flags)
+{
+       sc->irqs[irq_def->idx].res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+           &rid, flags);
+       if (sc->irqs[irq_def->idx].res == NULL) {
+               if (bootverbose || (flags & RF_OPTIONAL) == 0) {
+                       device_printf(dev,
+                           "could not allocate irq for %s interrupt '%s'\n",
+                           (flags & RF_OPTIONAL) != 0 ? "optional" :
+                           "required", irq_def->name);
+               }
+
+               if ((flags & RF_OPTIONAL) == 0)
+                       return (ENXIO);
+       } else if (bootverbose) {
+               device_printf(dev, "allocated irq for '%s'\n", irq_def->name);
+       }
+
+       return (0);
+}
+
 #ifdef FDT
 static int
 arm_tmr_fdt_probe(device_t dev)
@@ -479,42 +499,18 @@ arm_tmr_fdt_attach(device_t dev)
                        flags &= ~RF_OPTIONAL;
                }
 
-               sc->res[irq_def->idx] = bus_alloc_resource_any(dev,
-                   SYS_RES_IRQ, &rid, flags);
-
-               if (sc->res[irq_def->idx] == NULL) {
-                       device_printf(dev,
-                           "could not allocate irq for %s interrupt '%s'\n",
-                           (flags & RF_OPTIONAL) != 0 ? "optional" :
-                           "required", irq_def->name);
-
-                       if ((flags & RF_OPTIONAL) == 0) {
-                               error = ENXIO;
-                               goto out;
-                       }
-
-                       continue;
-               }
-
-               if (bootverbose) {
-                       device_printf(dev,
-                           "allocated irq for '%s'\n", irq_def->name);
-               }
+               error = arm_tmr_attach_irq(dev, sc, irq_def, rid, flags);
+               if (error != 0)
+                       goto out;
        }
 
        error = arm_tmr_attach(dev);
 out:
        if (error != 0) {
                for (i = 0; i < GT_IRQ_COUNT; i++) {
-                       if (sc->res[i] != NULL) {
-                               /*
-                                * rid may not match the index into sc->res in
-                                * a number of cases; e.g., optional sec-phys or
-                                * interrupt-names specifying them in a
-                                * different order than expected.
-                                */
+                       if (sc->irqs[i].res != NULL) {
                                bus_release_resource(dev, SYS_RES_IRQ,
-                                   rman_get_rid(sc->res[i]), sc->res[i]);
+                                   sc->irqs[i].rid, sc->irqs[i].res);
                        }
                }
        }
@@ -578,18 +574,29 @@ arm_tmr_acpi_probe(device_t dev)
 static int
 arm_tmr_acpi_attach(device_t dev)
 {
+       const struct arm_tmr_irq_defs *irq_def;
        struct arm_tmr_softc *sc;
        int error;
 
        sc = device_get_softc(dev);
-       if (bus_alloc_resources(dev, timer_acpi_spec, sc->res)) {
-               device_printf(dev, "could not allocate resources\n");
-               return (ENXIO);
+       for (int i = 0; i < nitems(arm_tmr_irq_defs); i++) {
+               irq_def = &arm_tmr_irq_defs[i];
+               error = arm_tmr_attach_irq(dev, sc, irq_def, irq_def->idx,
+                   irq_def->flags);
+               if (error != 0)
+                       goto out;
        }
 
        error = arm_tmr_attach(dev);
-       if (error != 0)
-               bus_release_resources(dev, timer_acpi_spec, sc->res);
+out:
+       if (error != 0) {
+               for (int i = 0; i < GT_IRQ_COUNT; i++) {
+                       if (sc->irqs[i].res != NULL) {
+                               bus_release_resource(dev, SYS_RES_IRQ,
+                                   sc->irqs[i].rid, sc->irqs[i].res);
+                       }
+               }
+       }
        return (error);
 }
 #endif
@@ -643,13 +650,13 @@ arm_tmr_attach(device_t dev)
        for (i = 0; i < nitems(arm_tmr_irq_defs); i++) {
                irq_def = &arm_tmr_irq_defs[i];
 
-               MPASS(sc->res[irq_def->idx] != NULL ||
+               MPASS(sc->irqs[irq_def->idx].res != NULL ||
                    (irq_def->flags & RF_OPTIONAL) != 0);
        }
 
 #ifdef __aarch64__
        /* Use the virtual timer if we have one. */
-       if (sc->res[GT_VIRT] != NULL) {
+       if (sc->irqs[GT_VIRT].res != NULL) {
                sc->physical = false;
                first_timer = GT_VIRT;
                last_timer = GT_VIRT;
@@ -667,24 +674,25 @@ arm_tmr_attach(device_t dev)
        /* Setup secure, non-secure and virtual IRQs handler */
        for (i = first_timer; i <= last_timer; i++) {
                /* If we do not have the interrupt, skip it. */
-               if (sc->res[i] == NULL)
+               if (sc->irqs[i].res == NULL)
                        continue;
-               error = bus_setup_intr(dev, sc->res[i], INTR_TYPE_CLK,
-                   arm_tmr_intr, NULL, sc, &sc->ihl[i]);
+               error = bus_setup_intr(dev, sc->irqs[i].res, INTR_TYPE_CLK,
+                   arm_tmr_intr, NULL, sc, &sc->irqs[i].ihl);
                if (error) {
                        device_printf(dev, "Unable to alloc int resource.\n");
                        for (int j = first_timer; j < i; j++)
-                               bus_teardown_intr(dev, sc->res[j], &sc->ihl[j]);
+                               bus_teardown_intr(dev, sc->irqs[j].res,
+                                   &sc->irqs[j].ihl);
                        return (ENXIO);
                }
        }
 
        /* Disable the virtual timer until we are ready */
-       if (sc->res[GT_VIRT] != NULL)
+       if (sc->irqs[GT_VIRT].res != NULL)
                arm_tmr_disable(false);
        /* And the physical */
-       if ((sc->res[GT_PHYS_SECURE] != NULL ||
-           sc->res[GT_PHYS_NONSECURE] != NULL) && HAS_PHYS)
+       if ((sc->irqs[GT_PHYS_SECURE].res != NULL ||
+           sc->irqs[GT_PHYS_NONSECURE].res != NULL) && HAS_PHYS)
                arm_tmr_disable(true);
 
        arm_tmr_timecount.tc_frequency = sc->clkfreq;

Reply via email to