Page MenuHomeFreeBSD

D39094.diff
No OneTemporary

D39094.diff

diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -103,12 +103,14 @@
struct resource *res;
void *ihl;
int rid;
+ int idx;
};
struct arm_tmr_softc {
struct arm_tmr_irq irqs[GT_IRQ_COUNT];
uint64_t (*get_cntxct)(bool);
uint32_t clkfreq;
+ int irq_count;
struct eventtimer et;
bool physical;
};
@@ -403,9 +405,12 @@
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,
+ struct arm_tmr_irq *irq;
+
+ irq = &sc->irqs[sc->irq_count];
+ irq->res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&rid, flags);
- if (sc->irqs[irq_def->idx].res == NULL) {
+ if (irq->res == NULL) {
if (bootverbose || (flags & RF_OPTIONAL) == 0) {
device_printf(dev,
"could not allocate irq for %s interrupt '%s'\n",
@@ -415,8 +420,13 @@
if ((flags & RF_OPTIONAL) == 0)
return (ENXIO);
- } else if (bootverbose) {
- device_printf(dev, "allocated irq for '%s'\n", irq_def->name);
+ } else {
+ if (bootverbose)
+ device_printf(dev, "allocated irq for '%s'\n",
+ irq_def->name);
+ irq->rid = rid;
+ irq->idx = irq_def->idx;
+ sc->irq_count++;
}
return (0);
@@ -507,11 +517,9 @@
error = arm_tmr_attach(dev);
out:
if (error != 0) {
- for (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);
- }
+ for (i = 0; i < sc->irq_count; i++) {
+ bus_release_resource(dev, SYS_RES_IRQ, sc->irqs[i].rid,
+ sc->irqs[i].res);
}
}
@@ -590,11 +598,9 @@
error = arm_tmr_attach(dev);
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);
- }
+ for (int i = 0; i < sc->irq_count; i++) {
+ bus_release_resource(dev, SYS_RES_IRQ,
+ sc->irqs[i].rid, sc->irqs[i].res);
}
}
return (error);
@@ -605,7 +611,9 @@
arm_tmr_attach(device_t dev)
{
struct arm_tmr_softc *sc;
+#ifdef INVARIANTS
const struct arm_tmr_irq_defs *irq_def;
+#endif
#ifdef FDT
phandle_t node;
pcell_t clock;
@@ -646,13 +654,25 @@
return (ENXIO);
}
+#ifdef INVARIANTS
/* Confirm that non-optional irqs were allocated before coming in. */
for (i = 0; i < nitems(arm_tmr_irq_defs); i++) {
+ int j;
+
irq_def = &arm_tmr_irq_defs[i];
- MPASS(sc->irqs[irq_def->idx].res != NULL ||
- (irq_def->flags & RF_OPTIONAL) != 0);
+ /* Skip optional interrupts */
+ if ((irq_def->flags & RF_OPTIONAL) != 0)
+ continue;
+
+ for (j = 0; j < sc->irq_count; j++) {
+ if (sc->irqs[j].idx == irq_def->idx)
+ break;
+ }
+ KASSERT(j < sc->irq_count, ("%s: Missing required interrupt %s",
+ __func__, irq_def->name));
}
+#endif
#ifdef __aarch64__
/*
@@ -677,15 +697,16 @@
arm_tmr_sc = sc;
/* 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->irqs[i].res == NULL)
+ for (i = 0; i < sc->irq_count; i++) {
+ /* Only enable IRQs on timers we expect to use */
+ if (sc->irqs[i].idx < first_timer ||
+ sc->irqs[i].idx > last_timer)
continue;
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++)
+ for (int j = 0; j < i; j++)
bus_teardown_intr(dev, sc->irqs[j].res,
&sc->irqs[j].ihl);
return (ENXIO);

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 16, 8:28 PM (21 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14664089
Default Alt Text
D39094.diff (3 KB)

Event Timeline