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