| 116 | } |
| 117 | |
| 118 | static int |
| 119 | pmu_parse_intr(device_t dev, struct pmu_softc *sc) |
| 120 | { |
| 121 | bool has_affinity; |
| 122 | phandle_t node, *cpus; |
| 123 | int rid, err, ncpus, i; |
| 124 | |
| 125 | |
| 126 | node = ofw_bus_get_node(dev); |
| 127 | has_affinity = OF_hasprop(node, "interrupt-affinity"); |
| 128 | |
| 129 | for (i = 0; i < MAX_RLEN; i++) |
| 130 | sc->irq[i].cpuid = -1; |
| 131 | |
| 132 | cpus = NULL; |
| 133 | if (has_affinity) { |
| 134 | ncpus = OF_getencprop_alloc_multi(node, "interrupt-affinity", |
| 135 | sizeof(*cpus), (void **)&cpus); |
| 136 | if (ncpus < 0) { |
| 137 | device_printf(dev, |
| 138 | "Cannot read interrupt affinity property\n"); |
| 139 | return (ENXIO); |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | /* Process first interrupt */ |
| 144 | rid = 0; |
| 145 | sc->irq[0].res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, |
| 146 | RF_ACTIVE | RF_SHAREABLE); |
| 147 | |
| 148 | if (sc->irq[0].res == NULL) { |
| 149 | device_printf(dev, "Cannot get interrupt\n"); |
| 150 | err = ENXIO; |
| 151 | goto done; |
| 152 | } |
| 153 | |
| 154 | /* Check if PMU have one per-CPU interrupt */ |
| 155 | if (intr_is_per_cpu(sc->irq[0].res)) { |
| 156 | if (has_affinity) { |
| 157 | device_printf(dev, |
| 158 | "Per CPU interupt have declared affinity\n"); |
| 159 | err = ENXIO; |
| 160 | goto done; |
| 161 | } |
| 162 | return (0); |
| 163 | } |
| 164 | |
| 165 | /* |
| 166 | * PMU with set of generic interrupts (one per core) |
| 167 | * Each one must be binded to exact core. |
| 168 | */ |
| 169 | err = pmu_parse_affinity(dev, sc, sc->irq + 0, |
| 170 | has_affinity ? cpus[0] : 0, 0); |
| 171 | if (err != 0) { |
| 172 | device_printf(dev, "Cannot parse affinity for CPUid: 0\n"); |
| 173 | goto done; |
| 174 | } |
| 175 |
no test coverage detected