162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2016-17 Synopsys, Inc. (www.synopsys.com) 462306a36Sopenharmony_ci * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1, Each can be 862306a36Sopenharmony_ci * programmed to go from @count to @limit and optionally interrupt. 962306a36Sopenharmony_ci * We've designated TIMER0 for clockevents and TIMER1 for clocksource 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * ARCv2 based HS38 cores have RTC (in-core) and GFRC (inside ARConnect/MCIP) 1262306a36Sopenharmony_ci * which are suitable for UP and SMP based clocksources respectively 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/interrupt.h> 1662306a36Sopenharmony_ci#include <linux/bits.h> 1762306a36Sopenharmony_ci#include <linux/clk.h> 1862306a36Sopenharmony_ci#include <linux/clk-provider.h> 1962306a36Sopenharmony_ci#include <linux/clocksource.h> 2062306a36Sopenharmony_ci#include <linux/clockchips.h> 2162306a36Sopenharmony_ci#include <linux/cpu.h> 2262306a36Sopenharmony_ci#include <linux/of.h> 2362306a36Sopenharmony_ci#include <linux/of_irq.h> 2462306a36Sopenharmony_ci#include <linux/sched_clock.h> 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#include <soc/arc/timers.h> 2762306a36Sopenharmony_ci#include <soc/arc/mcip.h> 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistatic unsigned long arc_timer_freq; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_cistatic int noinline arc_get_timer_clk(struct device_node *node) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci struct clk *clk; 3562306a36Sopenharmony_ci int ret; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci clk = of_clk_get(node, 0); 3862306a36Sopenharmony_ci if (IS_ERR(clk)) { 3962306a36Sopenharmony_ci pr_err("timer missing clk\n"); 4062306a36Sopenharmony_ci return PTR_ERR(clk); 4162306a36Sopenharmony_ci } 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci ret = clk_prepare_enable(clk); 4462306a36Sopenharmony_ci if (ret) { 4562306a36Sopenharmony_ci pr_err("Couldn't enable parent clk\n"); 4662306a36Sopenharmony_ci return ret; 4762306a36Sopenharmony_ci } 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci arc_timer_freq = clk_get_rate(clk); 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci return 0; 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci/********** Clock Source Device *********/ 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#ifdef CONFIG_ARC_TIMERS_64BIT 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_cistatic u64 arc_read_gfrc(struct clocksource *cs) 5962306a36Sopenharmony_ci{ 6062306a36Sopenharmony_ci unsigned long flags; 6162306a36Sopenharmony_ci u32 l, h; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci /* 6462306a36Sopenharmony_ci * From a programming model pov, there seems to be just one instance of 6562306a36Sopenharmony_ci * MCIP_CMD/MCIP_READBACK however micro-architecturally there's 6662306a36Sopenharmony_ci * an instance PER ARC CORE (not per cluster), and there are dedicated 6762306a36Sopenharmony_ci * hardware decode logic (per core) inside ARConnect to handle 6862306a36Sopenharmony_ci * simultaneous read/write accesses from cores via those two registers. 6962306a36Sopenharmony_ci * So several concurrent commands to ARConnect are OK if they are 7062306a36Sopenharmony_ci * trying to access two different sub-components (like GFRC, 7162306a36Sopenharmony_ci * inter-core interrupt, etc...). HW also supports simultaneously 7262306a36Sopenharmony_ci * accessing GFRC by multiple cores. 7362306a36Sopenharmony_ci * That's why it is safe to disable hard interrupts on the local CPU 7462306a36Sopenharmony_ci * before access to GFRC instead of taking global MCIP spinlock 7562306a36Sopenharmony_ci * defined in arch/arc/kernel/mcip.c 7662306a36Sopenharmony_ci */ 7762306a36Sopenharmony_ci local_irq_save(flags); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci __mcip_cmd(CMD_GFRC_READ_LO, 0); 8062306a36Sopenharmony_ci l = read_aux_reg(ARC_REG_MCIP_READBACK); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci __mcip_cmd(CMD_GFRC_READ_HI, 0); 8362306a36Sopenharmony_ci h = read_aux_reg(ARC_REG_MCIP_READBACK); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci local_irq_restore(flags); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci return (((u64)h) << 32) | l; 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic notrace u64 arc_gfrc_clock_read(void) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci return arc_read_gfrc(NULL); 9362306a36Sopenharmony_ci} 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cistatic struct clocksource arc_counter_gfrc = { 9662306a36Sopenharmony_ci .name = "ARConnect GFRC", 9762306a36Sopenharmony_ci .rating = 400, 9862306a36Sopenharmony_ci .read = arc_read_gfrc, 9962306a36Sopenharmony_ci .mask = CLOCKSOURCE_MASK(64), 10062306a36Sopenharmony_ci .flags = CLOCK_SOURCE_IS_CONTINUOUS, 10162306a36Sopenharmony_ci}; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_cistatic int __init arc_cs_setup_gfrc(struct device_node *node) 10462306a36Sopenharmony_ci{ 10562306a36Sopenharmony_ci struct mcip_bcr mp; 10662306a36Sopenharmony_ci int ret; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci READ_BCR(ARC_REG_MCIP_BCR, mp); 10962306a36Sopenharmony_ci if (!mp.gfrc) { 11062306a36Sopenharmony_ci pr_warn("Global-64-bit-Ctr clocksource not detected\n"); 11162306a36Sopenharmony_ci return -ENXIO; 11262306a36Sopenharmony_ci } 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci ret = arc_get_timer_clk(node); 11562306a36Sopenharmony_ci if (ret) 11662306a36Sopenharmony_ci return ret; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci sched_clock_register(arc_gfrc_clock_read, 64, arc_timer_freq); 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci return clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq); 12162306a36Sopenharmony_ci} 12262306a36Sopenharmony_ciTIMER_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci#define AUX_RTC_CTRL 0x103 12562306a36Sopenharmony_ci#define AUX_RTC_LOW 0x104 12662306a36Sopenharmony_ci#define AUX_RTC_HIGH 0x105 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistatic u64 arc_read_rtc(struct clocksource *cs) 12962306a36Sopenharmony_ci{ 13062306a36Sopenharmony_ci unsigned long status; 13162306a36Sopenharmony_ci u32 l, h; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci /* 13462306a36Sopenharmony_ci * hardware has an internal state machine which tracks readout of 13562306a36Sopenharmony_ci * low/high and updates the CTRL.status if 13662306a36Sopenharmony_ci * - interrupt/exception taken between the two reads 13762306a36Sopenharmony_ci * - high increments after low has been read 13862306a36Sopenharmony_ci */ 13962306a36Sopenharmony_ci do { 14062306a36Sopenharmony_ci l = read_aux_reg(AUX_RTC_LOW); 14162306a36Sopenharmony_ci h = read_aux_reg(AUX_RTC_HIGH); 14262306a36Sopenharmony_ci status = read_aux_reg(AUX_RTC_CTRL); 14362306a36Sopenharmony_ci } while (!(status & BIT(31))); 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci return (((u64)h) << 32) | l; 14662306a36Sopenharmony_ci} 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cistatic notrace u64 arc_rtc_clock_read(void) 14962306a36Sopenharmony_ci{ 15062306a36Sopenharmony_ci return arc_read_rtc(NULL); 15162306a36Sopenharmony_ci} 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cistatic struct clocksource arc_counter_rtc = { 15462306a36Sopenharmony_ci .name = "ARCv2 RTC", 15562306a36Sopenharmony_ci .rating = 350, 15662306a36Sopenharmony_ci .read = arc_read_rtc, 15762306a36Sopenharmony_ci .mask = CLOCKSOURCE_MASK(64), 15862306a36Sopenharmony_ci .flags = CLOCK_SOURCE_IS_CONTINUOUS, 15962306a36Sopenharmony_ci}; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cistatic int __init arc_cs_setup_rtc(struct device_node *node) 16262306a36Sopenharmony_ci{ 16362306a36Sopenharmony_ci struct bcr_timer timer; 16462306a36Sopenharmony_ci int ret; 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci READ_BCR(ARC_REG_TIMERS_BCR, timer); 16762306a36Sopenharmony_ci if (!timer.rtc) { 16862306a36Sopenharmony_ci pr_warn("Local-64-bit-Ctr clocksource not detected\n"); 16962306a36Sopenharmony_ci return -ENXIO; 17062306a36Sopenharmony_ci } 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci /* Local to CPU hence not usable in SMP */ 17362306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_SMP)) { 17462306a36Sopenharmony_ci pr_warn("Local-64-bit-Ctr not usable in SMP\n"); 17562306a36Sopenharmony_ci return -EINVAL; 17662306a36Sopenharmony_ci } 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci ret = arc_get_timer_clk(node); 17962306a36Sopenharmony_ci if (ret) 18062306a36Sopenharmony_ci return ret; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci write_aux_reg(AUX_RTC_CTRL, 1); 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci sched_clock_register(arc_rtc_clock_read, 64, arc_timer_freq); 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci return clocksource_register_hz(&arc_counter_rtc, arc_timer_freq); 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ciTIMER_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci#endif 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci/* 19362306a36Sopenharmony_ci * 32bit TIMER1 to keep counting monotonically and wraparound 19462306a36Sopenharmony_ci */ 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_cistatic u64 arc_read_timer1(struct clocksource *cs) 19762306a36Sopenharmony_ci{ 19862306a36Sopenharmony_ci return (u64) read_aux_reg(ARC_REG_TIMER1_CNT); 19962306a36Sopenharmony_ci} 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_cistatic notrace u64 arc_timer1_clock_read(void) 20262306a36Sopenharmony_ci{ 20362306a36Sopenharmony_ci return arc_read_timer1(NULL); 20462306a36Sopenharmony_ci} 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_cistatic struct clocksource arc_counter_timer1 = { 20762306a36Sopenharmony_ci .name = "ARC Timer1", 20862306a36Sopenharmony_ci .rating = 300, 20962306a36Sopenharmony_ci .read = arc_read_timer1, 21062306a36Sopenharmony_ci .mask = CLOCKSOURCE_MASK(32), 21162306a36Sopenharmony_ci .flags = CLOCK_SOURCE_IS_CONTINUOUS, 21262306a36Sopenharmony_ci}; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_cistatic int __init arc_cs_setup_timer1(struct device_node *node) 21562306a36Sopenharmony_ci{ 21662306a36Sopenharmony_ci int ret; 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci /* Local to CPU hence not usable in SMP */ 21962306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_SMP)) 22062306a36Sopenharmony_ci return -EINVAL; 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci ret = arc_get_timer_clk(node); 22362306a36Sopenharmony_ci if (ret) 22462306a36Sopenharmony_ci return ret; 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMERN_MAX); 22762306a36Sopenharmony_ci write_aux_reg(ARC_REG_TIMER1_CNT, 0); 22862306a36Sopenharmony_ci write_aux_reg(ARC_REG_TIMER1_CTRL, ARC_TIMER_CTRL_NH); 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci sched_clock_register(arc_timer1_clock_read, 32, arc_timer_freq); 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci return clocksource_register_hz(&arc_counter_timer1, arc_timer_freq); 23362306a36Sopenharmony_ci} 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci/********** Clock Event Device *********/ 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cistatic int arc_timer_irq; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_ci/* 24062306a36Sopenharmony_ci * Arm the timer to interrupt after @cycles 24162306a36Sopenharmony_ci * The distinction for oneshot/periodic is done in arc_event_timer_ack() below 24262306a36Sopenharmony_ci */ 24362306a36Sopenharmony_cistatic void arc_timer_event_setup(unsigned int cycles) 24462306a36Sopenharmony_ci{ 24562306a36Sopenharmony_ci write_aux_reg(ARC_REG_TIMER0_LIMIT, cycles); 24662306a36Sopenharmony_ci write_aux_reg(ARC_REG_TIMER0_CNT, 0); /* start from 0 */ 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci write_aux_reg(ARC_REG_TIMER0_CTRL, ARC_TIMER_CTRL_IE | ARC_TIMER_CTRL_NH); 24962306a36Sopenharmony_ci} 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_cistatic int arc_clkevent_set_next_event(unsigned long delta, 25362306a36Sopenharmony_ci struct clock_event_device *dev) 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci arc_timer_event_setup(delta); 25662306a36Sopenharmony_ci return 0; 25762306a36Sopenharmony_ci} 25862306a36Sopenharmony_ci 25962306a36Sopenharmony_cistatic int arc_clkevent_set_periodic(struct clock_event_device *dev) 26062306a36Sopenharmony_ci{ 26162306a36Sopenharmony_ci /* 26262306a36Sopenharmony_ci * At X Hz, 1 sec = 1000ms -> X cycles; 26362306a36Sopenharmony_ci * 10ms -> X / 100 cycles 26462306a36Sopenharmony_ci */ 26562306a36Sopenharmony_ci arc_timer_event_setup(arc_timer_freq / HZ); 26662306a36Sopenharmony_ci return 0; 26762306a36Sopenharmony_ci} 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_cistatic DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = { 27062306a36Sopenharmony_ci .name = "ARC Timer0", 27162306a36Sopenharmony_ci .features = CLOCK_EVT_FEAT_ONESHOT | 27262306a36Sopenharmony_ci CLOCK_EVT_FEAT_PERIODIC, 27362306a36Sopenharmony_ci .rating = 300, 27462306a36Sopenharmony_ci .set_next_event = arc_clkevent_set_next_event, 27562306a36Sopenharmony_ci .set_state_periodic = arc_clkevent_set_periodic, 27662306a36Sopenharmony_ci}; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_cistatic irqreturn_t timer_irq_handler(int irq, void *dev_id) 27962306a36Sopenharmony_ci{ 28062306a36Sopenharmony_ci /* 28162306a36Sopenharmony_ci * Note that generic IRQ core could have passed @evt for @dev_id if 28262306a36Sopenharmony_ci * irq_set_chip_and_handler() asked for handle_percpu_devid_irq() 28362306a36Sopenharmony_ci */ 28462306a36Sopenharmony_ci struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); 28562306a36Sopenharmony_ci int irq_reenable = clockevent_state_periodic(evt); 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci /* 28862306a36Sopenharmony_ci * 1. ACK the interrupt 28962306a36Sopenharmony_ci * - For ARC700, any write to CTRL reg ACKs it, so just rewrite 29062306a36Sopenharmony_ci * Count when [N]ot [H]alted bit. 29162306a36Sopenharmony_ci * - For HS3x, it is a bit subtle. On taken count-down interrupt, 29262306a36Sopenharmony_ci * IP bit [3] is set, which needs to be cleared for ACK'ing. 29362306a36Sopenharmony_ci * The write below can only update the other two bits, hence 29462306a36Sopenharmony_ci * explicitly clears IP bit 29562306a36Sopenharmony_ci * 2. Re-arm interrupt if periodic by writing to IE bit [0] 29662306a36Sopenharmony_ci */ 29762306a36Sopenharmony_ci write_aux_reg(ARC_REG_TIMER0_CTRL, irq_reenable | ARC_TIMER_CTRL_NH); 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci evt->event_handler(evt); 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci return IRQ_HANDLED; 30262306a36Sopenharmony_ci} 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_cistatic int arc_timer_starting_cpu(unsigned int cpu) 30662306a36Sopenharmony_ci{ 30762306a36Sopenharmony_ci struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci evt->cpumask = cpumask_of(smp_processor_id()); 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMERN_MAX); 31262306a36Sopenharmony_ci enable_percpu_irq(arc_timer_irq, 0); 31362306a36Sopenharmony_ci return 0; 31462306a36Sopenharmony_ci} 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_cistatic int arc_timer_dying_cpu(unsigned int cpu) 31762306a36Sopenharmony_ci{ 31862306a36Sopenharmony_ci disable_percpu_irq(arc_timer_irq); 31962306a36Sopenharmony_ci return 0; 32062306a36Sopenharmony_ci} 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci/* 32362306a36Sopenharmony_ci * clockevent setup for boot CPU 32462306a36Sopenharmony_ci */ 32562306a36Sopenharmony_cistatic int __init arc_clockevent_setup(struct device_node *node) 32662306a36Sopenharmony_ci{ 32762306a36Sopenharmony_ci struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device); 32862306a36Sopenharmony_ci int ret; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci arc_timer_irq = irq_of_parse_and_map(node, 0); 33162306a36Sopenharmony_ci if (arc_timer_irq <= 0) { 33262306a36Sopenharmony_ci pr_err("clockevent: missing irq\n"); 33362306a36Sopenharmony_ci return -EINVAL; 33462306a36Sopenharmony_ci } 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci ret = arc_get_timer_clk(node); 33762306a36Sopenharmony_ci if (ret) 33862306a36Sopenharmony_ci return ret; 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci /* Needs apriori irq_set_percpu_devid() done in intc map function */ 34162306a36Sopenharmony_ci ret = request_percpu_irq(arc_timer_irq, timer_irq_handler, 34262306a36Sopenharmony_ci "Timer0 (per-cpu-tick)", evt); 34362306a36Sopenharmony_ci if (ret) { 34462306a36Sopenharmony_ci pr_err("clockevent: unable to request irq\n"); 34562306a36Sopenharmony_ci return ret; 34662306a36Sopenharmony_ci } 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci ret = cpuhp_setup_state(CPUHP_AP_ARC_TIMER_STARTING, 34962306a36Sopenharmony_ci "clockevents/arc/timer:starting", 35062306a36Sopenharmony_ci arc_timer_starting_cpu, 35162306a36Sopenharmony_ci arc_timer_dying_cpu); 35262306a36Sopenharmony_ci if (ret) { 35362306a36Sopenharmony_ci pr_err("Failed to setup hotplug state\n"); 35462306a36Sopenharmony_ci return ret; 35562306a36Sopenharmony_ci } 35662306a36Sopenharmony_ci return 0; 35762306a36Sopenharmony_ci} 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_cistatic int __init arc_of_timer_init(struct device_node *np) 36062306a36Sopenharmony_ci{ 36162306a36Sopenharmony_ci static int init_count = 0; 36262306a36Sopenharmony_ci int ret; 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci if (!init_count) { 36562306a36Sopenharmony_ci init_count = 1; 36662306a36Sopenharmony_ci ret = arc_clockevent_setup(np); 36762306a36Sopenharmony_ci } else { 36862306a36Sopenharmony_ci ret = arc_cs_setup_timer1(np); 36962306a36Sopenharmony_ci } 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci return ret; 37262306a36Sopenharmony_ci} 37362306a36Sopenharmony_ciTIMER_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init); 374