clock.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. struct clkops {
  18. void (*enable)(struct clk *);
  19. void (*disable)(struct clk *);
  20. unsigned long (*getrate)(struct clk *);
  21. };
  22. struct clk {
  23. const struct clkops *ops;
  24. unsigned long rate;
  25. unsigned int enabled;
  26. };
  27. #define INIT_CLKREG(_clk, _devname, _conname) \
  28. { \
  29. .clk = _clk, \
  30. .dev_id = _devname, \
  31. .con_id = _conname, \
  32. }
  33. #define DEFINE_CLK(_name, _ops, _rate) \
  34. struct clk clk_##_name = { \
  35. .ops = _ops, \
  36. .rate = _rate, \
  37. }
  38. static DEFINE_SPINLOCK(clocks_lock);
  39. static void clk_gpio27_enable(struct clk *clk)
  40. {
  41. /*
  42. * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
  43. * (SA-1110 Developer's Manual, section 9.1.2.1)
  44. */
  45. GAFR |= GPIO_32_768kHz;
  46. GPDR |= GPIO_32_768kHz;
  47. TUCR = TUCR_3_6864MHz;
  48. }
  49. static void clk_gpio27_disable(struct clk *clk)
  50. {
  51. TUCR = 0;
  52. GPDR &= ~GPIO_32_768kHz;
  53. GAFR &= ~GPIO_32_768kHz;
  54. }
  55. int clk_enable(struct clk *clk)
  56. {
  57. unsigned long flags;
  58. spin_lock_irqsave(&clocks_lock, flags);
  59. if (clk->enabled++ == 0)
  60. clk->ops->enable(clk);
  61. spin_unlock_irqrestore(&clocks_lock, flags);
  62. return 0;
  63. }
  64. EXPORT_SYMBOL(clk_enable);
  65. void clk_disable(struct clk *clk)
  66. {
  67. unsigned long flags;
  68. WARN_ON(clk->enabled == 0);
  69. spin_lock_irqsave(&clocks_lock, flags);
  70. if (--clk->enabled == 0)
  71. clk->ops->disable(clk);
  72. spin_unlock_irqrestore(&clocks_lock, flags);
  73. }
  74. EXPORT_SYMBOL(clk_disable);
  75. unsigned long clk_get_rate(struct clk *clk)
  76. {
  77. unsigned long rate;
  78. rate = clk->rate;
  79. if (clk->ops->getrate)
  80. rate = clk->ops->getrate(clk);
  81. return rate;
  82. }
  83. EXPORT_SYMBOL(clk_get_rate);
  84. const struct clkops clk_gpio27_ops = {
  85. .enable = clk_gpio27_enable,
  86. .disable = clk_gpio27_disable,
  87. };
  88. static void clk_dummy_enable(struct clk *clk) { }
  89. static void clk_dummy_disable(struct clk *clk) { }
  90. const struct clkops clk_dummy_ops = {
  91. .enable = clk_dummy_enable,
  92. .disable = clk_dummy_disable,
  93. };
  94. static DEFINE_CLK(gpio27, &clk_gpio27_ops, 3686400);
  95. static DEFINE_CLK(dummy, &clk_dummy_ops, 0);
  96. static struct clk_lookup sa11xx_clkregs[] = {
  97. INIT_CLKREG(&clk_gpio27, "sa1111.0", NULL),
  98. INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
  99. };
  100. static int __init sa11xx_clk_init(void)
  101. {
  102. clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
  103. return 0;
  104. }
  105. postcore_initcall(sa11xx_clk_init);