Skip to content

Commit

Permalink
clocksource: mips-gic-timer: Use new GIC accessor functions
Browse files Browse the repository at this point in the history
Switch from calling functions exported by the GIC interrupt controller
to using new accessors provided by asm/mips-gic.h. This will allow the
counter-handling functionality to be removed from the interrupt
controller driver, where it doesn't really belong, and also allow for
inlining of the accesses to the GIC.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/17021/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
Paul Burton authored and Ralf Baechle committed Aug 30, 2017
1 parent 582e2b4 commit e07127a
Showing 1 changed file with 31 additions and 6 deletions.
37 changes: 31 additions & 6 deletions drivers/clocksource/mips-gic-timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,45 @@
#include <linux/cpu.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irqchip/mips-gic.h>
#include <linux/notifier.h>
#include <linux/of_irq.h>
#include <linux/percpu.h>
#include <linux/smp.h>
#include <linux/time.h>
#include <asm/mips-cps.h>

static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device);
static int gic_timer_irq;
static unsigned int gic_frequency;

static u64 notrace gic_read_count(void)
{
unsigned int hi, hi2, lo;

if (mips_cm_is64)
return read_gic_counter();

do {
hi = read_gic_counter_32h();
lo = read_gic_counter_32l();
hi2 = read_gic_counter_32h();
} while (hi2 != hi);

return (((u64) hi) << 32) + lo;
}

static int gic_next_event(unsigned long delta, struct clock_event_device *evt)
{
unsigned long flags;
u64 cnt;
int res;

cnt = gic_read_count();
cnt += (u64)delta;
gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask));
local_irq_save(flags);
write_gic_vl_other(mips_cm_vp_id(cpumask_first(evt->cpumask)));
write_gic_vo_compare(cnt);
local_irq_restore(flags);
res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0;
return res;
}
Expand All @@ -37,7 +57,7 @@ static irqreturn_t gic_compare_interrupt(int irq, void *dev_id)
{
struct clock_event_device *cd = dev_id;

gic_write_compare(gic_read_compare());
write_gic_vl_compare(read_gic_vl_compare());
cd->event_handler(cd);
return IRQ_HANDLED;
}
Expand Down Expand Up @@ -139,10 +159,15 @@ static struct clocksource gic_clocksource = {

static int __init __gic_clocksource_init(void)
{
unsigned int count_width;
int ret;

/* Set clocksource mask. */
gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width());
count_width = read_gic_config() & GIC_CONFIG_COUNTBITS;
count_width >>= __fls(GIC_CONFIG_COUNTBITS);
count_width *= 4;
count_width += 32;
gic_clocksource.mask = CLOCKSOURCE_MASK(count_width);

/* Calculate a somewhat reasonable rating value. */
gic_clocksource.rating = 200 + gic_frequency / 10000000;
Expand All @@ -159,7 +184,7 @@ static int __init gic_clocksource_of_init(struct device_node *node)
struct clk *clk;
int ret;

if (!gic_present || !node->parent ||
if (!mips_gic_present() || !node->parent ||
!of_device_is_compatible(node->parent, "mti,gic")) {
pr_warn("No DT definition for the mips gic driver\n");
return -ENXIO;
Expand Down Expand Up @@ -197,7 +222,7 @@ static int __init gic_clocksource_of_init(struct device_node *node)
}

/* And finally start the counter */
gic_start_count();
clear_gic_config(GIC_CONFIG_COUNTSTOP);

return 0;
}
Expand Down

0 comments on commit e07127a

Please sign in to comment.