-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MIPS: Add new GIC clockevent driver.
Add new clockevent driver that uses the counter present on the MIPS Global Interrupt Controller. Signed-off-by: Raghu Gandham <Raghu.Gandham@imgtec.com> Signed-off-by: Steven J. Hill <Steven.Hill@imgtec.com>
- Loading branch information
Raghu Gandham
authored and
Ralf Baechle
committed
May 9, 2013
1 parent
2675fa7
commit 0ab2b7d
Showing
8 changed files
with
163 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License. See the file "COPYING" in the main directory of this archive | ||
* for more details. | ||
* | ||
* Copyright (C) 2013 Imagination Technologies Ltd. | ||
*/ | ||
#include <linux/clockchips.h> | ||
#include <linux/interrupt.h> | ||
#include <linux/percpu.h> | ||
#include <linux/smp.h> | ||
#include <linux/irq.h> | ||
|
||
#include <asm/time.h> | ||
#include <asm/gic.h> | ||
#include <asm/mips-boards/maltaint.h> | ||
|
||
DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); | ||
int gic_timer_irq_installed; | ||
|
||
|
||
static int gic_next_event(unsigned long delta, struct clock_event_device *evt) | ||
{ | ||
u64 cnt; | ||
int res; | ||
|
||
cnt = gic_read_count(); | ||
cnt += (u64)delta; | ||
gic_write_compare(cnt); | ||
res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; | ||
return res; | ||
} | ||
|
||
void gic_set_clock_mode(enum clock_event_mode mode, | ||
struct clock_event_device *evt) | ||
{ | ||
/* Nothing to do ... */ | ||
} | ||
|
||
irqreturn_t gic_compare_interrupt(int irq, void *dev_id) | ||
{ | ||
struct clock_event_device *cd; | ||
int cpu = smp_processor_id(); | ||
|
||
gic_write_compare(gic_read_compare()); | ||
cd = &per_cpu(gic_clockevent_device, cpu); | ||
cd->event_handler(cd); | ||
return IRQ_HANDLED; | ||
} | ||
|
||
struct irqaction gic_compare_irqaction = { | ||
.handler = gic_compare_interrupt, | ||
.flags = IRQF_PERCPU | IRQF_TIMER, | ||
.name = "timer", | ||
}; | ||
|
||
|
||
void gic_event_handler(struct clock_event_device *dev) | ||
{ | ||
} | ||
|
||
int __cpuinit gic_clockevent_init(void) | ||
{ | ||
unsigned int cpu = smp_processor_id(); | ||
struct clock_event_device *cd; | ||
unsigned int irq; | ||
|
||
if (!cpu_has_counter || !gic_frequency) | ||
return -ENXIO; | ||
|
||
irq = MIPS_GIC_IRQ_BASE; | ||
|
||
cd = &per_cpu(gic_clockevent_device, cpu); | ||
|
||
cd->name = "MIPS GIC"; | ||
cd->features = CLOCK_EVT_FEAT_ONESHOT; | ||
|
||
clockevent_set_clock(cd, gic_frequency); | ||
|
||
/* Calculate the min / max delta */ | ||
cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); | ||
cd->min_delta_ns = clockevent_delta2ns(0x300, cd); | ||
|
||
cd->rating = 300; | ||
cd->irq = irq; | ||
cd->cpumask = cpumask_of(cpu); | ||
cd->set_next_event = gic_next_event; | ||
cd->set_mode = gic_set_clock_mode; | ||
cd->event_handler = gic_event_handler; | ||
|
||
clockevents_register_device(cd); | ||
|
||
GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_MAP), 0x80000002); | ||
GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), GIC_VPE_SMASK_CMP_MSK); | ||
|
||
if (gic_timer_irq_installed) | ||
return 0; | ||
|
||
gic_timer_irq_installed = 1; | ||
|
||
setup_irq(irq, &gic_compare_irqaction); | ||
irq_set_handler(irq, handle_percpu_irq); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters