clock.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * linux/arch/arm/mach-sa1100/clock.c
  3. */
  4. #include <linux/module.h>
  5. #include <linux/kernel.h>
  6. #include <linux/list.h>
  7. #include <linux/errno.h>
  8. #include <linux/err.h>
  9. #include <linux/string.h>
  10. #include <linux/clk.h>
  11. #include <linux/spinlock.h>
  12. #include <linux/mutex.h>
  13. #include <mach/hardware.h>
  14. /*
  15. * Very simple clock implementation - we only have one clock to
  16. * deal with at the moment, so we only match using the "name".
  17. */
  18. struct clk {
  19. struct list_head node;
  20. unsigned long rate;
  21. const char *name;
  22. unsigned int enabled;
  23. void (*enable)(void);
  24. void (*disable)(void);
  25. };
  26. static LIST_HEAD(clocks);
  27. static DEFINE_MUTEX(clocks_mutex);
  28. static DEFINE_SPINLOCK(clocks_lock);
  29. struct clk *clk_get(struct device *dev, const char *id)
  30. {
  31. struct clk *p, *clk = ERR_PTR(-ENOENT);
  32. mutex_lock(&clocks_mutex);
  33. list_for_each_entry(p, &clocks, node) {
  34. if (strcmp(id, p->name) == 0) {
  35. clk = p;
  36. break;
  37. }
  38. }
  39. mutex_unlock(&clocks_mutex);
  40. return clk;
  41. }
  42. EXPORT_SYMBOL(clk_get);
  43. void clk_put(struct clk *clk)
  44. {
  45. }
  46. EXPORT_SYMBOL(clk_put);
  47. int clk_enable(struct clk *clk)
  48. {
  49. unsigned long flags;
  50. spin_lock_irqsave(&clocks_lock, flags);
  51. if (clk->enabled++ == 0)
  52. clk->enable();
  53. spin_unlock_irqrestore(&clocks_lock, flags);
  54. return 0;
  55. }
  56. EXPORT_SYMBOL(clk_enable);
  57. void clk_disable(struct clk *clk)
  58. {
  59. unsigned long flags;
  60. WARN_ON(clk->enabled == 0);
  61. spin_lock_irqsave(&clocks_lock, flags);
  62. if (--clk->enabled == 0)
  63. clk->disable();
  64. spin_unlock_irqrestore(&clocks_lock, flags);
  65. }
  66. EXPORT_SYMBOL(clk_disable);
  67. unsigned long clk_get_rate(struct clk *clk)
  68. {
  69. return clk->rate;
  70. }
  71. EXPORT_SYMBOL(clk_get_rate);
  72. static void clk_gpio27_enable(void)
  73. {
  74. /*
  75. * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
  76. * (SA-1110 Developer's Manual, section 9.1.2.1)
  77. */
  78. GAFR |= GPIO_32_768kHz;
  79. GPDR |= GPIO_32_768kHz;
  80. TUCR = TUCR_3_6864MHz;
  81. }
  82. static void clk_gpio27_disable(void)
  83. {
  84. TUCR = 0;
  85. GPDR &= ~GPIO_32_768kHz;
  86. GAFR &= ~GPIO_32_768kHz;
  87. }
  88. static struct clk clk_gpio27 = {
  89. .name = "SA1111_CLK",
  90. .rate = 3686400,
  91. .enable = clk_gpio27_enable,
  92. .disable = clk_gpio27_disable,
  93. };
  94. int clk_register(struct clk *clk)
  95. {
  96. mutex_lock(&clocks_mutex);
  97. list_add(&clk->node, &clocks);
  98. mutex_unlock(&clocks_mutex);
  99. return 0;
  100. }
  101. EXPORT_SYMBOL(clk_register);
  102. void clk_unregister(struct clk *clk)
  103. {
  104. mutex_lock(&clocks_mutex);
  105. list_del(&clk->node);
  106. mutex_unlock(&clocks_mutex);
  107. }
  108. EXPORT_SYMBOL(clk_unregister);
  109. static int __init clk_init(void)
  110. {
  111. clk_register(&clk_gpio27);
  112. return 0;
  113. }
  114. arch_initcall(clk_init);