xref: /kernel/linux/linux-5.10/arch/alpha/lib/udelay.c (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 1993, 2000 Linus Torvalds
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Delay routines, using a pre-computed "loops_per_jiffy" value.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/module.h>
98c2ecf20Sopenharmony_ci#include <linux/sched.h> /* for udelay's use of smp_processor_id */
108c2ecf20Sopenharmony_ci#include <asm/param.h>
118c2ecf20Sopenharmony_ci#include <asm/smp.h>
128c2ecf20Sopenharmony_ci#include <linux/delay.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci/*
158c2ecf20Sopenharmony_ci * Use only for very small delays (< 1 msec).
168c2ecf20Sopenharmony_ci *
178c2ecf20Sopenharmony_ci * The active part of our cycle counter is only 32-bits wide, and
188c2ecf20Sopenharmony_ci * we're treating the difference between two marks as signed.  On
198c2ecf20Sopenharmony_ci * a 1GHz box, that's about 2 seconds.
208c2ecf20Sopenharmony_ci */
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_civoid
238c2ecf20Sopenharmony_ci__delay(int loops)
248c2ecf20Sopenharmony_ci{
258c2ecf20Sopenharmony_ci	int tmp;
268c2ecf20Sopenharmony_ci	__asm__ __volatile__(
278c2ecf20Sopenharmony_ci		"	rpcc %0\n"
288c2ecf20Sopenharmony_ci		"	addl %1,%0,%1\n"
298c2ecf20Sopenharmony_ci		"1:	rpcc %0\n"
308c2ecf20Sopenharmony_ci		"	subl %1,%0,%0\n"
318c2ecf20Sopenharmony_ci		"	bgt %0,1b"
328c2ecf20Sopenharmony_ci		: "=&r" (tmp), "=r" (loops) : "1"(loops));
338c2ecf20Sopenharmony_ci}
348c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__delay);
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP
378c2ecf20Sopenharmony_ci#define LPJ	 cpu_data[smp_processor_id()].loops_per_jiffy
388c2ecf20Sopenharmony_ci#else
398c2ecf20Sopenharmony_ci#define LPJ	 loops_per_jiffy
408c2ecf20Sopenharmony_ci#endif
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_civoid
438c2ecf20Sopenharmony_ciudelay(unsigned long usecs)
448c2ecf20Sopenharmony_ci{
458c2ecf20Sopenharmony_ci	usecs *= (((unsigned long)HZ << 32) / 1000000) * LPJ;
468c2ecf20Sopenharmony_ci	__delay((long)usecs >> 32);
478c2ecf20Sopenharmony_ci}
488c2ecf20Sopenharmony_ciEXPORT_SYMBOL(udelay);
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_civoid
518c2ecf20Sopenharmony_cindelay(unsigned long nsecs)
528c2ecf20Sopenharmony_ci{
538c2ecf20Sopenharmony_ci	nsecs *= (((unsigned long)HZ << 32) / 1000000000) * LPJ;
548c2ecf20Sopenharmony_ci	__delay((long)nsecs >> 32);
558c2ecf20Sopenharmony_ci}
568c2ecf20Sopenharmony_ciEXPORT_SYMBOL(ndelay);
57