diff options
Diffstat (limited to 'arch/ia64/kernel/cyclone.c')
-rw-r--r-- | arch/ia64/kernel/cyclone.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c index e00b21514f7c..2fd96d9062a1 100644 --- a/arch/ia64/kernel/cyclone.c +++ b/arch/ia64/kernel/cyclone.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/time.h> | 3 | #include <linux/time.h> |
4 | #include <linux/errno.h> | 4 | #include <linux/errno.h> |
5 | #include <linux/timex.h> | 5 | #include <linux/timex.h> |
6 | #include <linux/clocksource.h> | ||
6 | #include <asm/io.h> | 7 | #include <asm/io.h> |
7 | 8 | ||
8 | /* IBM Summit (EXA) Cyclone counter code*/ | 9 | /* IBM Summit (EXA) Cyclone counter code*/ |
@@ -18,13 +19,21 @@ void __init cyclone_setup(void) | |||
18 | use_cyclone = 1; | 19 | use_cyclone = 1; |
19 | } | 20 | } |
20 | 21 | ||
22 | static void __iomem *cyclone_mc; | ||
21 | 23 | ||
22 | struct time_interpolator cyclone_interpolator = { | 24 | static cycle_t read_cyclone(void) |
23 | .source = TIME_SOURCE_MMIO64, | 25 | { |
24 | .shift = 16, | 26 | return (cycle_t)readq((void __iomem *)cyclone_mc); |
25 | .frequency = CYCLONE_TIMER_FREQ, | 27 | } |
26 | .drift = -100, | 28 | |
27 | .mask = (1LL << 40) - 1 | 29 | static struct clocksource clocksource_cyclone = { |
30 | .name = "cyclone", | ||
31 | .rating = 300, | ||
32 | .read = read_cyclone, | ||
33 | .mask = (1LL << 40) - 1, | ||
34 | .mult = 0, /*to be caluclated*/ | ||
35 | .shift = 16, | ||
36 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
28 | }; | 37 | }; |
29 | 38 | ||
30 | int __init init_cyclone_clock(void) | 39 | int __init init_cyclone_clock(void) |
@@ -44,13 +53,15 @@ int __init init_cyclone_clock(void) | |||
44 | offset = (CYCLONE_CBAR_ADDR); | 53 | offset = (CYCLONE_CBAR_ADDR); |
45 | reg = (u64*)ioremap_nocache(offset, sizeof(u64)); | 54 | reg = (u64*)ioremap_nocache(offset, sizeof(u64)); |
46 | if(!reg){ | 55 | if(!reg){ |
47 | printk(KERN_ERR "Summit chipset: Could not find valid CBAR register.\n"); | 56 | printk(KERN_ERR "Summit chipset: Could not find valid CBAR" |
57 | " register.\n"); | ||
48 | use_cyclone = 0; | 58 | use_cyclone = 0; |
49 | return -ENODEV; | 59 | return -ENODEV; |
50 | } | 60 | } |
51 | base = readq(reg); | 61 | base = readq(reg); |
52 | if(!base){ | 62 | if(!base){ |
53 | printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n"); | 63 | printk(KERN_ERR "Summit chipset: Could not find valid CBAR" |
64 | " value.\n"); | ||
54 | use_cyclone = 0; | 65 | use_cyclone = 0; |
55 | return -ENODEV; | 66 | return -ENODEV; |
56 | } | 67 | } |
@@ -60,7 +71,8 @@ int __init init_cyclone_clock(void) | |||
60 | offset = (base + CYCLONE_PMCC_OFFSET); | 71 | offset = (base + CYCLONE_PMCC_OFFSET); |
61 | reg = (u64*)ioremap_nocache(offset, sizeof(u64)); | 72 | reg = (u64*)ioremap_nocache(offset, sizeof(u64)); |
62 | if(!reg){ | 73 | if(!reg){ |
63 | printk(KERN_ERR "Summit chipset: Could not find valid PMCC register.\n"); | 74 | printk(KERN_ERR "Summit chipset: Could not find valid PMCC" |
75 | " register.\n"); | ||
64 | use_cyclone = 0; | 76 | use_cyclone = 0; |
65 | return -ENODEV; | 77 | return -ENODEV; |
66 | } | 78 | } |
@@ -71,7 +83,8 @@ int __init init_cyclone_clock(void) | |||
71 | offset = (base + CYCLONE_MPCS_OFFSET); | 83 | offset = (base + CYCLONE_MPCS_OFFSET); |
72 | reg = (u64*)ioremap_nocache(offset, sizeof(u64)); | 84 | reg = (u64*)ioremap_nocache(offset, sizeof(u64)); |
73 | if(!reg){ | 85 | if(!reg){ |
74 | printk(KERN_ERR "Summit chipset: Could not find valid MPCS register.\n"); | 86 | printk(KERN_ERR "Summit chipset: Could not find valid MPCS" |
87 | " register.\n"); | ||
75 | use_cyclone = 0; | 88 | use_cyclone = 0; |
76 | return -ENODEV; | 89 | return -ENODEV; |
77 | } | 90 | } |
@@ -82,7 +95,8 @@ int __init init_cyclone_clock(void) | |||
82 | offset = (base + CYCLONE_MPMC_OFFSET); | 95 | offset = (base + CYCLONE_MPMC_OFFSET); |
83 | cyclone_timer = (u32*)ioremap_nocache(offset, sizeof(u32)); | 96 | cyclone_timer = (u32*)ioremap_nocache(offset, sizeof(u32)); |
84 | if(!cyclone_timer){ | 97 | if(!cyclone_timer){ |
85 | printk(KERN_ERR "Summit chipset: Could not find valid MPMC register.\n"); | 98 | printk(KERN_ERR "Summit chipset: Could not find valid MPMC" |
99 | " register.\n"); | ||
86 | use_cyclone = 0; | 100 | use_cyclone = 0; |
87 | return -ENODEV; | 101 | return -ENODEV; |
88 | } | 102 | } |
@@ -93,7 +107,8 @@ int __init init_cyclone_clock(void) | |||
93 | int stall = 100; | 107 | int stall = 100; |
94 | while(stall--) barrier(); | 108 | while(stall--) barrier(); |
95 | if(readl(cyclone_timer) == old){ | 109 | if(readl(cyclone_timer) == old){ |
96 | printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n"); | 110 | printk(KERN_ERR "Summit chipset: Counter not counting!" |
111 | " DISABLED\n"); | ||
97 | iounmap(cyclone_timer); | 112 | iounmap(cyclone_timer); |
98 | cyclone_timer = 0; | 113 | cyclone_timer = 0; |
99 | use_cyclone = 0; | 114 | use_cyclone = 0; |
@@ -101,8 +116,11 @@ int __init init_cyclone_clock(void) | |||
101 | } | 116 | } |
102 | } | 117 | } |
103 | /* initialize last tick */ | 118 | /* initialize last tick */ |
104 | cyclone_interpolator.addr = cyclone_timer; | 119 | cyclone_mc = cyclone_timer; |
105 | register_time_interpolator(&cyclone_interpolator); | 120 | clocksource_cyclone.fsys_mmio = cyclone_timer; |
121 | clocksource_cyclone.mult = clocksource_hz2mult(CYCLONE_TIMER_FREQ, | ||
122 | clocksource_cyclone.shift); | ||
123 | clocksource_register(&clocksource_cyclone); | ||
106 | 124 | ||
107 | return 0; | 125 | return 0; |
108 | } | 126 | } |