timer-gp.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /*
  2. * linux/arch/arm/mach-omap2/timer-gp.c
  3. *
  4. * OMAP2 GP timer support.
  5. *
  6. * Copyright (C) 2005 Nokia Corporation
  7. * Author: Paul Mundt <paul.mundt@nokia.com>
  8. * Juha Yrjölä <juha.yrjola@nokia.com>
  9. * OMAP Dual-mode timer framework support by Timo Teras
  10. *
  11. * Some parts based off of TI's 24xx code:
  12. *
  13. * Copyright (C) 2004 Texas Instruments, Inc.
  14. *
  15. * Roughly modelled after the OMAP1 MPU timer code.
  16. *
  17. * This file is subject to the terms and conditions of the GNU General Public
  18. * License. See the file "COPYING" in the main directory of this archive
  19. * for more details.
  20. */
  21. #include <linux/init.h>
  22. #include <linux/time.h>
  23. #include <linux/interrupt.h>
  24. #include <linux/err.h>
  25. #include <linux/clk.h>
  26. #include <linux/delay.h>
  27. #include <asm/mach/time.h>
  28. #include <asm/arch/dmtimer.h>
  29. static struct omap_dm_timer *gptimer;
  30. static inline void omap2_gp_timer_start(unsigned long load_val)
  31. {
  32. omap_dm_timer_set_load(gptimer, 1, 0xffffffff - load_val);
  33. omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
  34. omap_dm_timer_start(gptimer);
  35. }
  36. static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
  37. {
  38. write_seqlock(&xtime_lock);
  39. omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW);
  40. timer_tick();
  41. write_sequnlock(&xtime_lock);
  42. return IRQ_HANDLED;
  43. }
  44. static struct irqaction omap2_gp_timer_irq = {
  45. .name = "gp timer",
  46. .flags = IRQF_DISABLED | IRQF_TIMER,
  47. .handler = omap2_gp_timer_interrupt,
  48. };
  49. static void __init omap2_gp_timer_init(void)
  50. {
  51. u32 tick_period;
  52. omap_dm_timer_init();
  53. gptimer = omap_dm_timer_request_specific(1);
  54. BUG_ON(gptimer == NULL);
  55. omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_SYS_CLK);
  56. tick_period = clk_get_rate(omap_dm_timer_get_fclk(gptimer)) / 100;
  57. tick_period -= 1;
  58. setup_irq(omap_dm_timer_get_irq(gptimer), &omap2_gp_timer_irq);
  59. omap2_gp_timer_start(tick_period);
  60. }
  61. struct sys_timer omap_timer = {
  62. .init = omap2_gp_timer_init,
  63. };