| 304 | } |
| 305 | |
| 306 | static int |
| 307 | attach_et(struct arm_tmr_softc *sc) |
| 308 | { |
| 309 | void *ihl; |
| 310 | int irid, mrid; |
| 311 | |
| 312 | if (arm_tmr_et != NULL) |
| 313 | return (EBUSY); |
| 314 | |
| 315 | mrid = sc->memrid; |
| 316 | sc->prv_mem = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY, &mrid, |
| 317 | RF_ACTIVE); |
| 318 | if (sc->prv_mem == NULL) { |
| 319 | device_printf(sc->dev, "could not allocate prv mem resources\n"); |
| 320 | return (ENXIO); |
| 321 | } |
| 322 | tmr_prv_write_4(sc, PRV_TIMER_CTRL, 0x00000000); |
| 323 | |
| 324 | irid = sc->irqrid; |
| 325 | sc->prv_irq = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &irid, RF_ACTIVE); |
| 326 | if (sc->prv_irq == NULL) { |
| 327 | bus_release_resource(sc->dev, SYS_RES_MEMORY, mrid, sc->prv_mem); |
| 328 | device_printf(sc->dev, "could not allocate prv irq resources\n"); |
| 329 | return (ENXIO); |
| 330 | } |
| 331 | |
| 332 | if (bus_setup_intr(sc->dev, sc->prv_irq, INTR_TYPE_CLK, arm_tmr_intr, |
| 333 | NULL, sc, &ihl) != 0) { |
| 334 | bus_release_resource(sc->dev, SYS_RES_MEMORY, mrid, sc->prv_mem); |
| 335 | bus_release_resource(sc->dev, SYS_RES_IRQ, irid, sc->prv_irq); |
| 336 | device_printf(sc->dev, "unable to setup the et irq handler.\n"); |
| 337 | return (ENXIO); |
| 338 | } |
| 339 | |
| 340 | /* |
| 341 | * Setup and register the eventtimer. Most event timers set their min |
| 342 | * and max period values to some value calculated from the clock |
| 343 | * frequency. We might not know yet what our runtime clock frequency |
| 344 | * will be, so we just use some safe values. A max of 2 seconds ensures |
| 345 | * that even if our base clock frequency is 2GHz (meaning a 4GHz CPU), |
| 346 | * we won't overflow our 32-bit timer count register. A min of 20 |
| 347 | * nanoseconds is pretty much completely arbitrary. |
| 348 | */ |
| 349 | sc->et.et_name = "MPCore"; |
| 350 | sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT | ET_FLAGS_PERCPU; |
| 351 | sc->et.et_quality = 1000; |
| 352 | sc->et.et_frequency = sc->clkfreq; |
| 353 | sc->et.et_min_period = nstosbt(20); |
| 354 | sc->et.et_max_period = 2 * SBT_1S; |
| 355 | sc->et.et_start = arm_tmr_start; |
| 356 | sc->et.et_stop = arm_tmr_stop; |
| 357 | sc->et.et_priv = sc; |
| 358 | et_register(&sc->et); |
| 359 | arm_tmr_et = &sc->et; |
| 360 | |
| 361 | return (0); |
| 362 | } |
| 363 |
no test coverage detected