clk-max-gen.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * clk-max-gen.c - Generic clock driver for Maxim PMICs clocks
  3. *
  4. * Copyright (C) 2014 Google, Inc
  5. *
  6. * Copyright (C) 2012 Samsung Electornics
  7. * Jonghwa Lee <jonghwa3.lee@samsung.com>
  8. *
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License as published by the
  11. * Free Software Foundation; either version 2 of the License, or (at your
  12. * option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * This driver is based on clk-max77686.c
  20. *
  21. */
  22. #include <linux/kernel.h>
  23. #include <linux/slab.h>
  24. #include <linux/err.h>
  25. #include <linux/regmap.h>
  26. #include <linux/platform_device.h>
  27. #include <linux/clk-provider.h>
  28. #include <linux/mutex.h>
  29. #include <linux/clkdev.h>
  30. #include <linux/of.h>
  31. #include <linux/export.h>
  32. struct max_gen_clk {
  33. struct regmap *regmap;
  34. u32 mask;
  35. u32 reg;
  36. struct clk_hw hw;
  37. };
  38. static struct max_gen_clk *to_max_gen_clk(struct clk_hw *hw)
  39. {
  40. return container_of(hw, struct max_gen_clk, hw);
  41. }
  42. static int max_gen_clk_prepare(struct clk_hw *hw)
  43. {
  44. struct max_gen_clk *max_gen = to_max_gen_clk(hw);
  45. return regmap_update_bits(max_gen->regmap, max_gen->reg,
  46. max_gen->mask, max_gen->mask);
  47. }
  48. static void max_gen_clk_unprepare(struct clk_hw *hw)
  49. {
  50. struct max_gen_clk *max_gen = to_max_gen_clk(hw);
  51. regmap_update_bits(max_gen->regmap, max_gen->reg,
  52. max_gen->mask, ~max_gen->mask);
  53. }
  54. static int max_gen_clk_is_prepared(struct clk_hw *hw)
  55. {
  56. struct max_gen_clk *max_gen = to_max_gen_clk(hw);
  57. int ret;
  58. u32 val;
  59. ret = regmap_read(max_gen->regmap, max_gen->reg, &val);
  60. if (ret < 0)
  61. return -EINVAL;
  62. return val & max_gen->mask;
  63. }
  64. static unsigned long max_gen_recalc_rate(struct clk_hw *hw,
  65. unsigned long parent_rate)
  66. {
  67. return 32768;
  68. }
  69. struct clk_ops max_gen_clk_ops = {
  70. .prepare = max_gen_clk_prepare,
  71. .unprepare = max_gen_clk_unprepare,
  72. .is_prepared = max_gen_clk_is_prepared,
  73. .recalc_rate = max_gen_recalc_rate,
  74. };
  75. EXPORT_SYMBOL_GPL(max_gen_clk_ops);
  76. static struct clk *max_gen_clk_register(struct device *dev,
  77. struct max_gen_clk *max_gen)
  78. {
  79. struct clk *clk;
  80. struct clk_hw *hw = &max_gen->hw;
  81. int ret;
  82. clk = devm_clk_register(dev, hw);
  83. if (IS_ERR(clk))
  84. return clk;
  85. ret = clk_register_clkdev(clk, hw->init->name, NULL);
  86. if (ret)
  87. return ERR_PTR(ret);
  88. return clk;
  89. }
  90. int max_gen_clk_probe(struct platform_device *pdev, struct regmap *regmap,
  91. u32 reg, struct clk_init_data *clks_init, int num_init)
  92. {
  93. int i, ret;
  94. struct max_gen_clk *max_gen_clks;
  95. struct clk **clocks;
  96. struct device *dev = pdev->dev.parent;
  97. const char *clk_name;
  98. struct clk_init_data *init;
  99. clocks = devm_kzalloc(dev, sizeof(struct clk *) * num_init, GFP_KERNEL);
  100. if (!clocks)
  101. return -ENOMEM;
  102. max_gen_clks = devm_kzalloc(dev, sizeof(struct max_gen_clk)
  103. * num_init, GFP_KERNEL);
  104. if (!max_gen_clks)
  105. return -ENOMEM;
  106. for (i = 0; i < num_init; i++) {
  107. max_gen_clks[i].regmap = regmap;
  108. max_gen_clks[i].mask = 1 << i;
  109. max_gen_clks[i].reg = reg;
  110. init = devm_kzalloc(dev, sizeof(*init), GFP_KERNEL);
  111. if (!init)
  112. return -ENOMEM;
  113. if (dev->of_node &&
  114. !of_property_read_string_index(dev->of_node,
  115. "clock-output-names",
  116. i, &clk_name))
  117. init->name = clk_name;
  118. else
  119. init->name = clks_init[i].name;
  120. init->ops = clks_init[i].ops;
  121. init->flags = clks_init[i].flags;
  122. max_gen_clks[i].hw.init = init;
  123. clocks[i] = max_gen_clk_register(dev, &max_gen_clks[i]);
  124. if (IS_ERR(clocks[i])) {
  125. ret = PTR_ERR(clocks[i]);
  126. dev_err(dev, "failed to register %s\n",
  127. max_gen_clks[i].hw.init->name);
  128. return ret;
  129. }
  130. }
  131. platform_set_drvdata(pdev, clocks);
  132. if (dev->of_node) {
  133. struct clk_onecell_data *of_data;
  134. of_data = devm_kzalloc(dev, sizeof(*of_data), GFP_KERNEL);
  135. if (!of_data)
  136. return -ENOMEM;
  137. of_data->clks = clocks;
  138. of_data->clk_num = num_init;
  139. ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
  140. of_data);
  141. if (ret) {
  142. dev_err(dev, "failed to register OF clock provider\n");
  143. return ret;
  144. }
  145. }
  146. return 0;
  147. }
  148. EXPORT_SYMBOL_GPL(max_gen_clk_probe);
  149. int max_gen_clk_remove(struct platform_device *pdev, int num_init)
  150. {
  151. struct device *dev = pdev->dev.parent;
  152. if (dev->of_node)
  153. of_clk_del_provider(dev->of_node);
  154. return 0;
  155. }
  156. EXPORT_SYMBOL_GPL(max_gen_clk_remove);