diff options
author | 2025-03-08 22:04:20 +0800 | |
---|---|---|
committer | 2025-03-08 22:04:20 +0800 | |
commit | a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch) | |
tree | 84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/kernel/cevt-gt641xx.c | |
download | ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip |
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/kernel/cevt-gt641xx.c')
-rw-r--r-- | arch/mips/kernel/cevt-gt641xx.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c new file mode 100644 index 000000000..5b132e8c5 --- /dev/null +++ b/arch/mips/kernel/cevt-gt641xx.c | |||
@@ -0,0 +1,146 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
2 | /* | ||
3 | * GT641xx clockevent routines. | ||
4 | * | ||
5 | * Copyright (C) 2007 Yoichi Yuasa <yuasa@linux-mips.org> | ||
6 | */ | ||
7 | #include <linux/clockchips.h> | ||
8 | #include <linux/init.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/spinlock.h> | ||
11 | #include <linux/irq.h> | ||
12 | |||
13 | #include <asm/gt64120.h> | ||
14 | #include <asm/time.h> | ||
15 | |||
16 | static DEFINE_RAW_SPINLOCK(gt641xx_timer_lock); | ||
17 | static unsigned int gt641xx_base_clock; | ||
18 | |||
19 | void gt641xx_set_base_clock(unsigned int clock) | ||
20 | { | ||
21 | gt641xx_base_clock = clock; | ||
22 | } | ||
23 | |||
24 | int gt641xx_timer0_state(void) | ||
25 | { | ||
26 | if (GT_READ(GT_TC0_OFS)) | ||
27 | return 0; | ||
28 | |||
29 | GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ); | ||
30 | GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK); | ||
31 | |||
32 | return 1; | ||
33 | } | ||
34 | |||
35 | static int gt641xx_timer0_set_next_event(unsigned long delta, | ||
36 | struct clock_event_device *evt) | ||
37 | { | ||
38 | u32 ctrl; | ||
39 | |||
40 | raw_spin_lock(>641xx_timer_lock); | ||
41 | |||
42 | ctrl = GT_READ(GT_TC_CONTROL_OFS); | ||
43 | ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); | ||
44 | ctrl |= GT_TC_CONTROL_ENTC0_MSK; | ||
45 | |||
46 | GT_WRITE(GT_TC0_OFS, delta); | ||
47 | GT_WRITE(GT_TC_CONTROL_OFS, ctrl); | ||
48 | |||
49 | raw_spin_unlock(>641xx_timer_lock); | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | static int gt641xx_timer0_shutdown(struct clock_event_device *evt) | ||
55 | { | ||
56 | u32 ctrl; | ||
57 | |||
58 | raw_spin_lock(>641xx_timer_lock); | ||
59 | |||
60 | ctrl = GT_READ(GT_TC_CONTROL_OFS); | ||
61 | ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK); | ||
62 | GT_WRITE(GT_TC_CONTROL_OFS, ctrl); | ||
63 | |||
64 | raw_spin_unlock(>641xx_timer_lock); | ||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | static int gt641xx_timer0_set_oneshot(struct clock_event_device *evt) | ||
69 | { | ||
70 | u32 ctrl; | ||
71 | |||
72 | raw_spin_lock(>641xx_timer_lock); | ||
73 | |||
74 | ctrl = GT_READ(GT_TC_CONTROL_OFS); | ||
75 | ctrl &= ~GT_TC_CONTROL_SELTC0_MSK; | ||
76 | ctrl |= GT_TC_CONTROL_ENTC0_MSK; | ||
77 | GT_WRITE(GT_TC_CONTROL_OFS, ctrl); | ||
78 | |||
79 | raw_spin_unlock(>641xx_timer_lock); | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static int gt641xx_timer0_set_periodic(struct clock_event_device *evt) | ||
84 | { | ||
85 | u32 ctrl; | ||
86 | |||
87 | raw_spin_lock(>641xx_timer_lock); | ||
88 | |||
89 | ctrl = GT_READ(GT_TC_CONTROL_OFS); | ||
90 | ctrl |= GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK; | ||
91 | GT_WRITE(GT_TC_CONTROL_OFS, ctrl); | ||
92 | |||
93 | raw_spin_unlock(>641xx_timer_lock); | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static void gt641xx_timer0_event_handler(struct clock_event_device *dev) | ||
98 | { | ||
99 | } | ||
100 | |||
101 | static struct clock_event_device gt641xx_timer0_clockevent = { | ||
102 | .name = "gt641xx-timer0", | ||
103 | .features = CLOCK_EVT_FEAT_PERIODIC | | ||
104 | CLOCK_EVT_FEAT_ONESHOT, | ||
105 | .irq = GT641XX_TIMER0_IRQ, | ||
106 | .set_next_event = gt641xx_timer0_set_next_event, | ||
107 | .set_state_shutdown = gt641xx_timer0_shutdown, | ||
108 | .set_state_periodic = gt641xx_timer0_set_periodic, | ||
109 | .set_state_oneshot = gt641xx_timer0_set_oneshot, | ||
110 | .tick_resume = gt641xx_timer0_shutdown, | ||
111 | .event_handler = gt641xx_timer0_event_handler, | ||
112 | }; | ||
113 | |||
114 | static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id) | ||
115 | { | ||
116 | struct clock_event_device *cd = >641xx_timer0_clockevent; | ||
117 | |||
118 | cd->event_handler(cd); | ||
119 | |||
120 | return IRQ_HANDLED; | ||
121 | } | ||
122 | |||
123 | static int __init gt641xx_timer0_clockevent_init(void) | ||
124 | { | ||
125 | struct clock_event_device *cd; | ||
126 | |||
127 | if (!gt641xx_base_clock) | ||
128 | return 0; | ||
129 | |||
130 | GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ); | ||
131 | |||
132 | cd = >641xx_timer0_clockevent; | ||
133 | cd->rating = 200 + gt641xx_base_clock / 10000000; | ||
134 | clockevent_set_clock(cd, gt641xx_base_clock); | ||
135 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); | ||
136 | cd->max_delta_ticks = 0x7fffffff; | ||
137 | cd->min_delta_ns = clockevent_delta2ns(0x300, cd); | ||
138 | cd->min_delta_ticks = 0x300; | ||
139 | cd->cpumask = cpumask_of(0); | ||
140 | |||
141 | clockevents_register_device(>641xx_timer0_clockevent); | ||
142 | |||
143 | return request_irq(GT641XX_TIMER0_IRQ, gt641xx_timer0_interrupt, | ||
144 | IRQF_PERCPU | IRQF_TIMER, "gt641xx_timer0", NULL); | ||
145 | } | ||
146 | arch_initcall(gt641xx_timer0_clockevent_init); | ||