clk-fixed-factor.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * Standard functionality for the common clock API.
  9. */
  10. #include <linux/module.h>
  11. #include <linux/clk-provider.h>
  12. #include <linux/slab.h>
  13. #include <linux/err.h>
  14. /*
  15. * DOC: basic fixed multiplier and divider clock that cannot gate
  16. *
  17. * Traits of this clock:
  18. * prepare - clk_prepare only ensures that parents are prepared
  19. * enable - clk_enable only ensures that parents are enabled
  20. * rate - rate is fixed. clk->rate = parent->rate / div * mult
  21. * parent - fixed parent. No clk_set_parent support
  22. */
  23. #define to_clk_fixed_factor(_hw) container_of(_hw, struct clk_fixed_factor, hw)
  24. static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
  25. unsigned long parent_rate)
  26. {
  27. struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
  28. unsigned long long int rate;
  29. rate = (unsigned long long int)parent_rate * fix->mult;
  30. do_div(rate, fix->div);
  31. return (unsigned long)rate;
  32. }
  33. static long clk_factor_round_rate(struct clk_hw *hw, unsigned long rate,
  34. unsigned long *prate)
  35. {
  36. struct clk_fixed_factor *fix = to_clk_fixed_factor(hw);
  37. if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
  38. unsigned long best_parent;
  39. best_parent = (rate / fix->mult) * fix->div;
  40. *prate = __clk_round_rate(__clk_get_parent(hw->clk),
  41. best_parent);
  42. }
  43. return (*prate / fix->div) * fix->mult;
  44. }
  45. static int clk_factor_set_rate(struct clk_hw *hw, unsigned long rate,
  46. unsigned long parent_rate)
  47. {
  48. return 0;
  49. }
  50. struct clk_ops clk_fixed_factor_ops = {
  51. .round_rate = clk_factor_round_rate,
  52. .set_rate = clk_factor_set_rate,
  53. .recalc_rate = clk_factor_recalc_rate,
  54. };
  55. EXPORT_SYMBOL_GPL(clk_fixed_factor_ops);
  56. struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
  57. const char *parent_name, unsigned long flags,
  58. unsigned int mult, unsigned int div)
  59. {
  60. struct clk_fixed_factor *fix;
  61. struct clk_init_data init;
  62. struct clk *clk;
  63. fix = kmalloc(sizeof(*fix), GFP_KERNEL);
  64. if (!fix) {
  65. pr_err("%s: could not allocate fixed factor clk\n", __func__);
  66. return ERR_PTR(-ENOMEM);
  67. }
  68. /* struct clk_fixed_factor assignments */
  69. fix->mult = mult;
  70. fix->div = div;
  71. fix->hw.init = &init;
  72. init.name = name;
  73. init.ops = &clk_fixed_factor_ops;
  74. init.flags = flags | CLK_IS_BASIC;
  75. init.parent_names = &parent_name;
  76. init.num_parents = 1;
  77. clk = clk_register(dev, &fix->hw);
  78. if (IS_ERR(clk))
  79. kfree(fix);
  80. return clk;
  81. }