lkml.org 
[lkml]   [2005]   [Jul]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH] all-arch delay patch
    Date
    This one is for review only by arch maintainers.

    Run tested on i386.

    # size vmlinux.org vmlinux.delay
    text data bss dec hex filename
    4345737 1607102 259296 6212135 5eca27 vmlinux.org
    4345296 1604470 259296 6209062 5ebe26 vmlinux.delay

    If someone from non-i386 land with a bit of time to spare
    wants to test it, that will be appreciated.
    Add #include <linux/delay.h> if you will get undefined refs to
    [mun]delay(). (I already did in two files IIRC).

    Vojtech, I did not read your mail when I worked on the patch,
    thus your ndelay() concerns are not addressed.

    find.out.bz2 has some less boring cases of delays grepped
    from kernel source. Selected gems are:

    aic79xx_osm.h:
    ahd_delay(long usec)
    {
    /*
    * udelay on Linux can have problems for
    * multi-millisecond waits. Wait at most
    * 1024us per call.
    */
    while (usec > 0) {
    udelay(usec % 1024);
    usec -= 1024;
    }
    }

    arch/i386/kernel/traps.c:
    outb(reason, 0x61);
    i = 2000;
    while (--i) udelay(1000);
    reason &= ~8;
    outb(reason, 0x61);

    sound/oss/ad1889.c:
    //now 100ms
    /* #define WAIT_10MS() schedule_timeout(HZ/10) */
    #define WAIT_10MS() do { int __i; for (__i = 0; __i < 100; __i++) udelay(1000); } while(0)

    drivers/isdn/hisax/hisax.h:
    #define HZDELAY(jiffs) {int tout = jiffs; while (tout--) udelay(1000000/HZ);}

    drivers/scsi/u14-34f.c:
    while ((jiffies - time) < HZ && limit++ < 20000) udelay(100L);
    ...
    while ((jiffies - time) < (10 * HZ) && limit++ < 200000) udelay(100L);

    sound/isa/es18xx.c:
    udelay(100000);

    drivers/scsi/aha152x.c:
    mdelay(10000);
    --
    vda
    diff -U10 -urpN linux-2.6.12.org/arch/alpha/lib/udelay.c linux-2.6.12.delay/arch/alpha/lib/udelay.c
    --- linux-2.6.12.org/arch/alpha/lib/udelay.c Tue Oct 19 00:54:39 2004
    +++ linux-2.6.12.delay/arch/alpha/lib/udelay.c Thu Jun 30 22:48:06 2005
    @@ -32,24 +32,24 @@ __delay(int loops)
    : "=&r" (tmp), "=r" (loops) : "1"(loops));
    }

    #ifdef CONFIG_SMP
    #define LPJ cpu_data[smp_processor_id()].loops_per_jiffy
    #else
    #define LPJ loops_per_jiffy
    #endif

    void
    -udelay(unsigned long usecs)
    +__udelay(unsigned long usecs)
    {
    usecs *= (((unsigned long)HZ << 32) / 1000000) * LPJ;
    __delay((long)usecs >> 32);
    }
    -EXPORT_SYMBOL(udelay);
    +EXPORT_SYMBOL(__udelay);

    void
    -ndelay(unsigned long nsecs)
    +__ndelay(unsigned long nsecs)
    {
    nsecs *= (((unsigned long)HZ << 32) / 1000000000) * LPJ;
    __delay((long)nsecs >> 32);
    }
    -EXPORT_SYMBOL(ndelay);
    +EXPORT_SYMBOL(__ndelay);
    diff -U10 -urpN linux-2.6.12.org/arch/arm/kernel/armksyms.c linux-2.6.12.delay/arch/arm/kernel/armksyms.c
    --- linux-2.6.12.org/arch/arm/kernel/armksyms.c Thu Feb 3 11:38:47 2005
    +++ linux-2.6.12.delay/arch/arm/kernel/armksyms.c Thu Jun 30 22:42:50 2005
    @@ -54,21 +54,20 @@ extern void fp_enter(void);
    * These symbols will never change their calling convention...
    */
    EXPORT_SYMBOL_ALIAS(kern_fp_enter,fp_enter);
    EXPORT_SYMBOL_ALIAS(fp_printk,printk);
    EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig);

    EXPORT_SYMBOL(__backtrace);

    /* platform dependent support */
    EXPORT_SYMBOL(__udelay);
    -EXPORT_SYMBOL(__const_udelay);

    /* networking */
    EXPORT_SYMBOL(csum_partial);
    EXPORT_SYMBOL(csum_partial_copy_nocheck);
    EXPORT_SYMBOL(__csum_ipv6_magic);

    /* io */
    #ifndef __raw_readsb
    EXPORT_SYMBOL(__raw_readsb);
    #endif
    diff -U10 -urpN linux-2.6.12.org/arch/arm/lib/delay.S linux-2.6.12.delay/arch/arm/lib/delay.S
    --- linux-2.6.12.org/arch/arm/lib/delay.S Thu Feb 3 11:38:48 2005
    +++ linux-2.6.12.delay/arch/arm/lib/delay.S Thu Jun 30 22:44:30 2005
    @@ -13,21 +13,21 @@

    LC0: .word loops_per_jiffy

    /*
    * 0 <= r0 <= 2000
    */
    ENTRY(__udelay)
    mov r2, #0x6800
    orr r2, r2, #0x00db
    mul r0, r2, r0
    -ENTRY(__const_udelay) @ 0 <= r0 <= 0x01ffffff
    + @ 0 <= r0 <= 0x01ffffff
    ldr r2, LC0
    ldr r2, [r2] @ max = 0x0fffffff
    mov r0, r0, lsr #11 @ max = 0x00003fff
    mov r2, r2, lsr #11 @ max = 0x0003ffff
    mul r0, r2, r0 @ max = 2^32-1
    movs r0, r0, lsr #6
    RETINSTR(moveq,pc,lr)

    /*
    * loops = (r0 * 0x10c6 * 100 * loops_per_jiffy) / 2^32
    diff -U10 -urpN linux-2.6.12.org/arch/i386/kernel/i386_ksyms.c linux-2.6.12.delay/arch/i386/kernel/i386_ksyms.c
    --- linux-2.6.12.org/arch/i386/kernel/i386_ksyms.c Sun Jun 19 16:09:49 2005
    +++ linux-2.6.12.delay/arch/i386/kernel/i386_ksyms.c Thu Jun 30 20:33:42 2005
    @@ -84,21 +84,20 @@ EXPORT_SYMBOL(apm_info);
    EXPORT_SYMBOL(__down_failed);
    EXPORT_SYMBOL(__down_failed_interruptible);
    EXPORT_SYMBOL(__down_failed_trylock);
    EXPORT_SYMBOL(__up_wakeup);
    /* Networking helper routines. */
    EXPORT_SYMBOL(csum_partial_copy_generic);
    /* Delay loops */
    EXPORT_SYMBOL(__ndelay);
    EXPORT_SYMBOL(__udelay);
    EXPORT_SYMBOL(__delay);
    -EXPORT_SYMBOL(__const_udelay);

    EXPORT_SYMBOL(__get_user_1);
    EXPORT_SYMBOL(__get_user_2);
    EXPORT_SYMBOL(__get_user_4);

    EXPORT_SYMBOL(__put_user_1);
    EXPORT_SYMBOL(__put_user_2);
    EXPORT_SYMBOL(__put_user_4);
    EXPORT_SYMBOL(__put_user_8);

    diff -U10 -urpN linux-2.6.12.org/arch/i386/kernel/i8259.c linux-2.6.12.delay/arch/i386/kernel/i8259.c
    --- linux-2.6.12.org/arch/i386/kernel/i8259.c Sun Jun 19 16:09:49 2005
    +++ linux-2.6.12.delay/arch/i386/kernel/i8259.c Fri Jul 1 00:18:40 2005
    @@ -4,20 +4,21 @@
    #include <linux/sched.h>
    #include <linux/ioport.h>
    #include <linux/interrupt.h>
    #include <linux/slab.h>
    #include <linux/random.h>
    #include <linux/smp_lock.h>
    #include <linux/init.h>
    #include <linux/kernel_stat.h>
    #include <linux/sysdev.h>
    #include <linux/bitops.h>
    +#include <linux/delay.h>

    #include <asm/8253pit.h>
    #include <asm/atomic.h>
    #include <asm/system.h>
    #include <asm/io.h>
    #include <asm/irq.h>
    #include <asm/timer.h>
    #include <asm/pgtable.h>
    #include <asm/delay.h>
    #include <asm/desc.h>
    diff -U10 -urpN linux-2.6.12.org/arch/i386/kernel/timers/timer_pit.c linux-2.6.12.delay/arch/i386/kernel/timers/timer_pit.c
    --- linux-2.6.12.org/arch/i386/kernel/timers/timer_pit.c Thu Feb 3 11:38:53 2005
    +++ linux-2.6.12.delay/arch/i386/kernel/timers/timer_pit.c Fri Jul 1 00:20:04 2005
    @@ -2,21 +2,21 @@
    * This code largely moved from arch/i386/kernel/time.c.
    * See comments there for proper credits.
    */

    #include <linux/spinlock.h>
    #include <linux/module.h>
    #include <linux/device.h>
    #include <linux/irq.h>
    #include <linux/sysdev.h>
    #include <linux/timex.h>
    -#include <asm/delay.h>
    +#include <linux/delay.h>
    #include <asm/mpspec.h>
    #include <asm/timer.h>
    #include <asm/smp.h>
    #include <asm/io.h>
    #include <asm/arch_hooks.h>

    extern spinlock_t i8259A_lock;
    extern spinlock_t i8253_lock;
    #include "do_timer.h"
    #include "io_ports.h"
    diff -U10 -urpN linux-2.6.12.org/arch/i386/lib/delay.c linux-2.6.12.delay/arch/i386/lib/delay.c
    --- linux-2.6.12.org/arch/i386/lib/delay.c Thu Mar 3 09:30:10 2005
    +++ linux-2.6.12.delay/arch/i386/lib/delay.c Thu Jun 30 20:33:54 2005
    @@ -21,21 +21,21 @@
    #include <asm/smp.h>
    #endif

    extern struct timer_opts* timer;

    void __delay(unsigned long loops)
    {
    cur_timer->delay(loops);
    }

    -inline void __const_udelay(unsigned long xloops)
    +static inline void __const_udelay(unsigned long xloops)
    {
    int d0;
    xloops *= 4;
    __asm__("mull %0"
    :"=d" (xloops), "=&a" (d0)
    :"1" (xloops),"0" (cpu_data[_smp_processor_id()].loops_per_jiffy * (HZ/4)));
    __delay(++xloops);
    }

    void __udelay(unsigned long usecs)
    diff -U10 -urpN linux-2.6.12.org/arch/m32r/kernel/m32r_ksyms.c linux-2.6.12.delay/arch/m32r/kernel/m32r_ksyms.c
    --- linux-2.6.12.org/arch/m32r/kernel/m32r_ksyms.c Sun Jun 19 16:09:52 2005
    +++ linux-2.6.12.delay/arch/m32r/kernel/m32r_ksyms.c Thu Jun 30 20:31:44 2005
    @@ -37,21 +37,20 @@ EXPORT_SYMBOL(disable_irq_nosync);
    EXPORT_SYMBOL(kernel_thread);
    EXPORT_SYMBOL(__down);
    EXPORT_SYMBOL(__down_interruptible);
    EXPORT_SYMBOL(__up);
    EXPORT_SYMBOL(__down_trylock);

    /* Networking helper routines. */
    /* Delay loops */
    EXPORT_SYMBOL(__udelay);
    EXPORT_SYMBOL(__delay);
    -EXPORT_SYMBOL(__const_udelay);

    EXPORT_SYMBOL(__get_user_1);
    EXPORT_SYMBOL(__get_user_2);
    EXPORT_SYMBOL(__get_user_4);

    EXPORT_SYMBOL(strpbrk);
    EXPORT_SYMBOL(strstr);

    EXPORT_SYMBOL(strncpy_from_user);
    EXPORT_SYMBOL(__strncpy_from_user);
    diff -U10 -urpN linux-2.6.12.org/arch/m32r/lib/delay.c linux-2.6.12.delay/arch/m32r/lib/delay.c
    --- linux-2.6.12.org/arch/m32r/lib/delay.c Thu Feb 3 11:38:55 2005
    +++ linux-2.6.12.delay/arch/m32r/lib/delay.c Thu Jun 30 20:31:36 2005
    @@ -51,21 +51,21 @@ void __delay(unsigned long loops)
    "addi %0, #-1 \n\t"
    "bgtz %0, 1b \n\t"
    " .fillinsn \n\t"
    "2: \n\t"
    : "+r" (loops)
    : "r" (0)
    );
    #endif
    }

    -void __const_udelay(unsigned long xloops)
    +static void __const_udelay(unsigned long xloops)
    {
    #if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
    /*
    * loops [1] = (xloops >> 32) [sec] * loops_per_jiffy [1/jiffy]
    * * HZ [jiffy/sec]
    * = (xloops >> 32) [sec] * (loops_per_jiffy * HZ) [1/sec]
    * = (((xloops * loops_per_jiffy) >> 32) * HZ) [1]
    *
    * NOTE:
    * - '[]' depicts variable's dimension in the above equation.
    diff -U10 -urpN linux-2.6.12.org/arch/m68knommu/lib/delay.c linux-2.6.12.delay/arch/m68knommu/lib/delay.c
    --- linux-2.6.12.org/arch/m68knommu/lib/delay.c Thu Mar 3 09:30:14 2005
    +++ linux-2.6.12.delay/arch/m68knommu/lib/delay.c Thu Jun 30 20:29:49 2005
    @@ -5,17 +5,69 @@
    *
    * This program is free software; you can redistribute it and/or modify
    * it under the terms of the GNU General Public License version 2 as
    * published by the Free Software Foundation.
    */

    #include <linux/module.h>
    #include <asm/param.h>
    #include <asm/delay.h>

    -EXPORT_SYMBOL(udelay);
    +extern unsigned long loops_per_jiffy;

    -void udelay(unsigned long usecs)
    +extern __inline__ void __delay(unsigned long loops)
    {
    - _udelay(usecs);
    +#if defined(CONFIG_COLDFIRE)
    + /* The coldfire runs this loop at significantly different speeds
    + * depending upon long word alignment or not. We'll pad it to
    + * long word alignment which is the faster version.
    + * The 0x4a8e is of course a 'tstl %fp' instruction. This is better
    + * than using a NOP (0x4e71) instruction because it executes in one
    + * cycle not three and doesn't allow for an arbitary delay waiting
    + * for bus cycles to finish. Also fp/a6 isn't likely to cause a
    + * stall waiting for the register to become valid if such is added
    + * to the coldfire at some stage.
    + */
    + __asm__ __volatile__ ( ".balignw 4, 0x4a8e\n\t"
    + "1: subql #1, %0\n\t"
    + "jcc 1b"
    + : "=d" (loops) : "0" (loops));
    +#else
    + __asm__ __volatile__ ( "1: subql #1, %0\n\t"
    + "jcc 1b"
    + : "=d" (loops) : "0" (loops));
    +#endif
    +}
    +
    +/*
    + * Ideally we use a 32*32->64 multiply to calculate the number of
    + * loop iterations, but the older standard 68k and ColdFire do not
    + * have this instruction. So for them we have a clsoe approximation
    + * loop using 32*32->32 multiplies only. This calculation based on
    + * the ARM version of delay.
    + *
    + * We want to implement:
    + *
    + * loops = (usecs * 0x10c6 * HZ * loops_per_jiffy) / 2^32
    + */
    +
    +#define HZSCALE (268435456 / (1000000/HZ))
    +
    +EXPORT_SYMBOL(__udelay);
    +
    +void __udelay(unsigned long usecs)
    +{
    +#if defined(CONFIG_M68328) || defined(CONFIG_M68EZ328) || \
    + defined(CONFIG_M68VZ328) || defined(CONFIG_M68360) || \
    + defined(CONFIG_COLDFIRE)
    + __delay((((usecs * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6);
    +#else
    + unsigned long tmp;
    +
    + usecs *= 4295; /* 2**32 / 1000000 */
    + __asm__ ("mulul %2,%0:%1"
    + : "=d" (usecs), "=d" (tmp)
    + : "d" (usecs), "1" (loops_per_jiffy*HZ));
    + __delay(usecs);
    +#endif
    }

    diff -U10 -urpN linux-2.6.12.org/arch/sh/kernel/sh_ksyms.c linux-2.6.12.delay/arch/sh/kernel/sh_ksyms.c
    --- linux-2.6.12.org/arch/sh/kernel/sh_ksyms.c Sun Jun 19 16:09:58 2005
    +++ linux-2.6.12.delay/arch/sh/kernel/sh_ksyms.c Thu Jun 30 20:32:27 2005
    @@ -70,21 +70,20 @@ EXPORT_SYMBOL(boot_cpu_data);
    EXPORT_SYMBOL(get_vm_area);
    #endif

    /* semaphore exports */
    EXPORT_SYMBOL(__up);
    EXPORT_SYMBOL(__down);
    EXPORT_SYMBOL(__down_interruptible);

    EXPORT_SYMBOL(__udelay);
    EXPORT_SYMBOL(__ndelay);
    -EXPORT_SYMBOL(__const_udelay);

    EXPORT_SYMBOL(__div64_32);

    #define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL(name)

    /* These symbols are generated by the compiler itself */
    DECLARE_EXPORT(__udivsi3);
    DECLARE_EXPORT(__udivdi3);
    DECLARE_EXPORT(__sdivsi3);
    DECLARE_EXPORT(__ashrdi3);
    diff -U10 -urpN linux-2.6.12.org/arch/sh/lib/delay.c linux-2.6.12.delay/arch/sh/lib/delay.c
    --- linux-2.6.12.org/arch/sh/lib/delay.c Thu Mar 3 09:30:22 2005
    +++ linux-2.6.12.delay/arch/sh/lib/delay.c Thu Jun 30 20:32:33 2005
    @@ -12,21 +12,21 @@ void __delay(unsigned long loops)
    __asm__ __volatile__(
    "tst %0, %0\n\t"
    "1:\t"
    "bf/s 1b\n\t"
    " dt %0"
    : "=r" (loops)
    : "0" (loops)
    : "t");
    }

    -inline void __const_udelay(unsigned long xloops)
    +static inline void __const_udelay(unsigned long xloops)
    {
    __asm__("dmulu.l %0, %2\n\t"
    "sts mach, %0"
    : "=r" (xloops)
    : "0" (xloops), "r" (cpu_data[_smp_processor_id()].loops_per_jiffy)
    : "macl", "mach");
    __delay(xloops * HZ);
    }

    void __udelay(unsigned long usecs)
    diff -U10 -urpN linux-2.6.12.org/arch/sh64/lib/udelay.c linux-2.6.12.delay/arch/sh64/lib/udelay.c
    --- linux-2.6.12.org/arch/sh64/lib/udelay.c Tue Oct 19 00:53:46 2004
    +++ linux-2.6.12.delay/arch/sh64/lib/udelay.c Thu Jun 30 22:46:11 2005
    @@ -29,32 +29,21 @@ void __delay(int loops)
    long long dummy;
    __asm__ __volatile__("gettr tr0, %1\n\t"
    "pta $+4, tr0\n\t"
    "addi %0, -1, %0\n\t"
    "bne %0, r63, tr0\n\t"
    "ptabs %1, tr0\n\t":"=r"(loops),
    "=r"(dummy)
    :"0"(loops));
    }

    -void __udelay(unsigned long long usecs, unsigned long lpj)
    +void __udelay(unsigned long long usecs)
    {
    - usecs *= (((unsigned long long) HZ << 32) / 1000000) * lpj;
    + usecs *= (((unsigned long long) HZ << 32) / 1000000) * loops_per_jiffy;
    __delay((long long) usecs >> 32);
    }

    -void __ndelay(unsigned long long nsecs, unsigned long lpj)
    +void __ndelay(unsigned long long nsecs)
    {
    - nsecs *= (((unsigned long long) HZ << 32) / 1000000000) * lpj;
    + nsecs *= (((unsigned long long) HZ << 32) / 1000000000) * loops_per_jiffy;
    __delay((long long) nsecs >> 32);
    }
    -
    -void udelay(unsigned long usecs)
    -{
    - __udelay(usecs, loops_per_jiffy);
    -}
    -
    -void ndelay(unsigned long nsecs)
    -{
    - __ndelay(nsecs, loops_per_jiffy);
    -}
    -
    diff -U10 -urpN linux-2.6.12.org/arch/sparc/kernel/entry.S linux-2.6.12.delay/arch/sparc/kernel/entry.S
    --- linux-2.6.12.org/arch/sparc/kernel/entry.S Thu Feb 3 11:39:08 2005
    +++ linux-2.6.12.delay/arch/sparc/kernel/entry.S Thu Jun 30 19:56:48 2005
    @@ -1789,40 +1789,40 @@ fpload:
    ldd [%o0 + 0x50], %f20
    ldd [%o0 + 0x58], %f22
    ldd [%o0 + 0x60], %f24
    ldd [%o0 + 0x68], %f26
    ldd [%o0 + 0x70], %f28
    ldd [%o0 + 0x78], %f30
    ld [%o1], %fsr
    retl
    nop

    - /* __ndelay and __udelay take two arguments:
    + /* ___ndelay and ___udelay take two arguments:
    * 0 - nsecs or usecs to delay
    * 1 - per_cpu udelay_val (loops per jiffy)
    *
    * Note that ndelay gives HZ times higher resolution but has a 10ms
    * limit. udelay can handle up to 1s.
    */
    - .globl __ndelay
    -__ndelay:
    + .globl ___ndelay
    +___ndelay:
    save %sp, -STACKFRAME_SZ, %sp
    mov %i0, %o0
    call .umul
    mov 0x1ad, %o1 ! 2**32 / (1 000 000 000 / HZ)
    call .umul
    mov %i1, %o1 ! udelay_val
    ba delay_continue
    mov %o1, %o0 ! >>32 later for better resolution

    - .globl __udelay
    -__udelay:
    + .globl ___udelay
    +___udelay:
    save %sp, -STACKFRAME_SZ, %sp
    mov %i0, %o0
    sethi %hi(0x10c6), %o1
    call .umul
    or %o1, %lo(0x10c6), %o1 ! 2**32 / 1 000 000
    call .umul
    mov %i1, %o1 ! udelay_val
    call .umul
    mov HZ, %o0 ! >>32 earlier for wider range

    diff -U10 -urpN linux-2.6.12.org/arch/sparc/kernel/sparc_ksyms.c linux-2.6.12.delay/arch/sparc/kernel/sparc_ksyms.c
    --- linux-2.6.12.org/arch/sparc/kernel/sparc_ksyms.c Sun Jun 19 16:09:59 2005
    +++ linux-2.6.12.delay/arch/sparc/kernel/sparc_ksyms.c Thu Jun 30 19:57:13 2005
    @@ -157,22 +157,22 @@ EXPORT_SYMBOL(synchronize_irq);

    /* Misc SMP information */
    EXPORT_SYMBOL(__cpu_number_map);
    EXPORT_SYMBOL(__cpu_logical_map);

    /* CPU online map and active count. */
    EXPORT_SYMBOL(cpu_online_map);
    EXPORT_SYMBOL(phys_cpu_present_map);
    #endif

    -EXPORT_SYMBOL(__udelay);
    -EXPORT_SYMBOL(__ndelay);
    +EXPORT_SYMBOL(___udelay);
    +EXPORT_SYMBOL(___ndelay);
    EXPORT_SYMBOL(rtc_lock);
    EXPORT_SYMBOL(mostek_lock);
    EXPORT_SYMBOL(mstk48t02_regs);
    #ifdef CONFIG_SUN_AUXIO
    EXPORT_SYMBOL(set_auxio);
    EXPORT_SYMBOL(get_auxio);
    #endif
    EXPORT_SYMBOL(request_fast_irq);
    EXPORT_SYMBOL(io_remap_page_range);
    EXPORT_SYMBOL(io_remap_pfn_range);
    diff -U10 -urpN linux-2.6.12.org/arch/sparc64/kernel/sparc64_ksyms.c linux-2.6.12.delay/arch/sparc64/kernel/sparc64_ksyms.c
    --- linux-2.6.12.org/arch/sparc64/kernel/sparc64_ksyms.c Sun Jun 19 16:10:00 2005
    +++ linux-2.6.12.delay/arch/sparc64/kernel/sparc64_ksyms.c Thu Jun 30 20:35:43 2005
    @@ -393,21 +393,20 @@ EXPORT_SYMBOL(__ret_efault);
    /* No version information on these, as gcc produces such symbols. */
    EXPORT_SYMBOL(memcmp);
    EXPORT_SYMBOL(memcpy);
    EXPORT_SYMBOL(memset);
    EXPORT_SYMBOL(memmove);
    EXPORT_SYMBOL(strncmp);

    /* Delay routines. */
    EXPORT_SYMBOL(__udelay);
    EXPORT_SYMBOL(__ndelay);
    -EXPORT_SYMBOL(__const_udelay);
    EXPORT_SYMBOL(__delay);

    void VISenter(void);
    /* RAID code needs this */
    EXPORT_SYMBOL(VISenter);

    /* for input/keybdev */
    EXPORT_SYMBOL(sun_do_break);
    EXPORT_SYMBOL(serial_console);
    EXPORT_SYMBOL(stop_a_enabled);
    diff -U10 -urpN linux-2.6.12.org/arch/sparc64/lib/delay.c linux-2.6.12.delay/arch/sparc64/lib/delay.c
    --- linux-2.6.12.org/arch/sparc64/lib/delay.c Thu Mar 3 09:30:22 2005
    +++ linux-2.6.12.delay/arch/sparc64/lib/delay.c Thu Jun 30 20:35:40 2005
    @@ -20,21 +20,21 @@ void __delay(unsigned long loops)
    " subcc %0, 1, %0\n"
    : "=&r" (loops)
    : "0" (loops)
    : "cc");
    }

    /* We used to multiply by HZ after shifting down by 32 bits
    * but that runs into problems for higher values of HZ and
    * slow cpus.
    */
    -void __const_udelay(unsigned long n)
    +static void __const_udelay(unsigned long n)
    {
    n *= 4;

    n *= (cpu_data(_smp_processor_id()).udelay_val * (HZ/4));
    n >>= 32;

    __delay(n + 1);
    }

    void __udelay(unsigned long n)
    diff -U10 -urpN linux-2.6.12.org/arch/um/sys-i386/delay.c linux-2.6.12.delay/arch/um/sys-i386/delay.c
    --- linux-2.6.12.org/arch/um/sys-i386/delay.c Sun Jun 19 16:10:01 2005
    +++ linux-2.6.12.delay/arch/um/sys-i386/delay.c Thu Jun 30 22:43:14 2005
    @@ -20,21 +20,10 @@ void __delay(unsigned long time)
    void __udelay(unsigned long usecs)
    {
    int i, n;

    n = (loops_per_jiffy * HZ * usecs) / MILLION;
    for(i=0;i<n;i++)
    cpu_relax();
    }

    EXPORT_SYMBOL(__udelay);
    -
    -void __const_udelay(unsigned long usecs)
    -{
    - int i, n;
    -
    - n = (loops_per_jiffy * HZ * usecs) / MILLION;
    - for(i=0;i<n;i++)
    - cpu_relax();
    -}
    -
    -EXPORT_SYMBOL(__const_udelay);
    diff -U10 -urpN linux-2.6.12.org/arch/um/sys-i386/ksyms.c linux-2.6.12.delay/arch/um/sys-i386/ksyms.c
    --- linux-2.6.12.org/arch/um/sys-i386/ksyms.c Sun Jun 19 16:10:01 2005
    +++ linux-2.6.12.delay/arch/um/sys-i386/ksyms.c Thu Jun 30 22:43:50 2005
    @@ -10,12 +10,11 @@

    EXPORT_SYMBOL(__down_failed);
    EXPORT_SYMBOL(__down_failed_interruptible);
    EXPORT_SYMBOL(__down_failed_trylock);
    EXPORT_SYMBOL(__up_wakeup);

    /* Networking helper routines. */
    EXPORT_SYMBOL(csum_partial);

    /* delay core functions */
    -EXPORT_SYMBOL(__const_udelay);
    EXPORT_SYMBOL(__udelay);
    diff -U10 -urpN linux-2.6.12.org/arch/um/sys-x86_64/delay.c linux-2.6.12.delay/arch/um/sys-x86_64/delay.c
    --- linux-2.6.12.org/arch/um/sys-x86_64/delay.c Sun Jun 19 16:10:01 2005
    +++ linux-2.6.12.delay/arch/um/sys-x86_64/delay.c Thu Jun 30 22:43:27 2005
    @@ -21,21 +21,10 @@ void __delay(unsigned long loops)
    void __udelay(unsigned long usecs)
    {
    unsigned long i, n;

    n = (loops_per_jiffy * HZ * usecs) / MILLION;
    for(i=0;i<n;i++)
    cpu_relax();
    }

    EXPORT_SYMBOL(__udelay);
    -
    -void __const_udelay(unsigned long usecs)
    -{
    - unsigned long i, n;
    -
    - n = (loops_per_jiffy * HZ * usecs) / MILLION;
    - for(i=0;i<n;i++)
    - cpu_relax();
    -}
    -
    -EXPORT_SYMBOL(__const_udelay);
    diff -U10 -urpN linux-2.6.12.org/arch/x86_64/kernel/x8664_ksyms.c linux-2.6.12.delay/arch/x86_64/kernel/x8664_ksyms.c
    --- linux-2.6.12.org/arch/x86_64/kernel/x8664_ksyms.c Sun Jun 19 16:10:03 2005
    +++ linux-2.6.12.delay/arch/x86_64/kernel/x8664_ksyms.c Thu Jun 30 20:37:34 2005
    @@ -66,21 +66,20 @@ EXPORT_SYMBOL(__down_failed);
    EXPORT_SYMBOL(__down_failed_interruptible);
    EXPORT_SYMBOL(__down_failed_trylock);
    EXPORT_SYMBOL(__up_wakeup);
    /* Networking helper routines. */
    EXPORT_SYMBOL(csum_partial_copy_nocheck);
    EXPORT_SYMBOL(ip_compute_csum);
    /* Delay loops */
    EXPORT_SYMBOL(__udelay);
    EXPORT_SYMBOL(__ndelay);
    EXPORT_SYMBOL(__delay);
    -EXPORT_SYMBOL(__const_udelay);

    EXPORT_SYMBOL(__get_user_1);
    EXPORT_SYMBOL(__get_user_2);
    EXPORT_SYMBOL(__get_user_4);
    EXPORT_SYMBOL(__get_user_8);
    EXPORT_SYMBOL(__put_user_1);
    EXPORT_SYMBOL(__put_user_2);
    EXPORT_SYMBOL(__put_user_4);
    EXPORT_SYMBOL(__put_user_8);

    diff -U10 -urpN linux-2.6.12.org/arch/x86_64/lib/delay.c linux-2.6.12.delay/arch/x86_64/lib/delay.c
    --- linux-2.6.12.org/arch/x86_64/lib/delay.c Sun Jun 19 16:10:03 2005
    +++ linux-2.6.12.delay/arch/x86_64/lib/delay.c Thu Jun 30 20:35:15 2005
    @@ -25,21 +25,21 @@ void __delay(unsigned long loops)

    rdtscl(bclock);
    do
    {
    rep_nop();
    rdtscl(now);
    }
    while((now-bclock) < loops);
    }

    -inline void __const_udelay(unsigned long xloops)
    +static inline void __const_udelay(unsigned long xloops)
    {
    __delay(((xloops * cpu_data[_smp_processor_id()].loops_per_jiffy) >> 32) * HZ);
    }

    void __udelay(unsigned long usecs)
    {
    __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */
    }

    void __ndelay(unsigned long nsecs)
    diff -U10 -urpN linux-2.6.12.org/include/asm-alpha/delay.h linux-2.6.12.delay/include/asm-alpha/delay.h
    --- linux-2.6.12.org/include/asm-alpha/delay.h Tue Oct 19 00:53:51 2004
    +++ linux-2.6.12.delay/include/asm-alpha/delay.h Thu Jun 30 19:58:07 2005
    @@ -1,10 +1,9 @@
    #ifndef __ALPHA_DELAY_H
    #define __ALPHA_DELAY_H

    extern void __delay(int loops);
    -extern void udelay(unsigned long usecs);
    -
    -extern void ndelay(unsigned long nsecs);
    -#define ndelay ndelay
    +extern void __udelay(unsigned long usecs);
    +extern void __ndelay(unsigned long nsecs);
    +#define __ndelay(n) __ndelay(n)

    #endif /* defined(__ALPHA_DELAY_H) */
    diff -U10 -urpN linux-2.6.12.org/include/asm-arm/delay.h linux-2.6.12.delay/include/asm-arm/delay.h
    --- linux-2.6.12.org/include/asm-arm/delay.h Thu Feb 3 11:40:05 2005
    +++ linux-2.6.12.delay/include/asm-arm/delay.h Thu Jun 30 20:24:49 2005
    @@ -1,42 +1,16 @@
    /*
    * Copyright (C) 1995-2004 Russell King
    *
    * Delay routines, using a pre-computed "loops_per_second" value.
    */
    #ifndef __ASM_ARM_DELAY_H
    #define __ASM_ARM_DELAY_H

    extern void __delay(int loops);

    -/*
    - * This function intentionally does not exist; if you see references to
    - * it, it means that you're calling udelay() with an out of range value.
    - *
    - * With currently imposed limits, this means that we support a max delay
    - * of 2000us and 671 bogomips
    - */
    -extern void __bad_udelay(void);
    -
    -/*
    - * division by multiplication: you don't have to worry about
    - * loss of precision.
    - *
    - * Use only for very small delays ( < 1 msec). Should probably use a
    - * lookup table, really, as the multiplications take much too long with
    - * short delays. This is a "reasonable" implementation, though (and the
    - * first constant multiplications gets optimized away if the delay is
    - * a constant)
    - */
    extern void __udelay(unsigned long usecs);
    -extern void __const_udelay(unsigned long);

    #define MAX_UDELAY_MS 2
    -
    -#define udelay(n) \
    - (__builtin_constant_p(n) ? \
    - ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() : \
    - __const_udelay((n) * 0x68dbul)) : \
    - __udelay(n))

    #endif /* defined(_ARM_DELAY_H) */

    diff -U10 -urpN linux-2.6.12.org/include/asm-arm26/delay.h linux-2.6.12.delay/include/asm-arm26/delay.h
    --- linux-2.6.12.org/include/asm-arm26/delay.h Tue Oct 19 00:53:06 2004
    +++ linux-2.6.12.delay/include/asm-arm26/delay.h Thu Jun 30 19:38:27 2005
    @@ -14,21 +14,21 @@ extern void __delay(int loops);
    * loss of precision.
    *
    * Use only for very small delays ( < 1 msec). Should probably use a
    * lookup table, really, as the multiplications take much too long with
    * short delays. This is a "reasonable" implementation, though (and the
    * first constant multiplications gets optimized away if the delay is
    * a constant)
    *
    * FIXME - lets improve it then...
    */
    -extern void udelay(unsigned long usecs);
    +extern void __udelay(unsigned long usecs);

    static inline unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
    {
    return a * b / c;
    }



    #endif /* defined(_ARM_DELAY_H) */

    diff -U10 -urpN linux-2.6.12.org/include/asm-cris/delay.h linux-2.6.12.delay/include/asm-cris/delay.h
    --- linux-2.6.12.org/include/asm-cris/delay.h Tue Oct 19 00:55:23 2004
    +++ linux-2.6.12.delay/include/asm-cris/delay.h Thu Jun 30 19:33:41 2005
    @@ -6,19 +6,19 @@
    *
    * Delay routines, using a pre-computed "loops_per_second" value.
    */

    #include <asm/arch/delay.h>

    /* Use only for very small delays ( < 1 msec). */

    extern unsigned long loops_per_usec; /* arch/cris/mm/init.c */

    -extern __inline__ void udelay(unsigned long usecs)
    +extern __inline__ void __udelay(unsigned long usecs)
    {
    __delay(usecs * loops_per_usec);
    }

    #endif /* defined(_CRIS_DELAY_H) */



    diff -U10 -urpN linux-2.6.12.org/include/asm-frv/delay.h linux-2.6.12.delay/include/asm-frv/delay.h
    --- linux-2.6.12.org/include/asm-frv/delay.h Thu Mar 3 09:31:07 2005
    +++ linux-2.6.12.delay/include/asm-frv/delay.h Thu Jun 30 19:22:31 2005
    @@ -33,18 +33,18 @@ static inline void __delay(unsigned long
    /*
    * Use only for very small delays ( < 1 msec). Should probably use a
    * lookup table, really, as the multiplications take much too long with
    * short delays. This is a "reasonable" implementation, though (and the
    * first constant multiplications gets optimized away if the delay is
    * a constant)
    */

    extern unsigned long loops_per_jiffy;

    -static inline void udelay(unsigned long usecs)
    +static inline void __udelay(unsigned long usecs)
    {
    __delay(usecs * __delay_loops_MHz);
    }

    -#define ndelay(n) udelay((n) * 5)
    +//BOGUS! #define ndelay(n) udelay((n) * 5)

    #endif /* _ASM_DELAY_H */
    diff -U10 -urpN linux-2.6.12.org/include/asm-h8300/delay.h linux-2.6.12.delay/include/asm-h8300/delay.h
    --- linux-2.6.12.org/include/asm-h8300/delay.h Thu Feb 3 11:40:05 2005
    +++ linux-2.6.12.delay/include/asm-h8300/delay.h Thu Jun 30 19:38:09 2005
    @@ -20,19 +20,19 @@ extern __inline__ void __delay(unsigned
    /*
    * Use only for very small delays ( < 1 msec). Should probably use a
    * lookup table, really, as the multiplications take much too long with
    * short delays. This is a "reasonable" implementation, though (and the
    * first constant multiplications gets optimized away if the delay is
    * a constant)
    */

    extern unsigned long loops_per_jiffy;

    -extern __inline__ void udelay(unsigned long usecs)
    +extern __inline__ void __udelay(unsigned long usecs)
    {
    usecs *= 4295; /* 2**32 / 1000000 */
    usecs /= (loops_per_jiffy*HZ);
    if (usecs)
    __delay(usecs);
    }

    #endif /* _H8300_DELAY_H */
    diff -U10 -urpN linux-2.6.12.org/include/asm-i386/delay.h linux-2.6.12.delay/include/asm-i386/delay.h
    --- linux-2.6.12.org/include/asm-i386/delay.h Tue Oct 19 00:53:05 2004
    +++ linux-2.6.12.delay/include/asm-i386/delay.h Thu Jun 30 20:34:21 2005
    @@ -1,26 +1,15 @@
    #ifndef _I386_DELAY_H
    #define _I386_DELAY_H

    /*
    * Copyright (C) 1993 Linus Torvalds
    *
    * Delay routines calling functions in arch/i386/lib/delay.c
    */

    -extern void __bad_udelay(void);
    -extern void __bad_ndelay(void);
    -
    extern void __udelay(unsigned long usecs);
    extern void __ndelay(unsigned long nsecs);
    -extern void __const_udelay(unsigned long usecs);
    +#define __ndelay(n) __ndelay(n)
    extern void __delay(unsigned long loops);
    -
    -#define udelay(n) (__builtin_constant_p(n) ? \
    - ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
    - __udelay(n))
    -
    -#define ndelay(n) (__builtin_constant_p(n) ? \
    - ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
    - __ndelay(n))

    #endif /* defined(_I386_DELAY_H) */
    diff -U10 -urpN linux-2.6.12.org/include/asm-m32r/delay.h linux-2.6.12.delay/include/asm-m32r/delay.h
    --- linux-2.6.12.org/include/asm-m32r/delay.h Tue Oct 19 00:53:45 2004
    +++ linux-2.6.12.delay/include/asm-m32r/delay.h Thu Jun 30 20:32:48 2005
    @@ -2,27 +2,16 @@
    #define _ASM_M32R_DELAY_H

    /* $Id$ */

    /*
    * Copyright (C) 1993 Linus Torvalds
    *
    * Delay routines calling functions in arch/m32r/lib/delay.c
    */

    -extern void __bad_udelay(void);
    -extern void __bad_ndelay(void);
    -
    extern void __udelay(unsigned long usecs);
    extern void __ndelay(unsigned long nsecs);
    -extern void __const_udelay(unsigned long usecs);
    +#define __ndelay(n) __ndelay(n)
    extern void __delay(unsigned long loops);
    -
    -#define udelay(n) (__builtin_constant_p(n) ? \
    - ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
    - __udelay(n))
    -
    -#define ndelay(n) (__builtin_constant_p(n) ? \
    - ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
    - __ndelay(n))

    #endif /* _ASM_M32R_DELAY_H */
    diff -U10 -urpN linux-2.6.12.org/include/asm-m68k/delay.h linux-2.6.12.delay/include/asm-m68k/delay.h
    --- linux-2.6.12.org/include/asm-m68k/delay.h Tue Oct 19 00:55:28 2004
    +++ linux-2.6.12.delay/include/asm-m68k/delay.h Thu Jun 30 20:29:04 2005
    @@ -8,22 +8,20 @@
    *
    * Delay routines, using a pre-computed "loops_per_jiffy" value.
    */

    static inline void __delay(unsigned long loops)
    {
    __asm__ __volatile__ ("1: subql #1,%0; jcc 1b"
    : "=d" (loops) : "0" (loops));
    }

    -extern void __bad_udelay(void);
    -
    /*
    * Use only for very small delays ( < 1 msec). Should probably use a
    * lookup table, really, as the multiplications take much too long with
    * short delays. This is a "reasonable" implementation, though (and the
    * first constant multiplications gets optimized away if the delay is
    * a constant)
    */
    static inline void __const_udelay(unsigned long xloops)
    {
    unsigned long tmp;
    @@ -31,24 +29,20 @@ static inline void __const_udelay(unsign
    __asm__ ("mulul %2,%0:%1"
    : "=d" (xloops), "=d" (tmp)
    : "d" (xloops), "1" (loops_per_jiffy));
    __delay(xloops * HZ);
    }

    static inline void __udelay(unsigned long usecs)
    {
    __const_udelay(usecs * 4295); /* 2**32 / 1000000 */
    }
    -
    -#define udelay(n) (__builtin_constant_p(n) ? \
    - ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 4295)) : \
    - __udelay(n))

    static inline unsigned long muldiv(unsigned long a, unsigned long b,
    unsigned long c)
    {
    unsigned long tmp;

    __asm__ ("mulul %2,%0:%1; divul %3,%0:%1"
    : "=d" (tmp), "=d" (a)
    : "d" (b), "d" (c), "1" (a));
    return a;
    diff -U10 -urpN linux-2.6.12.org/include/asm-m68knommu/delay.h linux-2.6.12.delay/include/asm-m68knommu/delay.h
    --- linux-2.6.12.org/include/asm-m68knommu/delay.h Thu Feb 3 11:40:08 2005
    +++ linux-2.6.12.delay/include/asm-m68knommu/delay.h Thu Jun 30 20:27:54 2005
    @@ -1,76 +1,13 @@
    #ifndef _M68KNOMMU_DELAY_H
    #define _M68KNOMMU_DELAY_H

    /*
    * Copyright (C) 1994 Hamish Macdonald
    * Copyright (C) 2004 Greg Ungerer <gerg@snapgear.com>
    */

    #include <asm/param.h>

    -extern __inline__ void __delay(unsigned long loops)
    -{
    -#if defined(CONFIG_COLDFIRE)
    - /* The coldfire runs this loop at significantly different speeds
    - * depending upon long word alignment or not. We'll pad it to
    - * long word alignment which is the faster version.
    - * The 0x4a8e is of course a 'tstl %fp' instruction. This is better
    - * than using a NOP (0x4e71) instruction because it executes in one
    - * cycle not three and doesn't allow for an arbitary delay waiting
    - * for bus cycles to finish. Also fp/a6 isn't likely to cause a
    - * stall waiting for the register to become valid if such is added
    - * to the coldfire at some stage.
    - */
    - __asm__ __volatile__ ( ".balignw 4, 0x4a8e\n\t"
    - "1: subql #1, %0\n\t"
    - "jcc 1b"
    - : "=d" (loops) : "0" (loops));
    -#else
    - __asm__ __volatile__ ( "1: subql #1, %0\n\t"
    - "jcc 1b"
    - : "=d" (loops) : "0" (loops));
    -#endif
    -}
    -
    -/*
    - * Ideally we use a 32*32->64 multiply to calculate the number of
    - * loop iterations, but the older standard 68k and ColdFire do not
    - * have this instruction. So for them we have a clsoe approximation
    - * loop using 32*32->32 multiplies only. This calculation based on
    - * the ARM version of delay.
    - *
    - * We want to implement:
    - *
    - * loops = (usecs * 0x10c6 * HZ * loops_per_jiffy) / 2^32
    - */
    -
    -#define HZSCALE (268435456 / (1000000/HZ))
    -
    -extern unsigned long loops_per_jiffy;
    -
    -extern __inline__ void _udelay(unsigned long usecs)
    -{
    -#if defined(CONFIG_M68328) || defined(CONFIG_M68EZ328) || \
    - defined(CONFIG_M68VZ328) || defined(CONFIG_M68360) || \
    - defined(CONFIG_COLDFIRE)
    - __delay((((usecs * HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6);
    -#else
    - unsigned long tmp;
    -
    - usecs *= 4295; /* 2**32 / 1000000 */
    - __asm__ ("mulul %2,%0:%1"
    - : "=d" (usecs), "=d" (tmp)
    - : "d" (usecs), "1" (loops_per_jiffy*HZ));
    - __delay(usecs);
    -#endif
    -}
    -
    -/*
    - * Moved the udelay() function into library code, no longer inlined.
    - * I had to change the algorithm because we are overflowing now on
    - * the faster ColdFire parts. The code is a little biger, so it makes
    - * sense to library it.
    - */
    -extern void udelay(unsigned long usecs);
    +extern void __udelay(unsigned long usecs);

    #endif /* defined(_M68KNOMMU_DELAY_H) */
    diff -U10 -urpN linux-2.6.12.org/include/asm-mips/delay.h linux-2.6.12.delay/include/asm-mips/delay.h
    --- linux-2.6.12.org/include/asm-mips/delay.h Thu Feb 3 11:40:09 2005
    +++ linux-2.6.12.delay/include/asm-mips/delay.h Thu Jun 30 20:29:34 2005
    @@ -42,52 +42,50 @@ static inline void __delay(unsigned long
    * Division by multiplication: you don't have to worry about
    * loss of precision.
    *
    * Use only for very small delays ( < 1 msec). Should probably use a
    * lookup table, really, as the multiplications take much too long with
    * short delays. This is a "reasonable" implementation, though (and the
    * first constant multiplications gets optimized away if the delay is
    * a constant)
    */

    -static inline void __udelay(unsigned long usecs, unsigned long lpj)
    +static inline void __udelay(unsigned long usecs)
    {
    unsigned long lo;

    +#ifdef CONFIG_SMP
    + unsigned long loops_per_jiffy = cpu_data[smp_processor_id()].udelay_val;
    +#else
    + /* using global one */
    +#endif
    +
    /*
    * The common rates of 1000 and 128 are rounded wrongly by the
    * catchall case for 64-bit. Excessive precission? Probably ...
    */
    #if defined(CONFIG_MIPS64) && (HZ == 128)
    usecs *= 0x0008637bd05af6c7UL; /* 2**64 / (1000000 / HZ) */
    #elif defined(CONFIG_MIPS64) && (HZ == 1000)
    usecs *= 0x004189374BC6A7f0UL; /* 2**64 / (1000000 / HZ) */
    #elif defined(CONFIG_MIPS64)
    usecs *= (0x8000000000000000UL / (500000 / HZ));
    #else /* 32-bit junk follows here */
    usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) +
    0x80000000ULL) >> 32);
    #endif

    if (sizeof(long) == 4)
    __asm__("multu\t%2, %3"
    : "=h" (usecs), "=l" (lo)
    - : "r" (usecs), "r" (lpj)
    + : "r" (usecs), "r" (loops_per_jiffy)
    : GCC_REG_ACCUM);
    else if (sizeof(long) == 8)
    __asm__("dmultu\t%2, %3"
    : "=h" (usecs), "=l" (lo)
    - : "r" (usecs), "r" (lpj)
    + : "r" (usecs), "r" (loops_per_jiffy)
    : GCC_REG_ACCUM);

    __delay(usecs);
    }
    -
    -#ifdef CONFIG_SMP
    -#define __udelay_val cpu_data[smp_processor_id()].udelay_val
    -#else
    -#define __udelay_val loops_per_jiffy
    -#endif
    -
    -#define udelay(usecs) __udelay((usecs),__udelay_val)

    #endif /* _ASM_DELAY_H */
    diff -U10 -urpN linux-2.6.12.org/include/asm-parisc/delay.h linux-2.6.12.delay/include/asm-parisc/delay.h
    --- linux-2.6.12.org/include/asm-parisc/delay.h Tue Oct 19 00:54:08 2004
    +++ linux-2.6.12.delay/include/asm-parisc/delay.h Thu Jun 30 20:28:18 2005
    @@ -31,13 +31,11 @@ static __inline__ void __cr16_delay(unsi

    start = mfctl(16);
    while ((mfctl(16) - start) < clocks)
    ;
    }

    static __inline__ void __udelay(unsigned long usecs) {
    __cr16_delay(usecs * ((unsigned long)boot_cpu_data.cpu_hz / 1000000UL));
    }

    -#define udelay(n) __udelay(n)
    -
    #endif /* defined(_PARISC_DELAY_H) */
    diff -U10 -urpN linux-2.6.12.org/include/asm-ppc/delay.h linux-2.6.12.delay/include/asm-ppc/delay.h
    --- linux-2.6.12.org/include/asm-ppc/delay.h Tue Oct 19 00:54:39 2004
    +++ linux-2.6.12.delay/include/asm-ppc/delay.h Thu Jun 30 20:22:55 2005
    @@ -43,24 +43,14 @@ extern __inline__ void __udelay(unsigned
    }

    extern __inline__ void __ndelay(unsigned int x)
    {
    unsigned int loops;

    __asm__("mulhwu %0,%1,%2" : "=r" (loops) :
    "r" (x), "r" (loops_per_jiffy * 5));
    __delay(loops);
    }
    -
    -extern void __bad_udelay(void); /* deliberately undefined */
    -extern void __bad_ndelay(void); /* deliberately undefined */
    -
    -#define udelay(n) (__builtin_constant_p(n)? \
    - ((n) > __MAX_UDELAY? __bad_udelay(): __udelay((n) * (19 * HZ))) : \
    - __udelay((n) * (19 * HZ)))
    -
    -#define ndelay(n) (__builtin_constant_p(n)? \
    - ((n) > __MAX_NDELAY? __bad_ndelay(): __ndelay((n) * HZ)) : \
    - __ndelay((n) * HZ))
    +#define __ndelay(n) __ndelay(n)

    #endif /* defined(_PPC_DELAY_H) */
    #endif /* __KERNEL__ */
    diff -U10 -urpN linux-2.6.12.org/include/asm-ppc64/delay.h linux-2.6.12.delay/include/asm-ppc64/delay.h
    --- linux-2.6.12.org/include/asm-ppc64/delay.h Tue Oct 19 00:53:06 2004
    +++ linux-2.6.12.delay/include/asm-ppc64/delay.h Thu Jun 30 19:37:43 2005
    @@ -31,18 +31,18 @@ static inline unsigned long __get_tb(voi
    static inline void __delay(unsigned long loops)
    {
    unsigned long start = __get_tb();

    while((__get_tb()-start) < loops)
    __HMT_low();
    __HMT_medium();
    __barrier();
    }

    -static inline void udelay(unsigned long usecs)
    +static inline void __udelay(unsigned long usecs)
    {
    unsigned long loops = tb_ticks_per_usec * usecs;

    __delay(loops);
    }

    #endif /* _PPC64_DELAY_H */
    diff -U10 -urpN linux-2.6.12.org/include/asm-s390/delay.h linux-2.6.12.delay/include/asm-s390/delay.h
    --- linux-2.6.12.org/include/asm-s390/delay.h Tue Oct 19 00:54:39 2004
    +++ linux-2.6.12.delay/include/asm-s390/delay.h Thu Jun 30 20:25:11 2005
    @@ -10,13 +10,11 @@
    *
    * Delay routines calling functions in arch/s390/lib/delay.c
    */

    #ifndef _S390_DELAY_H
    #define _S390_DELAY_H

    extern void __udelay(unsigned long usecs);
    extern void __delay(unsigned long loops);

    -#define udelay(n) __udelay(n)
    -
    #endif /* defined(_S390_DELAY_H) */
    diff -U10 -urpN linux-2.6.12.org/include/asm-sh/delay.h linux-2.6.12.delay/include/asm-sh/delay.h
    --- linux-2.6.12.org/include/asm-sh/delay.h Tue Oct 19 00:55:24 2004
    +++ linux-2.6.12.delay/include/asm-sh/delay.h Thu Jun 30 20:37:05 2005
    @@ -1,27 +1,15 @@
    #ifndef __ASM_SH_DELAY_H
    #define __ASM_SH_DELAY_H

    /*
    * Copyright (C) 1993 Linus Torvalds
    *
    * Delay routines calling functions in arch/sh/lib/delay.c
    */

    -extern void __bad_udelay(void);
    -extern void __bad_ndelay(void);
    -
    extern void __udelay(unsigned long usecs);
    extern void __ndelay(unsigned long nsecs);
    -extern void __const_udelay(unsigned long usecs);
    +#define __ndelay(n) __ndelay(n)
    extern void __delay(unsigned long loops);
    -
    -#define udelay(n) (__builtin_constant_p(n) ? \
    - ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c6ul)) : \
    - __udelay(n))
    -
    -
    -#define ndelay(n) (__builtin_constant_p(n) ? \
    - ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
    - __ndelay(n))

    #endif /* __ASM_SH_DELAY_H */
    diff -U10 -urpN linux-2.6.12.org/include/asm-sh64/delay.h linux-2.6.12.delay/include/asm-sh64/delay.h
    --- linux-2.6.12.org/include/asm-sh64/delay.h Tue Oct 19 00:54:37 2004
    +++ linux-2.6.12.delay/include/asm-sh64/delay.h Thu Jun 30 20:25:04 2005
    @@ -1,11 +1,10 @@
    #ifndef __ASM_SH64_DELAY_H
    #define __ASM_SH64_DELAY_H

    extern void __delay(int loops);
    -extern void __udelay(unsigned long long usecs, unsigned long lpj);
    -extern void __ndelay(unsigned long long nsecs, unsigned long lpj);
    -extern void udelay(unsigned long usecs);
    -extern void ndelay(unsigned long nsecs);
    +extern void __udelay(unsigned long long usecs);
    +extern void __ndelay(unsigned long long nsecs);
    +#define __ndelay(n) __ndelay(n)

    #endif /* __ASM_SH64_DELAY_H */

    diff -U10 -urpN linux-2.6.12.org/include/asm-sparc/delay.h linux-2.6.12.delay/include/asm-sparc/delay.h
    --- linux-2.6.12.org/include/asm-sparc/delay.h Tue Oct 19 00:53:45 2004
    +++ linux-2.6.12.delay/include/asm-sparc/delay.h Thu Jun 30 19:57:52 2005
    @@ -14,22 +14,22 @@ extern __inline__ void __delay(unsigned
    {
    __asm__ __volatile__("cmp %0, 0\n\t"
    "1: bne 1b\n\t"
    "subcc %0, 1, %0\n" :
    "=&r" (loops) :
    "0" (loops) :
    "cc");
    }

    /* This is too messy with inline asm on the Sparc. */
    -extern void __udelay(unsigned long usecs, unsigned long lpj);
    -extern void __ndelay(unsigned long nsecs, unsigned long lpj);
    +extern void ___udelay(unsigned long usecs, unsigned long lpj);
    +extern void ___ndelay(unsigned long nsecs, unsigned long lpj);

    #ifdef CONFIG_SMP
    #define __udelay_val cpu_data(smp_processor_id()).udelay_val
    #else /* SMP */
    #define __udelay_val loops_per_jiffy
    #endif /* SMP */
    -#define udelay(__usecs) __udelay(__usecs, __udelay_val)
    -#define ndelay(__nsecs) __ndelay(__nsecs, __udelay_val)
    +#define __udelay(__usecs) ___udelay(__usecs, __udelay_val)
    +#define __ndelay(__nsecs) ___ndelay(__nsecs, __udelay_val)

    #endif /* defined(__SPARC_DELAY_H) */
    diff -U10 -urpN linux-2.6.12.org/include/asm-sparc64/delay.h linux-2.6.12.delay/include/asm-sparc64/delay.h
    --- linux-2.6.12.org/include/asm-sparc64/delay.h Tue Oct 19 00:54:38 2004
    +++ linux-2.6.12.delay/include/asm-sparc64/delay.h Thu Jun 30 20:22:45 2005
    @@ -10,29 +10,17 @@

    #ifndef __SPARC64_DELAY_H
    #define __SPARC64_DELAY_H

    #include <linux/config.h>
    #include <linux/param.h>
    #include <asm/cpudata.h>

    #ifndef __ASSEMBLY__

    -extern void __bad_udelay(void);
    -extern void __bad_ndelay(void);
    -
    extern void __udelay(unsigned long usecs);
    extern void __ndelay(unsigned long nsecs);
    -extern void __const_udelay(unsigned long usecs);
    -extern void __delay(unsigned long loops);
    -
    -#define udelay(n) (__builtin_constant_p(n) ? \
    - ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \
    - __udelay(n))
    -
    -#define ndelay(n) (__builtin_constant_p(n) ? \
    - ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
    - __ndelay(n))
    +#define __ndelay(n) __ndelay(n)

    #endif /* !__ASSEMBLY__ */

    #endif /* defined(__SPARC64_DELAY_H) */
    diff -U10 -urpN linux-2.6.12.org/include/asm-v850/delay.h linux-2.6.12.delay/include/asm-v850/delay.h
    --- linux-2.6.12.org/include/asm-v850/delay.h Tue Oct 19 00:55:24 2004
    +++ linux-2.6.12.delay/include/asm-v850/delay.h Thu Jun 30 19:24:39 2005
    @@ -26,21 +26,21 @@ extern __inline__ void __delay(unsigned
    /*
    * Use only for very small delays ( < 1 msec). Should probably use a
    * lookup table, really, as the multiplications take much too long with
    * short delays. This is a "reasonable" implementation, though (and the
    * first constant multiplications gets optimized away if the delay is
    * a constant)
    */

    extern unsigned long loops_per_jiffy;

    -extern __inline__ void udelay(unsigned long usecs)
    +extern __inline__ void __udelay(unsigned long usecs)
    {
    register unsigned long full_loops, part_loops;

    full_loops = ((usecs * HZ) / 1000000) * loops_per_jiffy;
    usecs %= (1000000 / HZ);
    part_loops = (usecs * HZ * loops_per_jiffy) / 1000000;

    __delay(full_loops + part_loops);
    }

    diff -U10 -urpN linux-2.6.12.org/include/asm-x86_64/delay.h linux-2.6.12.delay/include/asm-x86_64/delay.h
    --- linux-2.6.12.org/include/asm-x86_64/delay.h Tue Oct 19 00:54:32 2004
    +++ linux-2.6.12.delay/include/asm-x86_64/delay.h Thu Jun 30 20:35:55 2005
    @@ -1,27 +1,16 @@
    #ifndef _X8664_DELAY_H
    #define _X8664_DELAY_H

    /*
    * Copyright (C) 1993 Linus Torvalds
    *
    * Delay routines calling functions in arch/x86_64/lib/delay.c
    */

    -extern void __bad_udelay(void);
    -extern void __bad_ndelay(void);

    extern void __udelay(unsigned long usecs);
    extern void __ndelay(unsigned long usecs);
    -extern void __const_udelay(unsigned long usecs);
    +#define __ndelay(n) __ndelay(n)
    extern void __delay(unsigned long loops);
    -
    -#define udelay(n) (__builtin_constant_p(n) ? \
    - ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c6ul)) : \
    - __udelay(n))
    -
    -#define ndelay(n) (__builtin_constant_p(n) ? \
    - ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
    - __ndelay(n))
    -

    #endif /* defined(_X8664_DELAY_H) */
    diff -U10 -urpN linux-2.6.12.org/include/linux/delay.h linux-2.6.12.delay/include/linux/delay.h
    --- linux-2.6.12.org/include/linux/delay.h Thu Mar 3 09:31:14 2005
    +++ linux-2.6.12.delay/include/linux/delay.h Fri Jul 1 00:32:09 2005
    @@ -5,46 +5,67 @@
    * Copyright (C) 1993 Linus Torvalds
    *
    * Delay routines, using a pre-computed "loops_per_jiffy" value.
    */

    extern unsigned long loops_per_jiffy;

    #include <asm/delay.h>

    /*
    - * Using udelay() for intervals greater than a few milliseconds can
    - * risk overflow for high loops_per_jiffy (high bogomips) machines. The
    - * mdelay() provides a wrapper to prevent this. For delays greater
    - * than MAX_UDELAY_MS milliseconds, the wrapper is used. Architecture
    - * specific values can be defined in asm-???/delay.h as an override.
    - * The 2nd mdelay() definition ensures GCC will optimize away the
    - * while loop for the common cases where n <= MAX_UDELAY_MS -- Paul G.
    + * Milli, micro and nanosecond delay loops.
    + *
    + * Duration is artificially capped by MAX_MDELAY_MS,
    + * MAX_UDELAY_MS*1000 and MAX_UDELAY_MS*1000*1000 respectively
    + * in order to catch math underflows etc.
    + * At compile time you get link failure, if you slip through
    + * __builtin_constant_p check, ar run time you get a message and
    + * dump_stack in the log and delay is capped.
    + *
    + * Arch has to provide __udelay(n).
    + * It is guaranteed that __udelay(n) is never called with n > 1024.
    + *
    + * Arch may provide a macro __ndelay(n), else ndelay is 'emulated'
    + * by udelay(n/1000). It is guaranteed that __ndelay() is never
    + * called with n > 64*1024.
    + *
    + * Arch may also override default MAX_MDELAY_MS and MAX_UDELAY_MS.
    */
    +#ifndef MAX_MDELAY_MS
    +#define MAX_MDELAY_MS 5000
    +#endif

    #ifndef MAX_UDELAY_MS
    -#define MAX_UDELAY_MS 5
    +#define MAX_UDELAY_MS 20
    #endif

    -#ifdef notdef
    -#define mdelay(n) (\
    - {unsigned long __ms=(n); while (__ms--) udelay(1000);})
    -#else
    -#define mdelay(n) (\
    - (__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? udelay((n)*1000) : \
    - ({unsigned long __ms=(n); while (__ms--) udelay(1000);}))
    -#endif
    +/* defined nowhere */
    +void BUG_overlong_mdelay(void);
    +void BUG_overlong_udelay(void);
    +void BUG_overlong_ndelay(void);
    +
    +void _mdelay(unsigned int msecs);
    +void _udelay(unsigned int usecs);
    +void _ndelay(unsigned int nsecs);
    +
    +#define mdelay(n) ( \
    + (__builtin_constant_p(n) && (unsigned int)(n)>MAX_MDELAY_MS) ? \
    + BUG_overlong_mdelay() : _mdelay(n))

    -#ifndef ndelay
    -#define ndelay(x) udelay(((x)+999)/1000)
    +#define udelay(n) ( \
    + (__builtin_constant_p(n) && (unsigned int)(n)>MAX_UDELAY_MS*1000) ? \
    + BUG_overlong_udelay() : _udelay(n))
    +
    +#ifndef __ndelay
    +#define __ndelay(x) __udelay(((x)+999)/1000)
    #endif

    +#define ndelay(n) ( \
    + (__builtin_constant_p(n) && (unsigned int)(n)>MAX_UDELAY_MS*1000*1000) ? \
    + BUG_overlong_ndelay() : _ndelay(n))
    +
    void calibrate_delay(void);
    +void ssleep(unsigned int secs);
    void msleep(unsigned int msecs);
    unsigned long msleep_interruptible(unsigned int msecs);
    -
    -static inline void ssleep(unsigned int seconds)
    -{
    - msleep(seconds * 1000);
    -}

    #endif /* defined(_LINUX_DELAY_H) */
    diff -U10 -urpN linux-2.6.12.org/kernel/timer.c linux-2.6.12.delay/kernel/timer.c
    --- linux-2.6.12.org/kernel/timer.c Sun Jun 19 16:11:00 2005
    +++ linux-2.6.12.delay/kernel/timer.c Fri Jul 1 00:05:52 2005
    @@ -26,20 +26,21 @@
    #include <linux/init.h>
    #include <linux/mm.h>
    #include <linux/swap.h>
    #include <linux/notifier.h>
    #include <linux/thread_info.h>
    #include <linux/time.h>
    #include <linux/jiffies.h>
    #include <linux/posix-timers.h>
    #include <linux/cpu.h>
    #include <linux/syscalls.h>
    +#include <linux/delay.h>

    #include <asm/uaccess.h>
    #include <asm/unistd.h>
    #include <asm/div64.h>
    #include <asm/timex.h>
    #include <asm/io.h>

    #ifdef CONFIG_TIME_INTERPOLATION
    static void time_interpolator_update(long delta_nsec);
    #else
    @@ -82,20 +83,70 @@ static inline void set_running_timer(tve
    struct timer_list *timer)
    {
    #ifdef CONFIG_SMP
    base->running_timer = timer;
    #endif
    }

    /* Fake initialization */
    static DEFINE_PER_CPU(tvec_base_t, tvec_bases) = { SPIN_LOCK_UNLOCKED };

    +/***
    + * Arch __udelay() for intervals greater than a few milliseconds can
    + * risk overflow for high loops_per_jiffy (high bogomips) machines. The
    + * _mdelay() and _udelay() provide wrappers to prevent this.
    + *
    + * It's not inlined because we do not optimize delays for speed,
    + * but for code size at mdelay/udelay callsite
    + */
    +void _mdelay(unsigned int msecs)
    +{
    + if (msecs > MAX_MDELAY_MS) {
    + printk("BUG: delay too large: mdelay(%u)\n", msecs);
    + dump_stack();
    + msecs = MAX_MDELAY_MS;
    + }
    + while (msecs--)
    + __udelay(1000);
    +}
    +EXPORT_SYMBOL(_mdelay);
    +
    +void _udelay(unsigned int usecs)
    +{
    + unsigned int k;
    + if (usecs > MAX_UDELAY_MS*1000) {
    + printk("BUG: delay too large: udelay(%u)\n", usecs);
    + dump_stack();
    + usecs = MAX_UDELAY_MS*1000;
    + }
    + k = usecs / 1024;
    + while (k--)
    + __udelay(1024);
    + __udelay(usecs % 1024);
    +}
    +EXPORT_SYMBOL(_udelay);
    +
    +void _ndelay(unsigned int nsecs)
    +{
    + unsigned int k;
    + if (nsecs > MAX_UDELAY_MS*1000*1000) {
    + printk("BUG: delay too large: ndelay(%u)\n", nsecs);
    + dump_stack();
    + nsecs = MAX_UDELAY_MS*1000*1000;
    + }
    + k = nsecs / (64*1024);
    + while (k--)
    + __ndelay(64*1024);
    + __ndelay(nsecs % (64*1024));
    +}
    +EXPORT_SYMBOL(_ndelay);
    +
    static void check_timer_failed(struct timer_list *timer)
    {
    static int whine_count;
    if (whine_count < 16) {
    whine_count++;
    printk("Uninitialised timer!\n");
    printk("This is just a warning. Your computer is OK\n");
    printk("function=0x%p, data=0x%lx\n",
    timer->function, timer->data);
    dump_stack();
    @@ -1583,22 +1634,27 @@ unregister_time_interpolator(struct time
    */
    void msleep(unsigned int msecs)
    {
    unsigned long timeout = msecs_to_jiffies(msecs) + 1;

    while (timeout) {
    set_current_state(TASK_UNINTERRUPTIBLE);
    timeout = schedule_timeout(timeout);
    }
    }
    -
    EXPORT_SYMBOL(msleep);
    +
    +void ssleep(unsigned int secs)
    +{
    + msleep(secs * 1000);
    +}
    +EXPORT_SYMBOL(ssleep);

    /**
    * msleep_interruptible - sleep waiting for waitqueue interruptions
    * @msecs: Time in milliseconds to sleep for
    */
    unsigned long msleep_interruptible(unsigned int msecs)
    {
    unsigned long timeout = msecs_to_jiffies(msecs) + 1;

    while (timeout && !signal_pending(current)) {[unhandled content-type:application/x-bzip2]
    \
     
     \ /
      Last update: 2005-07-01 11:43    [W:0.118 / U:28.868 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site