clock.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * linux/arch/arm/mach-sa1100/clock.c
  3. */
  4. #include <linux/module.h>
  5. #include <linux/kernel.h>
  6. #include <linux/device.h>
  7. #include <linux/list.h>
  8. #include <linux/errno.h>
  9. #include <linux/err.h>
  10. #include <linux/string.h>
  11. #include <linux/clk.h>
  12. #include <linux/spinlock.h>
  13. #include <linux/mutex.h>
  14. #include <linux/io.h>
  15. #include <linux/clkdev.h>
  16. #include <mach/hardware.h>
  17. #include <mach/generic.h>
  18. struct clkops {
  19. void (*enable)(struct clk *);
  20. void (*disable)(struct clk *);
  21. unsigned long (*get_rate)(struct clk *);
  22. };
  23. struct clk {
  24. const struct clkops *ops;
  25. unsigned int enabled;
  26. };
  27. #define DEFINE_CLK(_name, _ops) \
  28. struct clk clk_##_name = { \
  29. .ops = _ops, \
  30. }
  31. static DEFINE_SPINLOCK(clocks_lock);
  32. static void clk_gpio27_enable(struct clk *clk)
  33. {
  34. /*
  35. * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
  36. * (SA-1110 Developer's Manual, section 9.1.2.1)
  37. */
  38. GAFR |= GPIO_32_768kHz;
  39. GPDR |= GPIO_32_768kHz;
  40. TUCR = TUCR_3_6864MHz;
  41. }
  42. static void clk_gpio27_disable(struct clk *clk)
  43. {
  44. TUCR = 0;
  45. GPDR &= ~GPIO_32_768kHz;
  46. GAFR &= ~GPIO_32_768kHz;
  47. }
  48. static void clk_cpu_enable(struct clk *clk)
  49. {
  50. }
  51. static void clk_cpu_disable(struct clk *clk)
  52. {
  53. }
  54. static unsigned long clk_cpu_get_rate(struct clk *clk)
  55. {
  56. return sa11x0_getspeed(0) * 1000;
  57. }
  58. int clk_enable(struct clk *clk)
  59. {
  60. unsigned long flags;
  61. if (clk) {
  62. spin_lock_irqsave(&clocks_lock, flags);
  63. if (clk->enabled++ == 0)
  64. clk->ops->enable(clk);
  65. spin_unlock_irqrestore(&clocks_lock, flags);
  66. }
  67. return 0;
  68. }
  69. EXPORT_SYMBOL(clk_enable);
  70. void clk_disable(struct clk *clk)
  71. {
  72. unsigned long flags;
  73. if (clk) {
  74. WARN_ON(clk->enabled == 0);
  75. spin_lock_irqsave(&clocks_lock, flags);
  76. if (--clk->enabled == 0)
  77. clk->ops->disable(clk);
  78. spin_unlock_irqrestore(&clocks_lock, flags);
  79. }
  80. }
  81. EXPORT_SYMBOL(clk_disable);
  82. unsigned long clk_get_rate(struct clk *clk)
  83. {
  84. if (clk && clk->ops && clk->ops->get_rate)
  85. return clk->ops->get_rate(clk);
  86. return 0;
  87. }
  88. EXPORT_SYMBOL(clk_get_rate);
  89. const struct clkops clk_gpio27_ops = {
  90. .enable = clk_gpio27_enable,
  91. .disable = clk_gpio27_disable,
  92. };
  93. const struct clkops clk_cpu_ops = {
  94. .enable = clk_cpu_enable,
  95. .disable = clk_cpu_disable,
  96. .get_rate = clk_cpu_get_rate,
  97. };
  98. static DEFINE_CLK(gpio27, &clk_gpio27_ops);
  99. static DEFINE_CLK(cpu, &clk_cpu_ops);
  100. static unsigned long clk_36864_get_rate(struct clk *clk)
  101. {
  102. return 3686400;
  103. }
  104. static struct clkops clk_36864_ops = {
  105. .enable = clk_cpu_enable,
  106. .disable = clk_cpu_disable,
  107. .get_rate = clk_36864_get_rate,
  108. };
  109. static DEFINE_CLK(36864, &clk_36864_ops);
  110. static struct clk_lookup sa11xx_clkregs[] = {
  111. CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
  112. CLKDEV_INIT("sa1100-rtc", NULL, NULL),
  113. CLKDEV_INIT("sa11x0-fb", NULL, &clk_cpu),
  114. CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu),
  115. /* sa1111 names devices using internal offsets, PCMCIA is at 0x1800 */
  116. CLKDEV_INIT("1800", NULL, &clk_cpu),
  117. CLKDEV_INIT(NULL, "OSTIMER0", &clk_36864),
  118. };
  119. int __init sa11xx_clk_init(void)
  120. {
  121. clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
  122. return 0;
  123. }