Lines Matching +full:sp804 +full:- +full:has +full:- +full:irq
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * linux/drivers/clocksource/timer-sp.c
5 * Copyright (C) 1999 - 2003 ARM Limited
13 #include <linux/irq.h>
21 #include "timer-sp.h"
23 /* Hisilicon 64-bit timer(a variant of ARM SP804) */
66 clk = clk_get_sys("sp804", name); in sp804_get_clock_rate()
68 pr_err("sp804: %s clock not found: %ld\n", name, PTR_ERR(clk)); in sp804_get_clock_rate()
74 pr_err("sp804: clock failed to prepare: %d\n", err); in sp804_get_clock_rate()
81 pr_err("sp804: clock failed to enable: %d\n", err); in sp804_get_clock_rate()
89 pr_err("sp804: clock failed to get rate: %ld\n", rate); in sp804_get_clock_rate()
117 return ~readl_relaxed(sched_clkevt->value); in sp804_read()
130 return -EINVAL; in sp804_clocksource_and_sched_clock_init()
134 writel(0, clkevt->ctrl); in sp804_clocksource_and_sched_clock_init()
135 writel(0xffffffff, clkevt->load); in sp804_clocksource_and_sched_clock_init()
136 writel(0xffffffff, clkevt->value); in sp804_clocksource_and_sched_clock_init()
137 if (clkevt->width == 64) { in sp804_clocksource_and_sched_clock_init()
138 writel(0xffffffff, clkevt->load_h); in sp804_clocksource_and_sched_clock_init()
139 writel(0xffffffff, clkevt->value_h); in sp804_clocksource_and_sched_clock_init()
142 clkevt->ctrl); in sp804_clocksource_and_sched_clock_init()
144 clocksource_mmio_init(clkevt->value, name, in sp804_clocksource_and_sched_clock_init()
159 * IRQ handler for the timer
161 static irqreturn_t sp804_timer_interrupt(int irq, void *dev_id) in sp804_timer_interrupt() argument
166 writel(1, common_clkevt->intclr); in sp804_timer_interrupt()
168 evt->event_handler(evt); in sp804_timer_interrupt()
175 writel(0, common_clkevt->ctrl); in timer_shutdown()
190 writel(common_clkevt->reload, common_clkevt->load); in sp804_set_periodic()
191 writel(ctrl, common_clkevt->ctrl); in sp804_set_periodic()
201 writel(next, common_clkevt->load); in sp804_set_next_event()
202 writel(ctrl, common_clkevt->ctrl); in sp804_set_next_event()
219 int __init sp804_clockevents_init(void __iomem *base, unsigned int irq, in sp804_clockevents_init() argument
227 return -EINVAL; in sp804_clockevents_init()
230 common_clkevt->reload = DIV_ROUND_CLOSEST(rate, HZ); in sp804_clockevents_init()
231 evt->name = name; in sp804_clockevents_init()
232 evt->irq = irq; in sp804_clockevents_init()
233 evt->cpumask = cpu_possible_mask; in sp804_clockevents_init()
235 writel(0, common_clkevt->ctrl); in sp804_clockevents_init()
237 if (request_irq(irq, sp804_timer_interrupt, IRQF_TIMER | IRQF_IRQPOLL, in sp804_clockevents_init()
253 timer_base = base + timer->timer_base[i]; in sp804_clkevt_init()
255 clkevt->base = timer_base; in sp804_clkevt_init()
256 clkevt->load = timer_base + timer->load; in sp804_clkevt_init()
257 clkevt->load_h = timer_base + timer->load_h; in sp804_clkevt_init()
258 clkevt->value = timer_base + timer->value; in sp804_clkevt_init()
259 clkevt->value_h = timer_base + timer->value_h; in sp804_clkevt_init()
260 clkevt->ctrl = timer_base + timer->ctrl; in sp804_clkevt_init()
261 clkevt->intclr = timer_base + timer->intclr; in sp804_clkevt_init()
262 clkevt->width = timer->width; in sp804_clkevt_init()
272 int irq, ret = -EINVAL; in sp804_of_init() local
278 pr_debug("%pOF: skipping further SP804 timer device\n", np); in sp804_of_init()
284 return -ENXIO; in sp804_of_init()
286 timer1_base = base + timer->timer_base[0]; in sp804_of_init()
287 timer2_base = base + timer->timer_base[1]; in sp804_of_init()
290 writel(0, timer1_base + timer->ctrl); in sp804_of_init()
291 writel(0, timer2_base + timer->ctrl); in sp804_of_init()
297 /* Get the 2nd clock if the timer has 3 timer clocks */ in sp804_of_init()
301 pr_err("sp804: %pOFn clock not found: %d\n", np, in sp804_of_init()
308 irq = irq_of_parse_and_map(np, 0); in sp804_of_init()
309 if (irq <= 0) in sp804_of_init()
314 of_property_read_u32(np, "arm,sp804-has-irq", &irq_num); in sp804_of_init()
317 ret = sp804_clockevents_init(timer2_base, irq, clk2, name); in sp804_of_init()
327 ret = sp804_clockevents_init(timer1_base, irq, clk1, name); in sp804_of_init()
348 TIMER_OF_DECLARE(sp804, "arm,sp804", arm_sp804_of_init);
354 TIMER_OF_DECLARE(hisi_sp804, "hisilicon,sp804", hisi_sp804_of_init);
360 int irq, ret = -EINVAL; in integrator_cp_of_init() local
367 return -ENXIO; in integrator_cp_of_init()
390 irq = irq_of_parse_and_map(np, 0); in integrator_cp_of_init()
391 if (irq <= 0) in integrator_cp_of_init()
394 ret = sp804_clockevents_init(base, irq, clk, name); in integrator_cp_of_init()
405 TIMER_OF_DECLARE(intcp, "arm,integrator-cp-timer", integrator_cp_of_init);