^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * arch/arm/mach-pxa/time.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * PXA clocksource, clockevents, and OST interrupt handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2007 by Bill Gatliff <bgat@billgatliff.com>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Derived from Nicolas Pitre's PXA timer handler Copyright (c) 2001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * by MontaVista Software, Inc. (Nico, your code rocks!)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/clockchips.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/sched/clock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/sched_clock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <clocksource/pxa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/div64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define OSMR0 0x00 /* OS Timer 0 Match Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define OSMR1 0x04 /* OS Timer 1 Match Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define OSMR2 0x08 /* OS Timer 2 Match Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define OSMR3 0x0C /* OS Timer 3 Match Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define OSCR 0x10 /* OS Timer Counter Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define OSSR 0x14 /* OS Timer Status Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define OWER 0x18 /* OS Timer Watchdog Enable Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define OIER 0x1C /* OS Timer Interrupt Enable Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define OSSR_M3 (1 << 3) /* Match status channel 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define OSSR_M2 (1 << 2) /* Match status channel 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define OSSR_M1 (1 << 1) /* Match status channel 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define OSSR_M0 (1 << 0) /* Match status channel 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * This is PXA's sched_clock implementation. This has a resolution
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * of at least 308 ns and a maximum value of 208 days.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * The return value is guaranteed to be monotonic in that range as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * long as there is always less than 582 seconds between successive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * calls to sched_clock() which should always be the case in practice.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define timer_readl(reg) readl_relaxed(timer_base + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define timer_writel(val, reg) writel_relaxed((val), timer_base + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static void __iomem *timer_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static u64 notrace pxa_read_sched_clock(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return timer_readl(OSCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define MIN_OSCR_DELTA 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) pxa_ost0_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct clock_event_device *c = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Disarm the compare/match, signal the event. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) timer_writel(timer_readl(OIER) & ~OIER_E0, OIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) timer_writel(OSSR_M0, OSSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) c->event_handler(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) pxa_osmr0_set_next_event(unsigned long delta, struct clock_event_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) unsigned long next, oscr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) timer_writel(timer_readl(OIER) | OIER_E0, OIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) next = timer_readl(OSCR) + delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) timer_writel(next, OSMR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) oscr = timer_readl(OSCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static int pxa_osmr0_shutdown(struct clock_event_device *evt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /* initializing, released, or preparing for suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) timer_writel(timer_readl(OIER) & ~OIER_E0, OIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) timer_writel(OSSR_M0, OSSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static unsigned long osmr[4], oier, oscr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void pxa_timer_suspend(struct clock_event_device *cedev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) osmr[0] = timer_readl(OSMR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) osmr[1] = timer_readl(OSMR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) osmr[2] = timer_readl(OSMR2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) osmr[3] = timer_readl(OSMR3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) oier = timer_readl(OIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) oscr = timer_readl(OSCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static void pxa_timer_resume(struct clock_event_device *cedev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * Ensure that we have at least MIN_OSCR_DELTA between match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * register 0 and the OSCR, to guarantee that we will receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * the one-shot timer interrupt. We adjust OSMR0 in preference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * to OSCR to guarantee that OSCR is monotonically incrementing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (osmr[0] - oscr < MIN_OSCR_DELTA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) osmr[0] += MIN_OSCR_DELTA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) timer_writel(osmr[0], OSMR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) timer_writel(osmr[1], OSMR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) timer_writel(osmr[2], OSMR2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) timer_writel(osmr[3], OSMR3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) timer_writel(oier, OIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) timer_writel(oscr, OSCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define pxa_timer_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define pxa_timer_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static struct clock_event_device ckevt_pxa_osmr0 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .name = "osmr0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .features = CLOCK_EVT_FEAT_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .rating = 200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .set_next_event = pxa_osmr0_set_next_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .set_state_shutdown = pxa_osmr0_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .set_state_oneshot = pxa_osmr0_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .suspend = pxa_timer_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .resume = pxa_timer_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static int __init pxa_timer_common_init(int irq, unsigned long clock_tick_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) timer_writel(0, OIER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) timer_writel(OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3, OSSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) sched_clock_register(pxa_read_sched_clock, 32, clock_tick_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ckevt_pxa_osmr0.cpumask = cpumask_of(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ret = request_irq(irq, pxa_ost0_interrupt, IRQF_TIMER | IRQF_IRQPOLL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) "ost0", &ckevt_pxa_osmr0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) pr_err("Failed to setup irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ret = clocksource_mmio_init(timer_base + OSCR, "oscr0", clock_tick_rate, 200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 32, clocksource_mmio_readl_up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) pr_err("Failed to init clocksource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) clockevents_config_and_register(&ckevt_pxa_osmr0, clock_tick_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) MIN_OSCR_DELTA * 2, 0x7fffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static int __init pxa_timer_dt_init(struct device_node *np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) int irq, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /* timer registers are shared with watchdog timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) timer_base = of_iomap(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (!timer_base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) pr_err("%pOFn: unable to map resource\n", np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) clk = of_clk_get(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) pr_crit("%pOFn: unable to get clk\n", np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ret = clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) pr_crit("Failed to prepare clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* we are only interested in OS-timer0 irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) irq = irq_of_parse_and_map(np, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) pr_crit("%pOFn: unable to parse OS-timer0 irq\n", np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return pxa_timer_common_init(irq, clk_get_rate(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) TIMER_OF_DECLARE(pxa_timer, "marvell,pxa-timer", pxa_timer_dt_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * Legacy timer init for non device-tree boards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) void __init pxa_timer_nodt_init(int irq, void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) timer_base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) clk = clk_get(NULL, "OSTIMER0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (clk && !IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) pxa_timer_common_init(irq, clk_get_rate(clk));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) pr_crit("%s: unable to get clk\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }