1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Precise Delay Loops for parisc 4 * 5 * based on code by: 6 * Copyright (C) 1993 Linus Torvalds 7 * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz> 8 * Copyright (C) 2008 Jiri Hladky <hladky _dot_ jiri _at_ gmail _dot_ com> 9 * 10 * parisc implementation: 11 * Copyright (C) 2013 Helge Deller <deller@gmx.de> 12 */ 13 14 15 #include <linux/module.h> 16 #include <linux/preempt.h> 17 #include <linux/init.h> 18 19 #include <asm/processor.h> 20 #include <asm/delay.h> 21 22 #include <asm/special_insns.h> /* for mfctl() */ 23 #include <asm/processor.h> /* for boot_cpu_data */ 24 25 /* CR16 based delay: */ 26 static void __cr16_delay(unsigned long __loops) 27 { 28 /* 29 * Note: Due to unsigned math, cr16 rollovers shouldn't be 30 * a problem here. However, on 32 bit, we need to make sure 31 * we don't pass in too big a value. The current default 32 * value of MAX_UDELAY_MS should help prevent this. 33 */ 34 u32 bclock, now, loops = __loops; 35 int cpu; 36 37 preempt_disable(); 38 cpu = smp_processor_id(); 39 bclock = mfctl(16); 40 for (;;) { 41 now = mfctl(16); 42 if ((now - bclock) >= loops) 43 break; 44 45 /* Allow RT tasks to run */ 46 preempt_enable(); 47 asm volatile(" nop\n"); 48 barrier(); 49 preempt_disable(); 50 51 /* 52 * It is possible that we moved to another CPU, and 53 * since CR16's are per-cpu we need to calculate 54 * that. The delay must guarantee that we wait "at 55 * least" the amount of time. Being moved to another 56 * CPU could make the wait longer but we just need to 57 * make sure we waited long enough. Rebalance the 58 * counter for this CPU. 59 */ 60 if (unlikely(cpu != smp_processor_id())) { 61 loops -= (now - bclock); 62 cpu = smp_processor_id(); 63 bclock = mfctl(16); 64 } 65 } 66 preempt_enable(); 67 } 68 69 70 void __udelay(unsigned long usecs) 71 { 72 __cr16_delay(usecs * ((unsigned long)boot_cpu_data.cpu_hz / 1000000UL)); 73 } 74 EXPORT_SYMBOL(__udelay); 75