pr_debug("%s CPU %d state=oneshot\n", __func__,
cpumask_first(evt->cpumask));
ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL); /* * set free running mode, this mode will let timer reload max * timeout which will give time (3min on 25MHz clock) to rearm * the next event, therefore emulate the one-shot mode.
*/
ctrl &= ~APBTMR_CONTROL_ENABLE;
ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); /* write again to set free running mode */
apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
/* * DW APB p. 46, load counter with all 1s before starting free * running mode.
*/
apbt_writel(&dw_ced->timer, ~0, APBTMR_N_LOAD_COUNT);
ctrl &= ~APBTMR_CONTROL_INT;
ctrl |= APBTMR_CONTROL_ENABLE;
apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL); return 0;
}
/** * dw_apb_clockevent_init() - use an APB timer as a clock_event_device * * @cpu: The CPU the events will be targeted at or -1 if CPU affiliation * isn't required. * @name: The name used for the timer and the IRQ for it. * @rating: The rating to give the timer. * @base: I/O base for the timer registers. * @irq: The interrupt number to use for the timer. * @freq: The frequency that the timer counts at. * * This creates a clock_event_device for using with the generic clock layer * but does not start and register it. This should be done with * dw_apb_clockevent_register() as the next step. If this is the first time * it has been called for a timer then the IRQ will be requested, if not it * just be enabled to allow CPU hotplug to avoid repeatedly requesting and * releasing the IRQ.
*/ struct dw_apb_clock_event_device *
dw_apb_clockevent_init(int cpu, constchar *name, unsigned rating, void __iomem *base, int irq, unsignedlong freq)
{ struct dw_apb_clock_event_device *dw_ced =
kzalloc(sizeof(*dw_ced), GFP_KERNEL); int err;
/** * dw_apb_clockevent_register() - register the clock with the generic layer * * @dw_ced: The APB clock to register as a clock_event_device.
*/ void dw_apb_clockevent_register(struct dw_apb_clock_event_device *dw_ced)
{
apbt_writel(&dw_ced->timer, 0, APBTMR_N_CONTROL);
clockevents_register_device(&dw_ced->ced);
apbt_enable_int(&dw_ced->timer);
}
/** * dw_apb_clocksource_start() - start the clocksource counting. * * @dw_cs: The clocksource to start. * * This is used to start the clocksource before registration and can be used * to enable calibration of timers.
*/ void dw_apb_clocksource_start(struct dw_apb_clocksource *dw_cs)
{ /* * start count down from 0xffff_ffff. this is done by toggling the * enable bit then load initial load count to ~0.
*/
u32 ctrl = apbt_readl(&dw_cs->timer, APBTMR_N_CONTROL);
ctrl &= ~APBTMR_CONTROL_ENABLE;
apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL);
apbt_writel(&dw_cs->timer, ~0, APBTMR_N_LOAD_COUNT); /* enable, mask interrupt */
ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT);
apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL); /* read it once to get cached counter value initialized */
dw_apb_clocksource_read(dw_cs);
}
/** * dw_apb_clocksource_init() - use an APB timer as a clocksource. * * @rating: The rating to give the clocksource. * @name: The name for the clocksource. * @base: The I/O base for the timer registers. * @freq: The frequency that the timer counts at. * * This creates a clocksource using an APB timer but does not yet register it * with the clocksource system. This should be done with * dw_apb_clocksource_register() as the next step.
*/ struct dw_apb_clocksource *
dw_apb_clocksource_init(unsigned rating, constchar *name, void __iomem *base, unsignedlong freq)
{ struct dw_apb_clocksource *dw_cs = kzalloc(sizeof(*dw_cs), GFP_KERNEL);
/** * dw_apb_clocksource_register() - register the APB clocksource. * * @dw_cs: The clocksource to register.
*/ void dw_apb_clocksource_register(struct dw_apb_clocksource *dw_cs)
{
clocksource_register_hz(&dw_cs->cs, dw_cs->timer.freq);
}
/** * dw_apb_clocksource_read() - read the current value of a clocksource. * * @dw_cs: The clocksource to read.
*/
u64 dw_apb_clocksource_read(struct dw_apb_clocksource *dw_cs)
{ return (u64)~apbt_readl(&dw_cs->timer, APBTMR_N_CURRENT_VALUE);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.