diff options
| author | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-22 13:06:44 -0500 |
|---|---|---|
| committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-22 13:06:44 -0500 |
| commit | 0bd2af46839ad6262d25714a6ec0365db9d6b98f (patch) | |
| tree | dcced72d230d69fd0c5816ac6dd03ab84799a93e /arch/sh/kernel/timers/timer-tmu.c | |
| parent | e138a5d2356729b8752e88520cc1525fae9794ac (diff) | |
| parent | f26b90440cd74c78fe10c9bd5160809704a9627c (diff) | |
Merge ../scsi-rc-fixes-2.6
Diffstat (limited to 'arch/sh/kernel/timers/timer-tmu.c')
| -rw-r--r-- | arch/sh/kernel/timers/timer-tmu.c | 63 |
1 files changed, 4 insertions, 59 deletions
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c index 205816fcf0da..24927015dc31 100644 --- a/arch/sh/kernel/timers/timer-tmu.c +++ b/arch/sh/kernel/timers/timer-tmu.c | |||
| @@ -80,8 +80,7 @@ static unsigned long tmu_timer_get_offset(void) | |||
| 80 | return count; | 80 | return count; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | static irqreturn_t tmu_timer_interrupt(int irq, void *dev_id, | 83 | static irqreturn_t tmu_timer_interrupt(int irq, void *dummy) |
| 84 | struct pt_regs *regs) | ||
| 85 | { | 84 | { |
| 86 | unsigned long timer_status; | 85 | unsigned long timer_status; |
| 87 | 86 | ||
| @@ -98,7 +97,7 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dev_id, | |||
| 98 | * locally disabled. -arca | 97 | * locally disabled. -arca |
| 99 | */ | 98 | */ |
| 100 | write_seqlock(&xtime_lock); | 99 | write_seqlock(&xtime_lock); |
| 101 | handle_timer_tick(regs); | 100 | handle_timer_tick(); |
| 102 | write_sequnlock(&xtime_lock); | 101 | write_sequnlock(&xtime_lock); |
| 103 | 102 | ||
| 104 | return IRQ_HANDLED; | 103 | return IRQ_HANDLED; |
| @@ -111,60 +110,6 @@ static struct irqaction tmu_irq = { | |||
| 111 | .mask = CPU_MASK_NONE, | 110 | .mask = CPU_MASK_NONE, |
| 112 | }; | 111 | }; |
| 113 | 112 | ||
| 114 | /* | ||
| 115 | * Hah! We'll see if this works (switching from usecs to nsecs). | ||
| 116 | */ | ||
| 117 | static unsigned long tmu_timer_get_frequency(void) | ||
| 118 | { | ||
| 119 | u32 freq; | ||
| 120 | struct timespec ts1, ts2; | ||
| 121 | unsigned long diff_nsec; | ||
| 122 | unsigned long factor; | ||
| 123 | |||
| 124 | /* Setup the timer: We don't want to generate interrupts, just | ||
| 125 | * have it count down at its natural rate. | ||
| 126 | */ | ||
| 127 | ctrl_outb(0, TMU_TSTR); | ||
| 128 | #if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) | ||
| 129 | ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); | ||
| 130 | #endif | ||
| 131 | ctrl_outw(TMU0_TCR_CALIB, TMU0_TCR); | ||
| 132 | ctrl_outl(0xffffffff, TMU0_TCOR); | ||
| 133 | ctrl_outl(0xffffffff, TMU0_TCNT); | ||
| 134 | |||
| 135 | rtc_sh_get_time(&ts2); | ||
| 136 | |||
| 137 | do { | ||
| 138 | rtc_sh_get_time(&ts1); | ||
| 139 | } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); | ||
| 140 | |||
| 141 | /* actually start the timer */ | ||
| 142 | ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); | ||
| 143 | |||
| 144 | do { | ||
| 145 | rtc_sh_get_time(&ts2); | ||
| 146 | } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); | ||
| 147 | |||
| 148 | freq = 0xffffffff - ctrl_inl(TMU0_TCNT); | ||
| 149 | if (ts2.tv_nsec < ts1.tv_nsec) { | ||
| 150 | ts2.tv_nsec += 1000000000; | ||
| 151 | ts2.tv_sec--; | ||
| 152 | } | ||
| 153 | |||
| 154 | diff_nsec = (ts2.tv_sec - ts1.tv_sec) * 1000000000 + (ts2.tv_nsec - ts1.tv_nsec); | ||
| 155 | |||
| 156 | /* this should work well if the RTC has a precision of n Hz, where | ||
| 157 | * n is an integer. I don't think we have to worry about the other | ||
| 158 | * cases. */ | ||
| 159 | factor = (1000000000 + diff_nsec/2) / diff_nsec; | ||
| 160 | |||
| 161 | if (factor * diff_nsec > 1100000000 || | ||
| 162 | factor * diff_nsec < 900000000) | ||
| 163 | panic("weird RTC (diff_nsec %ld)", diff_nsec); | ||
| 164 | |||
| 165 | return freq * factor; | ||
| 166 | } | ||
| 167 | |||
| 168 | static void tmu_clk_init(struct clk *clk) | 113 | static void tmu_clk_init(struct clk *clk) |
| 169 | { | 114 | { |
| 170 | u8 divisor = TMU0_TCR_INIT & 0x7; | 115 | u8 divisor = TMU0_TCR_INIT & 0x7; |
| @@ -232,12 +177,12 @@ struct sys_timer_ops tmu_timer_ops = { | |||
| 232 | .init = tmu_timer_init, | 177 | .init = tmu_timer_init, |
| 233 | .start = tmu_timer_start, | 178 | .start = tmu_timer_start, |
| 234 | .stop = tmu_timer_stop, | 179 | .stop = tmu_timer_stop, |
| 235 | .get_frequency = tmu_timer_get_frequency, | 180 | #ifndef CONFIG_GENERIC_TIME |
| 236 | .get_offset = tmu_timer_get_offset, | 181 | .get_offset = tmu_timer_get_offset, |
| 182 | #endif | ||
| 237 | }; | 183 | }; |
| 238 | 184 | ||
| 239 | struct sys_timer tmu_timer = { | 185 | struct sys_timer tmu_timer = { |
| 240 | .name = "tmu", | 186 | .name = "tmu", |
| 241 | .ops = &tmu_timer_ops, | 187 | .ops = &tmu_timer_ops, |
| 242 | }; | 188 | }; |
| 243 | |||
