[ARM] 3427/1: ARM: OMAP: 2/8 Update timers

Patch from Tony Lindgren

Update OMAP timers from linux-omap tree. The highlights of the
patch are:

- Move timer32k code from mach-omap1 to plat-omap and make it
work also on omap24xx by Tony Lindgren
- Add support for dmtimer idle check for PM by Tuukka Tikkanen

Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by Tony Lindgren and committed by Russell King a569c6ec b824efae

+362 -199
-197
arch/arm/mach-omap1/time.c
··· 51 51 52 52 struct sys_timer omap_timer; 53 53 54 - #ifdef CONFIG_OMAP_MPU_TIMER 55 - 56 54 /* 57 55 * --------------------------------------------------------------------------- 58 56 * MPU timer ··· 220 222 221 223 return cycles_2_ns(ticks64); 222 224 } 223 - #endif /* CONFIG_OMAP_MPU_TIMER */ 224 - 225 - #ifdef CONFIG_OMAP_32K_TIMER 226 - 227 - #ifdef CONFIG_ARCH_OMAP15XX 228 - #error OMAP 32KHz timer does not currently work on 15XX! 229 - #endif 230 - 231 - /* 232 - * --------------------------------------------------------------------------- 233 - * 32KHz OS timer 234 - * 235 - * This currently works only on 16xx, as 1510 does not have the continuous 236 - * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track 237 - * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer 238 - * on 1510 would be possible, but the timer would not be as accurate as 239 - * with the 32KHz synchronized timer. 240 - * --------------------------------------------------------------------------- 241 - */ 242 - #define OMAP_32K_TIMER_BASE 0xfffb9000 243 - #define OMAP_32K_TIMER_CR 0x08 244 - #define OMAP_32K_TIMER_TVR 0x00 245 - #define OMAP_32K_TIMER_TCR 0x04 246 - 247 - #define OMAP_32K_TICKS_PER_HZ (32768 / HZ) 248 - 249 - /* 250 - * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 251 - * so with HZ = 100, TVR = 327.68. 252 - */ 253 - #define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) 254 - #define TIMER_32K_SYNCHRONIZED 0xfffbc410 255 - 256 - #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ 257 - (((nr_jiffies) * (clock_rate)) / HZ) 258 - 259 - static inline void omap_32k_timer_write(int val, int reg) 260 - { 261 - omap_writew(val, reg + OMAP_32K_TIMER_BASE); 262 - } 263 - 264 - static inline unsigned long omap_32k_timer_read(int reg) 265 - { 266 - return omap_readl(reg + OMAP_32K_TIMER_BASE) & 0xffffff; 267 - } 268 - 269 - /* 270 - * The 32KHz synchronized timer is an additional timer on 16xx. 271 - * It is always running. 272 - */ 273 - static inline unsigned long omap_32k_sync_timer_read(void) 274 - { 275 - return omap_readl(TIMER_32K_SYNCHRONIZED); 276 - } 277 - 278 - static inline void omap_32k_timer_start(unsigned long load_val) 279 - { 280 - omap_32k_timer_write(load_val, OMAP_32K_TIMER_TVR); 281 - omap_32k_timer_write(0x0f, OMAP_32K_TIMER_CR); 282 - } 283 - 284 - static inline void omap_32k_timer_stop(void) 285 - { 286 - omap_32k_timer_write(0x0, OMAP_32K_TIMER_CR); 287 - } 288 - 289 - /* 290 - * Rounds down to nearest usec. Note that this will overflow for larger values. 291 - */ 292 - static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k) 293 - { 294 - return (ticks_32k * 5*5*5*5*5*5) >> 9; 295 - } 296 - 297 - /* 298 - * Rounds down to nearest nsec. 299 - */ 300 - static inline unsigned long long 301 - omap_32k_ticks_to_nsecs(unsigned long ticks_32k) 302 - { 303 - return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9; 304 - } 305 - 306 - static unsigned long omap_32k_last_tick = 0; 307 - 308 - /* 309 - * Returns elapsed usecs since last 32k timer interrupt 310 - */ 311 - static unsigned long omap_32k_timer_gettimeoffset(void) 312 - { 313 - unsigned long now = omap_32k_sync_timer_read(); 314 - return omap_32k_ticks_to_usecs(now - omap_32k_last_tick); 315 - } 316 - 317 - /* 318 - * Returns current time from boot in nsecs. It's OK for this to wrap 319 - * around for now, as it's just a relative time stamp. 320 - */ 321 - unsigned long long sched_clock(void) 322 - { 323 - return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read()); 324 - } 325 - 326 - /* 327 - * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this 328 - * function is also called from other interrupts to remove latency 329 - * issues with dynamic tick. In the dynamic tick case, we need to lock 330 - * with irqsave. 331 - */ 332 - static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, 333 - struct pt_regs *regs) 334 - { 335 - unsigned long flags; 336 - unsigned long now; 337 - 338 - write_seqlock_irqsave(&xtime_lock, flags); 339 - now = omap_32k_sync_timer_read(); 340 - 341 - while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { 342 - omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; 343 - timer_tick(regs); 344 - } 345 - 346 - /* Restart timer so we don't drift off due to modulo or dynamic tick. 347 - * By default we program the next timer to be continuous to avoid 348 - * latencies during high system load. During dynamic tick operation the 349 - * continuous timer can be overridden from pm_idle to be longer. 350 - */ 351 - omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); 352 - write_sequnlock_irqrestore(&xtime_lock, flags); 353 - 354 - return IRQ_HANDLED; 355 - } 356 - 357 - #ifdef CONFIG_NO_IDLE_HZ 358 - /* 359 - * Programs the next timer interrupt needed. Called when dynamic tick is 360 - * enabled, and to reprogram the ticks to skip from pm_idle. Note that 361 - * we can keep the timer continuous, and don't need to set it to run in 362 - * one-shot mode. This is because the timer will get reprogrammed again 363 - * after next interrupt. 364 - */ 365 - void omap_32k_timer_reprogram(unsigned long next_tick) 366 - { 367 - omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); 368 - } 369 - 370 - static struct irqaction omap_32k_timer_irq; 371 - extern struct timer_update_handler timer_update; 372 - 373 - static int omap_32k_timer_enable_dyn_tick(void) 374 - { 375 - /* No need to reprogram timer, just use the next interrupt */ 376 - return 0; 377 - } 378 - 379 - static int omap_32k_timer_disable_dyn_tick(void) 380 - { 381 - omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); 382 - return 0; 383 - } 384 - 385 - static struct dyn_tick_timer omap_dyn_tick_timer = { 386 - .enable = omap_32k_timer_enable_dyn_tick, 387 - .disable = omap_32k_timer_disable_dyn_tick, 388 - .reprogram = omap_32k_timer_reprogram, 389 - .handler = omap_32k_timer_interrupt, 390 - }; 391 - #endif /* CONFIG_NO_IDLE_HZ */ 392 - 393 - static struct irqaction omap_32k_timer_irq = { 394 - .name = "32KHz timer", 395 - .flags = SA_INTERRUPT | SA_TIMER, 396 - .handler = omap_32k_timer_interrupt, 397 - }; 398 - 399 - static __init void omap_init_32k_timer(void) 400 - { 401 - 402 - #ifdef CONFIG_NO_IDLE_HZ 403 - omap_timer.dyn_tick = &omap_dyn_tick_timer; 404 - #endif 405 - 406 - setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); 407 - omap_timer.offset = omap_32k_timer_gettimeoffset; 408 - omap_32k_last_tick = omap_32k_sync_timer_read(); 409 - omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); 410 - } 411 - #endif /* CONFIG_OMAP_32K_TIMER */ 412 225 413 226 /* 414 227 * --------------------------------------------------------------------------- ··· 228 419 */ 229 420 static void __init omap_timer_init(void) 230 421 { 231 - #if defined(CONFIG_OMAP_MPU_TIMER) 232 422 omap_init_mpu_timer(); 233 - #elif defined(CONFIG_OMAP_32K_TIMER) 234 - omap_init_32k_timer(); 235 - #else 236 - #error No system timer selected in Kconfig! 237 - #endif 238 423 } 239 424 240 425 struct sys_timer omap_timer = {
+2 -2
arch/arm/plat-omap/Kconfig
··· 70 70 71 71 config OMAP_32K_TIMER 72 72 bool "Use 32KHz timer" 73 - depends on ARCH_OMAP16XX 73 + depends on ARCH_OMAP16XX || ARCH_OMAP24XX 74 74 help 75 75 Select this option if you want to enable the OMAP 32KHz timer. 76 76 This timer saves power compared to the OMAP_MPU_TIMER, and has 77 77 support for no tick during idle. The 32KHz timer provides less 78 78 intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is 79 - currently only available for OMAP-16xx. 79 + currently only available for OMAP16XX and 24XX. 80 80 81 81 endchoice 82 82
+26
arch/arm/plat-omap/dmtimer.c
··· 97 97 } 98 98 99 99 100 + /** 101 + * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR 102 + * @inputmask: current value of idlect mask 103 + */ 104 + __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) 105 + { 106 + int n; 107 + 108 + /* If ARMXOR cannot be idled this function call is unnecessary */ 109 + if (!(inputmask & (1 << 1))) 110 + return inputmask; 111 + 112 + /* If any active timer is using ARMXOR return modified mask */ 113 + for (n = 0; dm_timers[n].base; ++n) 114 + if (omap_dm_timer_read_reg(&dm_timers[n], OMAP_TIMER_CTRL_REG)& 115 + OMAP_TIMER_CTRL_ST) { 116 + if (((omap_readl(MOD_CONF_CTRL_1)>>(n*2)) & 0x03) == 0) 117 + inputmask &= ~(1 << 1); 118 + else 119 + inputmask &= ~(1 << 2); 120 + } 121 + 122 + return inputmask; 123 + } 124 + 125 + 100 126 void omap_dm_timer_set_source(struct omap_dm_timer *timer, int source) 101 127 { 102 128 int n = (timer - dm_timers) << 1;
+325
arch/arm/plat-omap/timer32k.c
··· 1 + /* 2 + * linux/arch/arm/plat-omap/timer32k.c 3 + * 4 + * OMAP 32K Timer 5 + * 6 + * Copyright (C) 2004 - 2005 Nokia Corporation 7 + * Partial timer rewrite and additional dynamic tick timer support by 8 + * Tony Lindgen <tony@atomide.com> and 9 + * Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> 10 + * 11 + * MPU timer code based on the older MPU timer code for OMAP 12 + * Copyright (C) 2000 RidgeRun, Inc. 13 + * Author: Greg Lonnon <glonnon@ridgerun.com> 14 + * 15 + * This program is free software; you can redistribute it and/or modify it 16 + * under the terms of the GNU General Public License as published by the 17 + * Free Software Foundation; either version 2 of the License, or (at your 18 + * option) any later version. 19 + * 20 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 23 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 26 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 27 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 + * 31 + * You should have received a copy of the GNU General Public License along 32 + * with this program; if not, write to the Free Software Foundation, Inc., 33 + * 675 Mass Ave, Cambridge, MA 02139, USA. 34 + */ 35 + 36 + #include <linux/config.h> 37 + #include <linux/kernel.h> 38 + #include <linux/init.h> 39 + #include <linux/delay.h> 40 + #include <linux/interrupt.h> 41 + #include <linux/sched.h> 42 + #include <linux/spinlock.h> 43 + #include <linux/err.h> 44 + #include <linux/clk.h> 45 + 46 + #include <asm/system.h> 47 + #include <asm/hardware.h> 48 + #include <asm/io.h> 49 + #include <asm/leds.h> 50 + #include <asm/irq.h> 51 + #include <asm/mach/irq.h> 52 + #include <asm/mach/time.h> 53 + 54 + struct sys_timer omap_timer; 55 + 56 + /* 57 + * --------------------------------------------------------------------------- 58 + * 32KHz OS timer 59 + * 60 + * This currently works only on 16xx, as 1510 does not have the continuous 61 + * 32KHz synchronous timer. The 32KHz synchronous timer is used to keep track 62 + * of time in addition to the 32KHz OS timer. Using only the 32KHz OS timer 63 + * on 1510 would be possible, but the timer would not be as accurate as 64 + * with the 32KHz synchronized timer. 65 + * --------------------------------------------------------------------------- 66 + */ 67 + 68 + #if defined(CONFIG_ARCH_OMAP16XX) 69 + #define TIMER_32K_SYNCHRONIZED 0xfffbc410 70 + #elif defined(CONFIG_ARCH_OMAP24XX) 71 + #define TIMER_32K_SYNCHRONIZED 0x48004010 72 + #else 73 + #error OMAP 32KHz timer does not currently work on 15XX! 74 + #endif 75 + 76 + /* 16xx specific defines */ 77 + #define OMAP1_32K_TIMER_BASE 0xfffb9000 78 + #define OMAP1_32K_TIMER_CR 0x08 79 + #define OMAP1_32K_TIMER_TVR 0x00 80 + #define OMAP1_32K_TIMER_TCR 0x04 81 + 82 + /* 24xx specific defines */ 83 + #define OMAP2_GP_TIMER_BASE 0x48028000 84 + #define CM_CLKSEL_WKUP 0x48008440 85 + #define GP_TIMER_TIDR 0x00 86 + #define GP_TIMER_TISR 0x18 87 + #define GP_TIMER_TIER 0x1c 88 + #define GP_TIMER_TCLR 0x24 89 + #define GP_TIMER_TCRR 0x28 90 + #define GP_TIMER_TLDR 0x2c 91 + #define GP_TIMER_TTGR 0x30 92 + #define GP_TIMER_TSICR 0x40 93 + 94 + #define OMAP_32K_TICKS_PER_HZ (32768 / HZ) 95 + 96 + /* 97 + * TRM says 1 / HZ = ( TVR + 1) / 32768, so TRV = (32768 / HZ) - 1 98 + * so with HZ = 128, TVR = 255. 99 + */ 100 + #define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) 101 + 102 + #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ 103 + (((nr_jiffies) * (clock_rate)) / HZ) 104 + 105 + static inline void omap_32k_timer_write(int val, int reg) 106 + { 107 + if (cpu_class_is_omap1()) 108 + omap_writew(val, OMAP1_32K_TIMER_BASE + reg); 109 + 110 + if (cpu_is_omap24xx()) 111 + omap_writel(val, OMAP2_GP_TIMER_BASE + reg); 112 + } 113 + 114 + static inline unsigned long omap_32k_timer_read(int reg) 115 + { 116 + if (cpu_class_is_omap1()) 117 + return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff; 118 + 119 + if (cpu_is_omap24xx()) 120 + return omap_readl(OMAP2_GP_TIMER_BASE + reg); 121 + } 122 + 123 + /* 124 + * The 32KHz synchronized timer is an additional timer on 16xx. 125 + * It is always running. 126 + */ 127 + static inline unsigned long omap_32k_sync_timer_read(void) 128 + { 129 + return omap_readl(TIMER_32K_SYNCHRONIZED); 130 + } 131 + 132 + static inline void omap_32k_timer_start(unsigned long load_val) 133 + { 134 + if (cpu_class_is_omap1()) { 135 + omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR); 136 + omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR); 137 + } 138 + 139 + if (cpu_is_omap24xx()) { 140 + omap_32k_timer_write(0xffffffff - load_val, GP_TIMER_TCRR); 141 + omap_32k_timer_write((1 << 1), GP_TIMER_TIER); 142 + omap_32k_timer_write((1 << 1) | 1, GP_TIMER_TCLR); 143 + } 144 + } 145 + 146 + static inline void omap_32k_timer_stop(void) 147 + { 148 + if (cpu_class_is_omap1()) 149 + omap_32k_timer_write(0x0, OMAP1_32K_TIMER_CR); 150 + 151 + if (cpu_is_omap24xx()) 152 + omap_32k_timer_write(0x0, GP_TIMER_TCLR); 153 + } 154 + 155 + /* 156 + * Rounds down to nearest usec. Note that this will overflow for larger values. 157 + */ 158 + static inline unsigned long omap_32k_ticks_to_usecs(unsigned long ticks_32k) 159 + { 160 + return (ticks_32k * 5*5*5*5*5*5) >> 9; 161 + } 162 + 163 + /* 164 + * Rounds down to nearest nsec. 165 + */ 166 + static inline unsigned long long 167 + omap_32k_ticks_to_nsecs(unsigned long ticks_32k) 168 + { 169 + return (unsigned long long) ticks_32k * 1000 * 5*5*5*5*5*5 >> 9; 170 + } 171 + 172 + static unsigned long omap_32k_last_tick = 0; 173 + 174 + /* 175 + * Returns elapsed usecs since last 32k timer interrupt 176 + */ 177 + static unsigned long omap_32k_timer_gettimeoffset(void) 178 + { 179 + unsigned long now = omap_32k_sync_timer_read(); 180 + return omap_32k_ticks_to_usecs(now - omap_32k_last_tick); 181 + } 182 + 183 + /* 184 + * Returns current time from boot in nsecs. It's OK for this to wrap 185 + * around for now, as it's just a relative time stamp. 186 + */ 187 + unsigned long long sched_clock(void) 188 + { 189 + return omap_32k_ticks_to_nsecs(omap_32k_sync_timer_read()); 190 + } 191 + 192 + /* 193 + * Timer interrupt for 32KHz timer. When dynamic tick is enabled, this 194 + * function is also called from other interrupts to remove latency 195 + * issues with dynamic tick. In the dynamic tick case, we need to lock 196 + * with irqsave. 197 + */ 198 + static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, 199 + struct pt_regs *regs) 200 + { 201 + unsigned long flags; 202 + unsigned long now; 203 + 204 + write_seqlock_irqsave(&xtime_lock, flags); 205 + 206 + if (cpu_is_omap24xx()) { 207 + u32 status = omap_32k_timer_read(GP_TIMER_TISR); 208 + omap_32k_timer_write(status, GP_TIMER_TISR); 209 + } 210 + 211 + now = omap_32k_sync_timer_read(); 212 + 213 + while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) { 214 + omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ; 215 + timer_tick(regs); 216 + } 217 + 218 + /* Restart timer so we don't drift off due to modulo or dynamic tick. 219 + * By default we program the next timer to be continuous to avoid 220 + * latencies during high system load. During dynamic tick operation the 221 + * continuous timer can be overridden from pm_idle to be longer. 222 + */ 223 + omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); 224 + write_sequnlock_irqrestore(&xtime_lock, flags); 225 + 226 + return IRQ_HANDLED; 227 + } 228 + 229 + #ifdef CONFIG_NO_IDLE_HZ 230 + /* 231 + * Programs the next timer interrupt needed. Called when dynamic tick is 232 + * enabled, and to reprogram the ticks to skip from pm_idle. Note that 233 + * we can keep the timer continuous, and don't need to set it to run in 234 + * one-shot mode. This is because the timer will get reprogrammed again 235 + * after next interrupt. 236 + */ 237 + void omap_32k_timer_reprogram(unsigned long next_tick) 238 + { 239 + omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); 240 + } 241 + 242 + static struct irqaction omap_32k_timer_irq; 243 + extern struct timer_update_handler timer_update; 244 + 245 + static int omap_32k_timer_enable_dyn_tick(void) 246 + { 247 + /* No need to reprogram timer, just use the next interrupt */ 248 + return 0; 249 + } 250 + 251 + static int omap_32k_timer_disable_dyn_tick(void) 252 + { 253 + omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); 254 + return 0; 255 + } 256 + 257 + static struct dyn_tick_timer omap_dyn_tick_timer = { 258 + .enable = omap_32k_timer_enable_dyn_tick, 259 + .disable = omap_32k_timer_disable_dyn_tick, 260 + .reprogram = omap_32k_timer_reprogram, 261 + .handler = omap_32k_timer_interrupt, 262 + }; 263 + #endif /* CONFIG_NO_IDLE_HZ */ 264 + 265 + static struct irqaction omap_32k_timer_irq = { 266 + .name = "32KHz timer", 267 + .flags = SA_INTERRUPT | SA_TIMER, 268 + .handler = omap_32k_timer_interrupt, 269 + }; 270 + 271 + static struct clk * gpt1_ick; 272 + static struct clk * gpt1_fck; 273 + 274 + static __init void omap_init_32k_timer(void) 275 + { 276 + #ifdef CONFIG_NO_IDLE_HZ 277 + omap_timer.dyn_tick = &omap_dyn_tick_timer; 278 + #endif 279 + 280 + if (cpu_class_is_omap1()) 281 + setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); 282 + if (cpu_is_omap24xx()) 283 + setup_irq(37, &omap_32k_timer_irq); 284 + omap_timer.offset = omap_32k_timer_gettimeoffset; 285 + omap_32k_last_tick = omap_32k_sync_timer_read(); 286 + 287 + /* REVISIT: Check 24xx TIOCP_CFG settings after idle works */ 288 + if (cpu_is_omap24xx()) { 289 + omap_32k_timer_write(0, GP_TIMER_TCLR); 290 + omap_writel(0, CM_CLKSEL_WKUP); /* 32KHz clock source */ 291 + 292 + gpt1_ick = clk_get(NULL, "gpt1_ick"); 293 + if (IS_ERR(gpt1_ick)) 294 + printk(KERN_ERR "Could not get gpt1_ick\n"); 295 + else 296 + clk_enable(gpt1_ick); 297 + 298 + gpt1_fck = clk_get(NULL, "gpt1_fck"); 299 + if (IS_ERR(gpt1_fck)) 300 + printk(KERN_ERR "Could not get gpt1_fck\n"); 301 + else 302 + clk_enable(gpt1_fck); 303 + 304 + mdelay(100); /* Wait for clocks to stabilize */ 305 + 306 + omap_32k_timer_write(0x7, GP_TIMER_TISR); 307 + } 308 + 309 + omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); 310 + } 311 + 312 + /* 313 + * --------------------------------------------------------------------------- 314 + * Timer initialization 315 + * --------------------------------------------------------------------------- 316 + */ 317 + static void __init omap_timer_init(void) 318 + { 319 + omap_init_32k_timer(); 320 + } 321 + 322 + struct sys_timer omap_timer = { 323 + .init = omap_timer_init, 324 + .offset = NULL, /* Initialized later */ 325 + };
+1
include/asm-arm/arch-omap/dmtimer.h
··· 88 88 void omap_dm_timer_reset_counter(struct omap_dm_timer *timer); 89 89 90 90 int omap_dm_timers_active(void); 91 + u32 omap_dm_timer_modify_idlect_mask(u32 inputmask); 91 92 92 93 #endif /* __ASM_ARCH_TIMER_H */
+8
include/asm-arm/arch-omap/param.h
··· 1 + /* 2 + * linux/include/asm-arm/arch-omap/param.h 3 + * 4 + */ 5 + 6 + #ifdef CONFIG_OMAP_32K_TIMER_HZ 7 + #define HZ CONFIG_OMAP_32K_TIMER_HZ 8 + #endif