Skip to content

Commit

Permalink
[MIPS] Probe for usability of cp0 compare interrupt.
Browse files Browse the repository at this point in the history
Some processors offer the option of using the interrupt on which
normally the count / compare interrupt would be signaled as a normal
interupt pin.  Previously this required some ugly hackery for each
system which is much easier done by a quick and simple probe.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
Ralf Baechle committed Oct 17, 2007
1 parent 60b0d65 commit b0d4056
Showing 1 changed file with 47 additions and 0 deletions.
47 changes: 47 additions & 0 deletions arch/mips/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,50 @@ static void mips_event_handler(struct clock_event_device *dev)
{
}

/*
* FIXME: This doesn't hold for the relocated E9000 compare interrupt.
*/
static int c0_compare_int_pending(void)
{
return (read_c0_cause() >> cp0_compare_irq) & 0x100;
}

static int c0_compare_int_usable(void)
{
const unsigned int delta = 0x300000;
unsigned int cnt;

/*
* IP7 already pending? Try to clear it by acking the timer.
*/
if (c0_compare_int_pending()) {
write_c0_compare(read_c0_compare());
irq_disable_hazard();
if (c0_compare_int_pending())
return 0;
}

cnt = read_c0_count();
cnt += delta;
write_c0_compare(cnt);

while ((long)(read_c0_count() - cnt) <= 0)
; /* Wait for expiry */

if (!c0_compare_int_pending())
return 0;

write_c0_compare(read_c0_compare());
irq_disable_hazard();
if (c0_compare_int_pending())
return 0;

/*
* Feels like a real count / compare timer.
*/
return 1;
}

void __cpuinit mips_clockevent_init(void)
{
uint64_t mips_freq = mips_hpt_frequency;
Expand All @@ -412,6 +456,9 @@ void __cpuinit mips_clockevent_init(void)
return;
#endif

if (!c0_compare_int_usable())
return;

cd = &per_cpu(mips_clockevent_device, cpu);

cd->name = "MIPS";
Expand Down

0 comments on commit b0d4056

Please sign in to comment.