1/* 2 * DEC I/O ASIC's counter clocksource 3 * 4 * Copyright (C) 2008 Yoichi Yuasa <yuasa@linux-mips.org> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16#include <linux/clocksource.h> 17#include <linux/sched_clock.h> 18#include <linux/init.h> 19 20#include <asm/ds1287.h> 21#include <asm/time.h> 22#include <asm/dec/ioasic.h> 23#include <asm/dec/ioasic_addrs.h> 24 25static cycle_t dec_ioasic_hpt_read(struct clocksource *cs) 26{ 27 return ioasic_read(IO_REG_FCTR); 28} 29 30static struct clocksource clocksource_dec = { 31 .name = "dec-ioasic", 32 .read = dec_ioasic_hpt_read, 33 .mask = CLOCKSOURCE_MASK(32), 34 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 35}; 36 37static u64 notrace dec_ioasic_read_sched_clock(void) 38{ 39 return ioasic_read(IO_REG_FCTR); 40} 41 42int __init dec_ioasic_clocksource_init(void) 43{ 44 unsigned int freq; 45 u32 start, end; 46 int i = HZ / 8; 47 48 ds1287_timer_state(); 49 while (!ds1287_timer_state()) 50 ; 51 52 start = dec_ioasic_hpt_read(&clocksource_dec); 53 54 while (i--) 55 while (!ds1287_timer_state()) 56 ; 57 58 end = dec_ioasic_hpt_read(&clocksource_dec); 59 60 freq = (end - start) * 8; 61 62 /* An early revision of the I/O ASIC didn't have the counter. */ 63 if (!freq) 64 return -ENXIO; 65 66 printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq); 67 68 clocksource_dec.rating = 200 + freq / 10000000; 69 clocksource_register_hz(&clocksource_dec, freq); 70 71 sched_clock_register(dec_ioasic_read_sched_clock, 32, freq); 72 73 return 0; 74} 75