Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 73928
b: refs/heads/master
c: 5aa85c9
h: refs/heads/master
v: v3
  • Loading branch information
Ralf Baechle committed Nov 26, 2007
1 parent bf0f40e commit d2527b2
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 62 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0f67e90e1caea4a0a14d2c60102547bce29f7f08
refs/heads/master: 5aa85c9fc49a6ce44dc10a42e2011bbde9dc445a
12 changes: 7 additions & 5 deletions trunk/arch/mips/kernel/cevt-r4k.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,15 +219,15 @@ static int c0_compare_int_usable(void)
return 1;
}

void __cpuinit mips_clockevent_init(void)
int __cpuinit mips_clockevent_init(void)
{
uint64_t mips_freq = mips_hpt_frequency;
unsigned int cpu = smp_processor_id();
struct clock_event_device *cd;
unsigned int irq;

if (!cpu_has_counter || !mips_hpt_frequency)
return;
return -ENXIO;

#ifdef CONFIG_MIPS_MT_SMTC
setup_smtc_dummy_clockevent_device();
Expand All @@ -237,11 +237,11 @@ void __cpuinit mips_clockevent_init(void)
* device.
*/
if (cpu)
return;
return 0;
#endif

if (!c0_compare_int_usable())
return;
return -ENXIO;

/*
* With vectored interrupts things are getting platform specific.
Expand Down Expand Up @@ -277,7 +277,7 @@ void __cpuinit mips_clockevent_init(void)
clockevents_register_device(cd);

if (cp0_timer_irq_installed)
return;
return 0;

cp0_timer_irq_installed = 1;

Expand All @@ -287,4 +287,6 @@ void __cpuinit mips_clockevent_init(void)
#else
setup_irq(irq, &c0_compare_irqaction);
#endif

return 0;
}
87 changes: 33 additions & 54 deletions trunk/arch/mips/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,48 +91,6 @@ static struct clocksource clocksource_mips = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};

static unsigned int __init calibrate_hpt(void)
{
cycle_t frequency, hpt_start, hpt_end, hpt_count, hz;

const int loops = HZ / 10;
int log_2_loops = 0;
int i;

/*
* We want to calibrate for 0.1s, but to avoid a 64-bit
* division we round the number of loops up to the nearest
* power of 2.
*/
while (loops > 1 << log_2_loops)
log_2_loops++;
i = 1 << log_2_loops;

/*
* Wait for a rising edge of the timer interrupt.
*/
while (mips_timer_state());
while (!mips_timer_state());

/*
* Now see how many high precision timer ticks happen
* during the calculated number of periods between timer
* interrupts.
*/
hpt_start = clocksource_mips.read();
do {
while (mips_timer_state());
while (!mips_timer_state());
} while (--i);
hpt_end = clocksource_mips.read();

hpt_count = (hpt_end - hpt_start) & clocksource_mips.mask;
hz = HZ;
frequency = hpt_count * hz;

return frequency >> log_2_loops;
}

void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
{
u64 temp;
Expand Down Expand Up @@ -194,21 +152,42 @@ void __init plat_timer_setup(void)
BUG();
}

static __init int cpu_has_mfc0_count_bug(void)
{
switch (current_cpu_type()) {
case CPU_R4000PC:
case CPU_R4000SC:
case CPU_R4000MC:
/*
* V3.0 is documented as suffering from the mfc0 from count bug.
* Afaik this is the last version of the R4000. Later versions
* were marketed as R4400.
*/
return 1;

case CPU_R4400PC:
case CPU_R4400SC:
case CPU_R4400MC:
/*
* The published errata for the R4400 upto 3.0 say the CPU
* has the mfc0 from count bug.
*/
if ((current_cpu_data.processor_id & 0xff) <= 0x30)
return 1;

/*
* I don't have erratas for newer R4400 so be paranoid.
*/
return 1;
}

return 0;
}

void __init time_init(void)
{
plat_time_init();

if (cpu_has_counter && (mips_hpt_frequency || mips_timer_state)) {
/* We know counter frequency. Or we can get it. */
if (!mips_hpt_frequency)
mips_hpt_frequency = calibrate_hpt();

/* Report the high precision timer rate for a reference. */
printk("Using %u.%03u MHz high precision timer.\n",
((mips_hpt_frequency + 500) / 1000) / 1000,
((mips_hpt_frequency + 500) / 1000) % 1000);
if (mips_clockevent_init() || !cpu_has_mfc0_count_bug())
init_mips_clocksource();
}

mips_clockevent_init();
}
5 changes: 3 additions & 2 deletions trunk/include/asm-mips/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,12 @@ extern int (*perf_irq)(void);
* Initialize the calling CPU's compare interrupt as clockevent device
*/
#ifdef CONFIG_CEVT_R4K
extern void mips_clockevent_init(void);
extern int mips_clockevent_init(void);
extern unsigned int __weak get_c0_compare_int(void);
#else
static inline void mips_clockevent_init(void)
static inline int mips_clockevent_init(void)
{
return -ENXIO;
}
#endif

Expand Down

0 comments on commit d2527b2

Please sign in to comment.