Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }