Merge branch 'for_linus' of git://cavan.codon.org.uk/platform-drivers-x86
[cascardo/linux.git] / arch / mips / kernel / csrc-gic.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
7  */
8 #include <linux/clocksource.h>
9 #include <linux/init.h>
10
11 #include <asm/time.h>
12 #include <asm/gic.h>
13
14 static cycle_t gic_hpt_read(struct clocksource *cs)
15 {
16         unsigned int hi, hi2, lo;
17
18         do {
19                 GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi);
20                 GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo);
21                 GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2);
22         } while (hi2 != hi);
23
24         return (((cycle_t) hi) << 32) + lo;
25 }
26
27 static struct clocksource gic_clocksource = {
28         .name   = "GIC",
29         .read   = gic_hpt_read,
30         .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
31 };
32
33 void __init gic_clocksource_init(unsigned int frequency)
34 {
35         unsigned int config, bits;
36
37         /* Calculate the clocksource mask. */
38         GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config);
39         bits = 32 + ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >>
40                 (GIC_SH_CONFIG_COUNTBITS_SHF - 2));
41
42         /* Set clocksource mask. */
43         gic_clocksource.mask = CLOCKSOURCE_MASK(bits);
44
45         /* Calculate a somewhat reasonable rating value. */
46         gic_clocksource.rating = 200 + frequency / 10000000;
47
48         clocksource_register_hz(&gic_clocksource, frequency);
49 }