#define TICK_SIZE (tick_nsec / 1000)
-static inline void timer_check_rtc(void)
+static __inline__ void timer_check_rtc(void)
{
/* last time the cmos clock got updated */
static long last_rtc_update;
void sparc64_do_profile(struct pt_regs *regs)
{
- unsigned long pc;
+ unsigned long pc = regs->tpc;
+ unsigned long o7 = regs->u_regs[UREG_RETPC];
profile_hook(regs);
if (!prof_buffer)
return;
- pc = regs->tpc;
-
- pc -= (unsigned long) _stext;
- pc >>= prof_shift;
-
- if(pc >= prof_len)
- pc = prof_len - 1;
- atomic_inc((atomic_t *)&prof_buffer[pc]);
+ {
+ extern int rwlock_impl_begin, rwlock_impl_end;
+ extern int atomic_impl_begin, atomic_impl_end;
+ extern int __memcpy_begin, __memcpy_end;
+ extern int __bzero_begin, __bzero_end;
+ extern int __bitops_begin, __bitops_end;
+
+ if ((pc >= (unsigned long) &atomic_impl_begin &&
+ pc < (unsigned long) &atomic_impl_end) ||
+ (pc >= (unsigned long) &rwlock_impl_begin &&
+ pc < (unsigned long) &rwlock_impl_end) ||
+ (pc >= (unsigned long) &__memcpy_begin &&
+ pc < (unsigned long) &__memcpy_end) ||
+ (pc >= (unsigned long) &__bzero_begin &&
+ pc < (unsigned long) &__bzero_end) ||
+ (pc >= (unsigned long) &__bitops_begin &&
+ pc < (unsigned long) &__bitops_end))
+ pc = o7;
+
+ pc -= (unsigned long) _stext;
+ pc >>= prof_shift;
+
+ if(pc >= prof_len)
+ pc = prof_len - 1;
+ atomic_inc((atomic_t *)&prof_buffer[pc]);
+ }
}
static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
*/
void do_gettimeofday(struct timeval *tv)
{
+ unsigned long flags;
unsigned long seq;
unsigned long usec, sec;
unsigned long max_ntp_tick = tick_usec - tickadj;
do {
unsigned long lost;
- seq = read_seqbegin(&xtime_lock);
+ seq = read_seqbegin_irqsave(&xtime_lock, flags);
usec = do_gettimeoffset();
lost = jiffies - wall_jiffies;
usec += lost * tick_usec;
sec = xtime.tv_sec;
-
- /* Believe it or not, this divide shows up on
- * kernel profiles. The problem is that it is
- * both 64-bit and signed. Happily, 32-bits
- * of precision is all we really need and in
- * doing so gcc ends up emitting a cheap multiply.
- *
- * XXX Why is tv_nsec 'long' and 'signed' in
- * XXX the first place, can it even be negative?
- */
- usec += ((unsigned int) xtime.tv_nsec / 1000U);
- } while (read_seqretry(&xtime_lock, seq));
+ usec += (xtime.tv_nsec / 1000);
+ } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
while (usec >= 1000000) {
usec -= 1000000;