Commit 414408d0 authored by Paul Burton's avatar Paul Burton

MIPS: allow GIC clockevent device config from other CPUs

This patch allows the GIC clockevent device for a CPU to be configured
by another CPU. This makes GIC clockevent devices suitable for use as
the tick broadcast device, where formerly the GIC timer local to the
configuring CPU would have been configured incorrectly.
Signed-off-by: default avatarPaul Burton <paul.burton@imgtec.com>
parent 0467811e
...@@ -380,6 +380,7 @@ extern unsigned int gic_compare_int (void); ...@@ -380,6 +380,7 @@ extern unsigned int gic_compare_int (void);
extern cycle_t gic_read_count(void); extern cycle_t gic_read_count(void);
extern cycle_t gic_read_compare(void); extern cycle_t gic_read_compare(void);
extern void gic_write_compare(cycle_t cnt); extern void gic_write_compare(cycle_t cnt);
extern void gic_write_cpu_compare(cycle_t cnt, int cpu);
extern void gic_send_ipi(unsigned int intr); extern void gic_send_ipi(unsigned int intr);
extern unsigned int plat_ipi_call_int_xlate(unsigned int); extern unsigned int plat_ipi_call_int_xlate(unsigned int);
extern unsigned int plat_ipi_resched_int_xlate(unsigned int); extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
......
...@@ -26,7 +26,7 @@ static int gic_next_event(unsigned long delta, struct clock_event_device *evt) ...@@ -26,7 +26,7 @@ static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
cnt = gic_read_count(); cnt = gic_read_count();
cnt += (u64)delta; cnt += (u64)delta;
gic_write_compare(cnt); gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask));
res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0;
return res; return res;
} }
......
...@@ -54,6 +54,21 @@ void gic_write_compare(cycle_t cnt) ...@@ -54,6 +54,21 @@ void gic_write_compare(cycle_t cnt)
(int)(cnt & 0xffffffff)); (int)(cnt & 0xffffffff));
} }
void gic_write_cpu_compare(cycle_t cnt, int cpu)
{
unsigned long flags;
local_irq_save(flags);
GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu);
GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI),
(int)(cnt >> 32));
GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO),
(int)(cnt & 0xffffffff));
local_irq_restore(flags);
}
cycle_t gic_read_compare(void) cycle_t gic_read_compare(void)
{ {
unsigned int hi, lo; unsigned int hi, lo;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment