xref: /kernel/linux/linux-6.6/arch/alpha/lib/udelay.c (revision 62306a36)
162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 1993, 2000 Linus Torvalds
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Delay routines, using a pre-computed "loops_per_jiffy" value.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/module.h>
962306a36Sopenharmony_ci#include <linux/sched.h> /* for udelay's use of smp_processor_id */
1062306a36Sopenharmony_ci#include <asm/param.h>
1162306a36Sopenharmony_ci#include <asm/smp.h>
1262306a36Sopenharmony_ci#include <linux/delay.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci/*
1562306a36Sopenharmony_ci * Use only for very small delays (< 1 msec).
1662306a36Sopenharmony_ci *
1762306a36Sopenharmony_ci * The active part of our cycle counter is only 32-bits wide, and
1862306a36Sopenharmony_ci * we're treating the difference between two marks as signed.  On
1962306a36Sopenharmony_ci * a 1GHz box, that's about 2 seconds.
2062306a36Sopenharmony_ci */
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_civoid
2362306a36Sopenharmony_ci__delay(int loops)
2462306a36Sopenharmony_ci{
2562306a36Sopenharmony_ci	int tmp;
2662306a36Sopenharmony_ci	__asm__ __volatile__(
2762306a36Sopenharmony_ci		"	rpcc %0\n"
2862306a36Sopenharmony_ci		"	addl %1,%0,%1\n"
2962306a36Sopenharmony_ci		"1:	rpcc %0\n"
3062306a36Sopenharmony_ci		"	subl %1,%0,%0\n"
3162306a36Sopenharmony_ci		"	bgt %0,1b"
3262306a36Sopenharmony_ci		: "=&r" (tmp), "=r" (loops) : "1"(loops));
3362306a36Sopenharmony_ci}
3462306a36Sopenharmony_ciEXPORT_SYMBOL(__delay);
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci#ifdef CONFIG_SMP
3762306a36Sopenharmony_ci#define LPJ	 cpu_data[smp_processor_id()].loops_per_jiffy
3862306a36Sopenharmony_ci#else
3962306a36Sopenharmony_ci#define LPJ	 loops_per_jiffy
4062306a36Sopenharmony_ci#endif
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_civoid
4362306a36Sopenharmony_ciudelay(unsigned long usecs)
4462306a36Sopenharmony_ci{
4562306a36Sopenharmony_ci	usecs *= (((unsigned long)HZ << 32) / 1000000) * LPJ;
4662306a36Sopenharmony_ci	__delay((long)usecs >> 32);
4762306a36Sopenharmony_ci}
4862306a36Sopenharmony_ciEXPORT_SYMBOL(udelay);
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_civoid
5162306a36Sopenharmony_cindelay(unsigned long nsecs)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	nsecs *= (((unsigned long)HZ << 32) / 1000000000) * LPJ;
5462306a36Sopenharmony_ci	__delay((long)nsecs >> 32);
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ciEXPORT_SYMBOL(ndelay);
57