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 | } |
