1414#include <linux/module.h>
1515#include <linux/rtc.h>
1616#include <linux/sched.h>
17+ #include <linux/sched_clock.h>
1718#include <linux/kernel.h>
1819#include <linux/param.h>
1920#include <linux/string.h>
3940
4041static unsigned long clocktick __read_mostly ; /* timer cycles per tick */
4142
42- #ifndef CONFIG_64BIT
43- /*
44- * The processor-internal cycle counter (Control Register 16) is used as time
45- * source for the sched_clock() function. This register is 64bit wide on a
46- * 64-bit kernel and 32bit on a 32-bit kernel. Since sched_clock() always
47- * requires a 64bit counter we emulate on the 32-bit kernel the higher 32bits
48- * with a per-cpu variable which we increase every time the counter
49- * wraps-around (which happens every ~4 secounds).
50- */
51- static DEFINE_PER_CPU (unsigned long, cr16_high_32_bits ) ;
52- #endif
53-
5443/*
5544 * We keep time on PA-RISC Linux by using the Interval Timer which is
5645 * a pair of registers; one is read-only and one is write-only; both
@@ -121,12 +110,6 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
121110 */
122111 mtctl (next_tick , 16 );
123112
124- #if !defined(CONFIG_64BIT )
125- /* check for overflow on a 32bit kernel (every ~4 seconds). */
126- if (unlikely (next_tick < now ))
127- this_cpu_inc (cr16_high_32_bits );
128- #endif
129-
130113 /* Skip one clocktick on purpose if we missed next_tick.
131114 * The new CR16 must be "later" than current CR16 otherwise
132115 * itimer would not fire until CR16 wrapped - e.g 4 seconds
@@ -208,7 +191,7 @@ EXPORT_SYMBOL(profile_pc);
208191
209192/* clock source code */
210193
211- static cycle_t read_cr16 (struct clocksource * cs )
194+ static cycle_t notrace read_cr16 (struct clocksource * cs )
212195{
213196 return get_cycles ();
214197}
@@ -287,26 +270,9 @@ void read_persistent_clock(struct timespec *ts)
287270}
288271
289272
290- /*
291- * sched_clock() framework
292- */
293-
294- static u32 cyc2ns_mul __read_mostly ;
295- static u32 cyc2ns_shift __read_mostly ;
296-
297- u64 sched_clock (void )
273+ static u64 notrace read_cr16_sched_clock (void )
298274{
299- u64 now ;
300-
301- /* Get current cycle counter (Control Register 16). */
302- #ifdef CONFIG_64BIT
303- now = mfctl (16 );
304- #else
305- now = mfctl (16 ) + (((u64 ) this_cpu_read (cr16_high_32_bits )) << 32 );
306- #endif
307-
308- /* return the value in ns (cycles_2_ns) */
309- return mul_u64_u32_shr (now , cyc2ns_mul , cyc2ns_shift );
275+ return get_cycles ();
310276}
311277
312278
@@ -316,17 +282,16 @@ u64 sched_clock(void)
316282
317283void __init time_init (void )
318284{
319- unsigned long current_cr16_khz ;
285+ unsigned long cr16_hz ;
320286
321- current_cr16_khz = PAGE0 -> mem_10msec /10 ; /* kHz */
322287 clocktick = (100 * PAGE0 -> mem_10msec ) / HZ ;
323-
324- /* calculate mult/shift values for cr16 */
325- clocks_calc_mult_shift (& cyc2ns_mul , & cyc2ns_shift , current_cr16_khz ,
326- NSEC_PER_MSEC , 0 );
327-
328288 start_cpu_itimer (); /* get CPU 0 started */
329289
290+ cr16_hz = 100 * PAGE0 -> mem_10msec ; /* Hz */
291+
330292 /* register at clocksource framework */
331- clocksource_register_khz (& clocksource_cr16 , current_cr16_khz );
293+ clocksource_register_hz (& clocksource_cr16 , cr16_hz );
294+
295+ /* register as sched_clock source */
296+ sched_clock_register (read_cr16_sched_clock , BITS_PER_LONG , cr16_hz );
332297}
0 commit comments