0001
0002
0003
0004
0005
0006
0007 #include <linux/clockchips.h>
0008
0009 #include <asm/irq.h>
0010 #include <asm/numachip/numachip.h>
0011 #include <asm/numachip/numachip_csr.h>
0012
0013 static DEFINE_PER_CPU(struct clock_event_device, numachip2_ced);
0014
0015 static cycles_t numachip2_timer_read(struct clocksource *cs)
0016 {
0017 return numachip2_read64_lcsr(NUMACHIP2_TIMER_NOW);
0018 }
0019
0020 static struct clocksource numachip2_clocksource = {
0021 .name = "numachip2",
0022 .rating = 295,
0023 .read = numachip2_timer_read,
0024 .mask = CLOCKSOURCE_MASK(64),
0025 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
0026 .mult = 1,
0027 .shift = 0,
0028 };
0029
0030 static int numachip2_set_next_event(unsigned long delta, struct clock_event_device *ced)
0031 {
0032 numachip2_write64_lcsr(NUMACHIP2_TIMER_DEADLINE + numachip2_timer(),
0033 delta);
0034 return 0;
0035 }
0036
0037 static const struct clock_event_device numachip2_clockevent __initconst = {
0038 .name = "numachip2",
0039 .rating = 400,
0040 .set_next_event = numachip2_set_next_event,
0041 .features = CLOCK_EVT_FEAT_ONESHOT,
0042 .mult = 1,
0043 .shift = 0,
0044 .min_delta_ns = 1250,
0045 .min_delta_ticks = 1250,
0046 .max_delta_ns = LONG_MAX,
0047 .max_delta_ticks = LONG_MAX,
0048 };
0049
0050 static void numachip_timer_interrupt(void)
0051 {
0052 struct clock_event_device *ced = this_cpu_ptr(&numachip2_ced);
0053
0054 ced->event_handler(ced);
0055 }
0056
0057 static __init void numachip_timer_each(struct work_struct *work)
0058 {
0059 unsigned local_apicid = __this_cpu_read(x86_cpu_to_apicid) & 0xff;
0060 struct clock_event_device *ced = this_cpu_ptr(&numachip2_ced);
0061
0062
0063 numachip2_write64_lcsr(NUMACHIP2_TIMER_INT + numachip2_timer(),
0064 (3 << 22) | (X86_PLATFORM_IPI_VECTOR << 14) |
0065 (local_apicid << 6));
0066
0067 *ced = numachip2_clockevent;
0068 ced->cpumask = cpumask_of(smp_processor_id());
0069 clockevents_register_device(ced);
0070 }
0071
0072 static int __init numachip_timer_init(void)
0073 {
0074 if (numachip_system != 2)
0075 return -ENODEV;
0076
0077
0078 numachip2_write64_lcsr(NUMACHIP2_TIMER_RESET, 0);
0079 clocksource_register_hz(&numachip2_clocksource, NSEC_PER_SEC);
0080
0081
0082 x86_platform_ipi_callback = numachip_timer_interrupt;
0083 schedule_on_each_cpu(&numachip_timer_each);
0084
0085 return 0;
0086 }
0087
0088 arch_initcall(numachip_timer_init);