* arm_tmr_attach - attaches the timer to the simplebus * @dev: new device * * Reserves memory and interrupt resources, stores the softc structure * globally and registers both the timecount and eventtimer objects. * * RETURNS * Zero on success or ENXIO if an error occuried. */
| 372 | * Zero on success or ENXIO if an error occuried. |
| 373 | */ |
| 374 | static int |
| 375 | arm_tmr_attach(device_t dev) |
| 376 | { |
| 377 | struct arm_tmr_softc *sc; |
| 378 | phandle_t node; |
| 379 | pcell_t clock; |
| 380 | int et_err, tc_err, tmrtype; |
| 381 | |
| 382 | sc = device_get_softc(dev); |
| 383 | sc->dev = dev; |
| 384 | |
| 385 | if (arm_tmr_freq_varies) { |
| 386 | sc->clkfreq = arm_tmr_freq; |
| 387 | } else { |
| 388 | if (arm_tmr_freq != 0) { |
| 389 | sc->clkfreq = arm_tmr_freq; |
| 390 | } else { |
| 391 | /* Get the base clock frequency */ |
| 392 | node = ofw_bus_get_node(dev); |
| 393 | if ((OF_getencprop(node, "clock-frequency", &clock, |
| 394 | sizeof(clock))) <= 0) { |
| 395 | device_printf(dev, "missing clock-frequency " |
| 396 | "attribute in FDT\n"); |
| 397 | return (ENXIO); |
| 398 | } |
| 399 | sc->clkfreq = clock; |
| 400 | } |
| 401 | } |
| 402 | |
| 403 | tmrtype = ofw_bus_search_compatible(dev, compat_data)->ocd_data; |
| 404 | tc_err = ENXIO; |
| 405 | et_err = ENXIO; |
| 406 | |
| 407 | /* |
| 408 | * If we're handling the global timer and it is fixed-frequency, set it |
| 409 | * up to use as a timecounter. If it's variable frequency it won't work |
| 410 | * as a timecounter. We also can't use it for DELAY(), so hopefully the |
| 411 | * platform provides its own implementation. If it doesn't, ours will |
| 412 | * get used, but since the frequency isn't set, it will only use the |
| 413 | * bogus loop counter. |
| 414 | */ |
| 415 | if (tmrtype & TMR_GBL) { |
| 416 | if (!arm_tmr_freq_varies) |
| 417 | tc_err = attach_tc(sc); |
| 418 | else if (bootverbose) |
| 419 | device_printf(sc->dev, |
| 420 | "not using variable-frequency device as timecounter\n"); |
| 421 | sc->memrid++; |
| 422 | sc->irqrid++; |
| 423 | } |
| 424 | |
| 425 | /* If we are handling the private timer, set it up as an eventtimer. */ |
| 426 | if (tmrtype & TMR_PRV) { |
| 427 | et_err = attach_et(sc); |
| 428 | } |
| 429 | |
| 430 | /* |
| 431 | * If we didn't successfully set up a timecounter or eventtimer then we |
nothing calls this directly
no test coverage detected