clock.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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/platform_device.h>
  13. #include <linux/delay.h>
  14. #include <asm/clkdev.h>
  15. #include <mach/pxa2xx-regs.h>
  16. #include <mach/hardware.h>
  17. #include "devices.h"
  18. #include "generic.h"
  19. #include "clock.h"
  20. static DEFINE_SPINLOCK(clocks_lock);
  21. int clk_enable(struct clk *clk)
  22. {
  23. unsigned long flags;
  24. spin_lock_irqsave(&clocks_lock, flags);
  25. if (clk->enabled++ == 0)
  26. clk->ops->enable(clk);
  27. spin_unlock_irqrestore(&clocks_lock, flags);
  28. if (clk->delay)
  29. udelay(clk->delay);
  30. return 0;
  31. }
  32. EXPORT_SYMBOL(clk_enable);
  33. void clk_disable(struct clk *clk)
  34. {
  35. unsigned long flags;
  36. WARN_ON(clk->enabled == 0);
  37. spin_lock_irqsave(&clocks_lock, flags);
  38. if (--clk->enabled == 0)
  39. clk->ops->disable(clk);
  40. spin_unlock_irqrestore(&clocks_lock, flags);
  41. }
  42. EXPORT_SYMBOL(clk_disable);
  43. unsigned long clk_get_rate(struct clk *clk)
  44. {
  45. unsigned long rate;
  46. rate = clk->rate;
  47. if (clk->ops->getrate)
  48. rate = clk->ops->getrate(clk);
  49. return rate;
  50. }
  51. EXPORT_SYMBOL(clk_get_rate);
  52. void clk_cken_enable(struct clk *clk)
  53. {
  54. CKEN |= 1 << clk->cken;
  55. }
  56. void clk_cken_disable(struct clk *clk)
  57. {
  58. CKEN &= ~(1 << clk->cken);
  59. }
  60. const struct clkops clk_cken_ops = {
  61. .enable = clk_cken_enable,
  62. .disable = clk_cken_disable,
  63. };
  64. void clks_register(struct clk_lookup *clks, size_t num)
  65. {
  66. int i;
  67. for (i = 0; i < num; i++)
  68. clkdev_add(&clks[i]);
  69. }
  70. int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
  71. struct device *dev)
  72. {
  73. struct clk *r = clk_get(dev, id);
  74. struct clk_lookup *l;
  75. if (!r)
  76. return -ENODEV;
  77. l = clkdev_alloc(r, alias, alias_dev_name);
  78. clk_put(r);
  79. if (!l)
  80. return -ENODEV;
  81. clkdev_add(l);
  82. return 0;
  83. }