/* * Place timer in reset and program the delta in the match * channel 0 (MR0). When the timer counter matches the value * in MR0 register the match will trigger an interrupt. * After setup the timer is released from reset and enabled.
*/
writel_relaxed(LPC32XX_TIMER_TCR_CRST, ddata->base + LPC32XX_TIMER_TCR);
writel_relaxed(delta, ddata->base + LPC32XX_TIMER_MR0);
writel_relaxed(LPC32XX_TIMER_TCR_CEN, ddata->base + LPC32XX_TIMER_TCR);
/* * When using oneshot, we must also disable the timer * to wait for the first call to set_next_event().
*/
writel_relaxed(0, ddata->base + LPC32XX_TIMER_TCR);
/* Enable interrupt, reset on match and stop on match (MCR). */
writel_relaxed(LPC32XX_TIMER_MCR_MR0I | LPC32XX_TIMER_MCR_MR0R |
LPC32XX_TIMER_MCR_MR0S, ddata->base + LPC32XX_TIMER_MCR); return 0;
}
/* Enable interrupt and reset on match. */
writel_relaxed(LPC32XX_TIMER_MCR_MR0I | LPC32XX_TIMER_MCR_MR0R,
ddata->base + LPC32XX_TIMER_MCR);
/* * Place timer in reset and program the delta in the match * channel 0 (MR0).
*/
writel_relaxed(LPC32XX_TIMER_TCR_CRST, ddata->base + LPC32XX_TIMER_TCR);
writel_relaxed(ddata->ticks_per_jiffy, ddata->base + LPC32XX_TIMER_MR0);
writel_relaxed(LPC32XX_TIMER_TCR_CEN, ddata->base + LPC32XX_TIMER_TCR);
clk = of_clk_get_by_name(np, "timerclk"); if (IS_ERR(clk)) {
pr_err("clock get failed (%ld)\n", PTR_ERR(clk)); return PTR_ERR(clk);
}
ret = clk_prepare_enable(clk); if (ret) {
pr_err("clock enable failed (%d)\n", ret); goto err_clk_enable;
}
base = of_iomap(np, 0); if (!base) {
pr_err("unable to map registers\n");
ret = -EADDRNOTAVAIL; goto err_iomap;
}
/* * Disable and reset timer then set it to free running timer * mode (CTCR) with no prescaler (PR) or match operations (MCR). * After setup the timer is released from reset and enabled.
*/
writel_relaxed(LPC32XX_TIMER_TCR_CRST, base + LPC32XX_TIMER_TCR);
writel_relaxed(0, base + LPC32XX_TIMER_PR);
writel_relaxed(0, base + LPC32XX_TIMER_MCR);
writel_relaxed(0, base + LPC32XX_TIMER_CTCR);
writel_relaxed(LPC32XX_TIMER_TCR_CEN, base + LPC32XX_TIMER_TCR);
rate = clk_get_rate(clk);
ret = clocksource_mmio_init(base + LPC32XX_TIMER_TC, "lpc3220 timer",
rate, 300, 32, clocksource_mmio_readl_up); if (ret) {
pr_err("failed to init clocksource (%d)\n", ret); goto err_clocksource_init;
}
clk = of_clk_get_by_name(np, "timerclk"); if (IS_ERR(clk)) {
pr_err("clock get failed (%ld)\n", PTR_ERR(clk)); return PTR_ERR(clk);
}
ret = clk_prepare_enable(clk); if (ret) {
pr_err("clock enable failed (%d)\n", ret); goto err_clk_enable;
}
base = of_iomap(np, 0); if (!base) {
pr_err("unable to map registers\n");
ret = -EADDRNOTAVAIL; goto err_iomap;
}
irq = irq_of_parse_and_map(np, 0); if (!irq) {
pr_err("get irq failed\n");
ret = -ENOENT; goto err_irq;
}
/* * Disable timer and clear any pending interrupt (IR) on match * channel 0 (MR0). Clear the prescaler as it's not used.
*/
writel_relaxed(0, base + LPC32XX_TIMER_TCR);
writel_relaxed(0, base + LPC32XX_TIMER_PR);
writel_relaxed(0, base + LPC32XX_TIMER_CTCR);
writel_relaxed(LPC32XX_TIMER_IR_MR0INT, base + LPC32XX_TIMER_IR);
/* * This function asserts that we have exactly one clocksource and one * clock_event_device in the end.
*/ staticint __init lpc32xx_timer_init(struct device_node *np)
{ staticint has_clocksource, has_clockevent; int ret = 0;
if (!has_clocksource) {
ret = lpc32xx_clocksource_init(np); if (!ret) {
has_clocksource = 1; return 0;
}
}
if (!has_clockevent) {
ret = lpc32xx_clockevent_init(np); if (!ret) {
has_clockevent = 1; return 0;
}
}
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.