clock.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * linux/arch/arm/mach-w90x900/clock.c
  3. *
  4. * Copyright (c) 2008 Nuvoton technology corporation
  5. *
  6. * Wan ZongShun <mcuos.com@gmail.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License.
  11. */
  12. #include <linux/module.h>
  13. #include <linux/kernel.h>
  14. #include <linux/list.h>
  15. #include <linux/errno.h>
  16. #include <linux/err.h>
  17. #include <linux/string.h>
  18. #include <linux/clk.h>
  19. #include <linux/spinlock.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/io.h>
  22. #include <mach/hardware.h>
  23. #include "clock.h"
  24. #define SUBCLK 0x24
  25. static DEFINE_SPINLOCK(clocks_lock);
  26. int clk_enable(struct clk *clk)
  27. {
  28. unsigned long flags;
  29. spin_lock_irqsave(&clocks_lock, flags);
  30. if (clk->enabled++ == 0)
  31. (clk->enable)(clk, 1);
  32. spin_unlock_irqrestore(&clocks_lock, flags);
  33. return 0;
  34. }
  35. EXPORT_SYMBOL(clk_enable);
  36. void clk_disable(struct clk *clk)
  37. {
  38. unsigned long flags;
  39. WARN_ON(clk->enabled == 0);
  40. spin_lock_irqsave(&clocks_lock, flags);
  41. if (--clk->enabled == 0)
  42. (clk->enable)(clk, 0);
  43. spin_unlock_irqrestore(&clocks_lock, flags);
  44. }
  45. EXPORT_SYMBOL(clk_disable);
  46. unsigned long clk_get_rate(struct clk *clk)
  47. {
  48. return 15000000;
  49. }
  50. EXPORT_SYMBOL(clk_get_rate);
  51. void nuc900_clk_enable(struct clk *clk, int enable)
  52. {
  53. unsigned int clocks = clk->cken;
  54. unsigned long clken;
  55. clken = __raw_readl(W90X900_VA_CLKPWR);
  56. if (enable)
  57. clken |= clocks;
  58. else
  59. clken &= ~clocks;
  60. __raw_writel(clken, W90X900_VA_CLKPWR);
  61. }
  62. void nuc900_subclk_enable(struct clk *clk, int enable)
  63. {
  64. unsigned int clocks = clk->cken;
  65. unsigned long clken;
  66. clken = __raw_readl(W90X900_VA_CLKPWR + SUBCLK);
  67. if (enable)
  68. clken |= clocks;
  69. else
  70. clken &= ~clocks;
  71. __raw_writel(clken, W90X900_VA_CLKPWR + SUBCLK);
  72. }