timer.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * This program is free software; you can redistribute it and/or modify it
  3. * under the terms of the GNU General Public License version 2 as published
  4. * by the Free Software Foundation.
  5. *
  6. * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
  7. */
  8. #include <linux/module.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/timer.h>
  12. #include <linux/of_gpio.h>
  13. #include <linux/clk.h>
  14. #include <asm/mach-ralink/ralink_regs.h>
  15. #define TIMER_REG_TMRSTAT 0x00
  16. #define TIMER_REG_TMR0LOAD 0x10
  17. #define TIMER_REG_TMR0CTL 0x18
  18. #define TMRSTAT_TMR0INT BIT(0)
  19. #define TMR0CTL_ENABLE BIT(7)
  20. #define TMR0CTL_MODE_PERIODIC BIT(4)
  21. #define TMR0CTL_PRESCALER 1
  22. #define TMR0CTL_PRESCALE_VAL (0xf - TMR0CTL_PRESCALER)
  23. #define TMR0CTL_PRESCALE_DIV (65536 / BIT(TMR0CTL_PRESCALER))
  24. struct rt_timer {
  25. struct device *dev;
  26. void __iomem *membase;
  27. int irq;
  28. unsigned long timer_freq;
  29. unsigned long timer_div;
  30. };
  31. static inline void rt_timer_w32(struct rt_timer *rt, u8 reg, u32 val)
  32. {
  33. __raw_writel(val, rt->membase + reg);
  34. }
  35. static inline u32 rt_timer_r32(struct rt_timer *rt, u8 reg)
  36. {
  37. return __raw_readl(rt->membase + reg);
  38. }
  39. static irqreturn_t rt_timer_irq(int irq, void *_rt)
  40. {
  41. struct rt_timer *rt = (struct rt_timer *) _rt;
  42. rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div);
  43. rt_timer_w32(rt, TIMER_REG_TMRSTAT, TMRSTAT_TMR0INT);
  44. return IRQ_HANDLED;
  45. }
  46. static int rt_timer_request(struct rt_timer *rt)
  47. {
  48. int err = request_irq(rt->irq, rt_timer_irq, 0,
  49. dev_name(rt->dev), rt);
  50. if (err) {
  51. dev_err(rt->dev, "failed to request irq\n");
  52. } else {
  53. u32 t = TMR0CTL_MODE_PERIODIC | TMR0CTL_PRESCALE_VAL;
  54. rt_timer_w32(rt, TIMER_REG_TMR0CTL, t);
  55. }
  56. return err;
  57. }
  58. static void rt_timer_free(struct rt_timer *rt)
  59. {
  60. free_irq(rt->irq, rt);
  61. }
  62. static int rt_timer_config(struct rt_timer *rt, unsigned long divisor)
  63. {
  64. if (rt->timer_freq < divisor)
  65. rt->timer_div = rt->timer_freq;
  66. else
  67. rt->timer_div = divisor;
  68. rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div);
  69. return 0;
  70. }
  71. static int rt_timer_enable(struct rt_timer *rt)
  72. {
  73. u32 t;
  74. rt_timer_w32(rt, TIMER_REG_TMR0LOAD, rt->timer_freq / rt->timer_div);
  75. t = rt_timer_r32(rt, TIMER_REG_TMR0CTL);
  76. t |= TMR0CTL_ENABLE;
  77. rt_timer_w32(rt, TIMER_REG_TMR0CTL, t);
  78. return 0;
  79. }
  80. static void rt_timer_disable(struct rt_timer *rt)
  81. {
  82. u32 t;
  83. t = rt_timer_r32(rt, TIMER_REG_TMR0CTL);
  84. t &= ~TMR0CTL_ENABLE;
  85. rt_timer_w32(rt, TIMER_REG_TMR0CTL, t);
  86. }
  87. static int rt_timer_probe(struct platform_device *pdev)
  88. {
  89. struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  90. struct rt_timer *rt;
  91. struct clk *clk;
  92. rt = devm_kzalloc(&pdev->dev, sizeof(*rt), GFP_KERNEL);
  93. if (!rt) {
  94. dev_err(&pdev->dev, "failed to allocate memory\n");
  95. return -ENOMEM;
  96. }
  97. rt->irq = platform_get_irq(pdev, 0);
  98. if (!rt->irq) {
  99. dev_err(&pdev->dev, "failed to load irq\n");
  100. return -ENOENT;
  101. }
  102. rt->membase = devm_ioremap_resource(&pdev->dev, res);
  103. if (IS_ERR(rt->membase))
  104. return PTR_ERR(rt->membase);
  105. clk = devm_clk_get(&pdev->dev, NULL);
  106. if (IS_ERR(clk)) {
  107. dev_err(&pdev->dev, "failed get clock rate\n");
  108. return PTR_ERR(clk);
  109. }
  110. rt->timer_freq = clk_get_rate(clk) / TMR0CTL_PRESCALE_DIV;
  111. if (!rt->timer_freq)
  112. return -EINVAL;
  113. rt->dev = &pdev->dev;
  114. platform_set_drvdata(pdev, rt);
  115. rt_timer_request(rt);
  116. rt_timer_config(rt, 2);
  117. rt_timer_enable(rt);
  118. dev_info(&pdev->dev, "maximum frequency is %luHz\n", rt->timer_freq);
  119. return 0;
  120. }
  121. static int rt_timer_remove(struct platform_device *pdev)
  122. {
  123. struct rt_timer *rt = platform_get_drvdata(pdev);
  124. rt_timer_disable(rt);
  125. rt_timer_free(rt);
  126. return 0;
  127. }
  128. static const struct of_device_id rt_timer_match[] = {
  129. { .compatible = "ralink,rt2880-timer" },
  130. {},
  131. };
  132. MODULE_DEVICE_TABLE(of, rt_timer_match);
  133. static struct platform_driver rt_timer_driver = {
  134. .probe = rt_timer_probe,
  135. .remove = rt_timer_remove,
  136. .driver = {
  137. .name = "rt-timer",
  138. .of_match_table = rt_timer_match
  139. },
  140. };
  141. module_platform_driver(rt_timer_driver);
  142. MODULE_DESCRIPTION("Ralink RT2880 timer");
  143. MODULE_AUTHOR("John Crispin <blogic@openwrt.org");
  144. MODULE_LICENSE("GPL");