forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement generic time support for MN10300. Signed-off-by: Mark Salter <[email protected]> Signed-off-by: David Howells <[email protected]>
- Loading branch information
Showing
12 changed files
with
401 additions
and
115 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/* MN10300 clockevents | ||
* | ||
* Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. | ||
* Written by Mark Salter ([email protected]) | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public Licence | ||
* as published by the Free Software Foundation; either version | ||
* 2 of the Licence, or (at your option) any later version. | ||
*/ | ||
#include <linux/clockchips.h> | ||
#include <linux/interrupt.h> | ||
#include <linux/percpu.h> | ||
#include <linux/smp.h> | ||
#include <asm/timex.h> | ||
#include "internal.h" | ||
|
||
#ifdef CONFIG_SMP | ||
#if (CONFIG_NR_CPUS > 2) && !defined(CONFIG_GEENERIC_CLOCKEVENTS_BROADCAST) | ||
#error "This doesn't scale well! Need per-core local timers." | ||
#endif | ||
#else /* CONFIG_SMP */ | ||
#define stop_jiffies_counter1() | ||
#define reload_jiffies_counter1(x) | ||
#define TMJC1IRQ TMJCIRQ | ||
#endif | ||
|
||
|
||
static int next_event(unsigned long delta, | ||
struct clock_event_device *evt) | ||
{ | ||
unsigned int cpu = smp_processor_id(); | ||
|
||
if (cpu == 0) { | ||
stop_jiffies_counter(); | ||
reload_jiffies_counter(delta - 1); | ||
} else { | ||
stop_jiffies_counter1(); | ||
reload_jiffies_counter1(delta - 1); | ||
} | ||
return 0; | ||
} | ||
|
||
static void set_clock_mode(enum clock_event_mode mode, | ||
struct clock_event_device *evt) | ||
{ | ||
/* Nothing to do ... */ | ||
} | ||
|
||
static DEFINE_PER_CPU(struct clock_event_device, mn10300_clockevent_device); | ||
static DEFINE_PER_CPU(struct irqaction, timer_irq); | ||
|
||
static irqreturn_t timer_interrupt(int irq, void *dev_id) | ||
{ | ||
struct clock_event_device *cd; | ||
unsigned int cpu = smp_processor_id(); | ||
|
||
if (cpu == 0) | ||
stop_jiffies_counter(); | ||
else | ||
stop_jiffies_counter1(); | ||
|
||
cd = &per_cpu(mn10300_clockevent_device, cpu); | ||
cd->event_handler(cd); | ||
|
||
return IRQ_HANDLED; | ||
} | ||
|
||
static void event_handler(struct clock_event_device *dev) | ||
{ | ||
} | ||
|
||
int __init init_clockevents(void) | ||
{ | ||
struct clock_event_device *cd; | ||
struct irqaction *iact; | ||
unsigned int cpu = smp_processor_id(); | ||
|
||
cd = &per_cpu(mn10300_clockevent_device, cpu); | ||
|
||
if (cpu == 0) { | ||
stop_jiffies_counter(); | ||
cd->irq = TMJCIRQ; | ||
} else { | ||
stop_jiffies_counter1(); | ||
cd->irq = TMJC1IRQ; | ||
} | ||
|
||
cd->name = "Timestamp"; | ||
cd->features = CLOCK_EVT_FEAT_ONESHOT; | ||
|
||
/* Calculate the min / max delta */ | ||
clockevent_set_clock(cd, MN10300_JCCLK); | ||
|
||
cd->max_delta_ns = clockevent_delta2ns(TMJCBR_MAX, cd); | ||
cd->min_delta_ns = clockevent_delta2ns(100, cd); | ||
|
||
cd->rating = 200; | ||
cd->cpumask = cpumask_of(smp_processor_id()); | ||
cd->set_mode = set_clock_mode; | ||
cd->event_handler = event_handler; | ||
cd->set_next_event = next_event; | ||
|
||
iact = &per_cpu(timer_irq, cpu); | ||
iact->flags = IRQF_DISABLED | IRQF_SHARED | IRQF_TIMER; | ||
iact->handler = timer_interrupt; | ||
|
||
clockevents_register_device(cd); | ||
|
||
#if defined(CONFIG_SMP) && !defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) | ||
/* setup timer irq affinity so it only runs on this cpu */ | ||
{ | ||
struct irq_desc *desc; | ||
desc = irq_to_desc(cd->irq); | ||
cpumask_copy(desc->affinity, cpumask_of(cpu)); | ||
iact->flags |= IRQF_NOBALANCING; | ||
} | ||
#endif | ||
|
||
if (cpu == 0) { | ||
reload_jiffies_counter(MN10300_JC_PER_HZ - 1); | ||
iact->name = "CPU0 Timer"; | ||
} else { | ||
reload_jiffies_counter1(MN10300_JC_PER_HZ - 1); | ||
iact->name = "CPU1 Timer"; | ||
} | ||
|
||
setup_jiffies_interrupt(cd->irq, iact); | ||
|
||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* MN10300 clocksource | ||
* | ||
* Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. | ||
* Written by Mark Salter ([email protected]) | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public Licence | ||
* as published by the Free Software Foundation; either version | ||
* 2 of the Licence, or (at your option) any later version. | ||
*/ | ||
#include <linux/clocksource.h> | ||
#include <linux/init.h> | ||
#include <asm/timex.h> | ||
#include "internal.h" | ||
|
||
static cycle_t mn10300_read(struct clocksource *cs) | ||
{ | ||
return read_timestamp_counter(); | ||
} | ||
|
||
static struct clocksource clocksource_mn10300 = { | ||
.name = "TSC", | ||
.rating = 200, | ||
.read = mn10300_read, | ||
.mask = CLOCKSOURCE_MASK(32), | ||
.flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
}; | ||
|
||
int __init init_clocksource(void) | ||
{ | ||
startup_timestamp_counter(); | ||
clocksource_set_clock(&clocksource_mn10300, MN10300_TSCCLK); | ||
clocksource_register(&clocksource_mn10300); | ||
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
Oops, something went wrong.