1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (C) 2020-2022 Loongson Technology Corporation Limited |
4 | */ |
5 | #include <linux/delay.h> |
6 | #include <linux/export.h> |
7 | #include <linux/smp.h> |
8 | #include <linux/timex.h> |
9 | |
10 | #include <asm/processor.h> |
11 | |
12 | void __delay(unsigned long cycles) |
13 | { |
14 | u64 t0 = get_cycles(); |
15 | |
16 | while ((unsigned long)(get_cycles() - t0) < cycles) |
17 | cpu_relax(); |
18 | } |
19 | EXPORT_SYMBOL(__delay); |
20 | |
21 | /* |
22 | * Division by multiplication: you don't have to worry about |
23 | * loss of precision. |
24 | * |
25 | * Use only for very small delays ( < 1 msec). Should probably use a |
26 | * lookup table, really, as the multiplications take much too long with |
27 | * short delays. This is a "reasonable" implementation, though (and the |
28 | * first constant multiplications gets optimized away if the delay is |
29 | * a constant) |
30 | */ |
31 | |
32 | void __udelay(unsigned long us) |
33 | { |
34 | __delay((us * 0x000010c7ull * HZ * lpj_fine) >> 32); |
35 | } |
36 | EXPORT_SYMBOL(__udelay); |
37 | |
38 | void __ndelay(unsigned long ns) |
39 | { |
40 | __delay((ns * 0x00000005ull * HZ * lpj_fine) >> 32); |
41 | } |
42 | EXPORT_SYMBOL(__ndelay); |
43 | |