clk-max-gen.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. #include "clk-max-gen.h"
  33. struct max_gen_clk {
  34. struct regmap *regmap;
  35. u32 mask;
  36. u32 reg;
  37. struct clk_hw hw;
  38. };
  39. static struct max_gen_clk *to_max_gen_clk(struct clk_hw *hw)
  40. {
  41. return container_of(hw, struct max_gen_clk, hw);
  42. }
  43. static int max_gen_clk_prepare(struct clk_hw *hw)
  44. {
  45. struct max_gen_clk *max_gen = to_max_gen_clk(hw);
  46. return regmap_update_bits(max_gen->regmap, max_gen->reg,
  47. max_gen->mask, max_gen->mask);
  48. }
  49. static void max_gen_clk_unprepare(struct clk_hw *hw)
  50. {
  51. struct max_gen_clk *max_gen = to_max_gen_clk(hw);
  52. regmap_update_bits(max_gen->regmap, max_gen->reg,
  53. max_gen->mask, ~max_gen->mask);
  54. }
  55. static int max_gen_clk_is_prepared(struct clk_hw *hw)
  56. {
  57. struct max_gen_clk *max_gen = to_max_gen_clk(hw);
  58. int ret;
  59. u32 val;
  60. ret = regmap_read(max_gen->regmap, max_gen->reg, &val);
  61. if (ret < 0)
  62. return -EINVAL;
  63. return val & max_gen->mask;
  64. }
  65. static unsigned long max_gen_recalc_rate(struct clk_hw *hw,
  66. unsigned long parent_rate)
  67. {
  68. return 32768;
  69. }
  70. struct clk_ops max_gen_clk_ops = {
  71. .prepare = max_gen_clk_prepare,
  72. .unprepare = max_gen_clk_unprepare,
  73. .is_prepared = max_gen_clk_is_prepared,
  74. .recalc_rate = max_gen_recalc_rate,
  75. };
  76. EXPORT_SYMBOL_GPL(max_gen_clk_ops);
  77. static struct clk *max_gen_clk_register(struct device *dev,
  78. struct max_gen_clk *max_gen)
  79. {
  80. struct clk *clk;
  81. struct clk_hw *hw = &max_gen->hw;
  82. int ret;
  83. clk = devm_clk_register(dev, hw);
  84. if (IS_ERR(clk))
  85. return clk;
  86. ret = clk_register_clkdev(clk, hw->init->name, NULL);
  87. if (ret)
  88. return ERR_PTR(ret);
  89. return clk;
  90. }
  91. int max_gen_clk_probe(struct platform_device *pdev, struct regmap *regmap,
  92. u32 reg, struct clk_init_data *clks_init, int num_init)
  93. {
  94. int i, ret;
  95. struct max_gen_clk *max_gen_clks;
  96. struct clk **clocks;
  97. struct device *dev = pdev->dev.parent;
  98. const char *clk_name;
  99. struct clk_init_data *init;
  100. clocks = devm_kzalloc(dev, sizeof(struct clk *) * num_init, GFP_KERNEL);
  101. if (!clocks)
  102. return -ENOMEM;
  103. max_gen_clks = devm_kzalloc(dev, sizeof(struct max_gen_clk)
  104. * num_init, GFP_KERNEL);
  105. if (!max_gen_clks)
  106. return -ENOMEM;
  107. for (i = 0; i < num_init; i++) {
  108. max_gen_clks[i].regmap = regmap;
  109. max_gen_clks[i].mask = 1 << i;
  110. max_gen_clks[i].reg = reg;
  111. init = devm_kzalloc(dev, sizeof(*init), GFP_KERNEL);
  112. if (!init)
  113. return -ENOMEM;
  114. if (dev->of_node &&
  115. !of_property_read_string_index(dev->of_node,
  116. "clock-output-names",
  117. i, &clk_name))
  118. init->name = clk_name;
  119. else
  120. init->name = clks_init[i].name;
  121. init->ops = clks_init[i].ops;
  122. init->flags = clks_init[i].flags;
  123. max_gen_clks[i].hw.init = init;
  124. clocks[i] = max_gen_clk_register(dev, &max_gen_clks[i]);
  125. if (IS_ERR(clocks[i])) {
  126. ret = PTR_ERR(clocks[i]);
  127. dev_err(dev, "failed to register %s\n",
  128. max_gen_clks[i].hw.init->name);
  129. return ret;
  130. }
  131. }
  132. platform_set_drvdata(pdev, clocks);
  133. if (dev->of_node) {
  134. struct clk_onecell_data *of_data;
  135. of_data = devm_kzalloc(dev, sizeof(*of_data), GFP_KERNEL);
  136. if (!of_data)
  137. return -ENOMEM;
  138. of_data->clks = clocks;
  139. of_data->clk_num = num_init;
  140. ret = of_clk_add_provider(dev->of_node, of_clk_src_onecell_get,
  141. of_data);
  142. if (ret) {
  143. dev_err(dev, "failed to register OF clock provider\n");
  144. return ret;
  145. }
  146. }
  147. return 0;
  148. }
  149. EXPORT_SYMBOL_GPL(max_gen_clk_probe);
  150. int max_gen_clk_remove(struct platform_device *pdev, int num_init)
  151. {
  152. struct device *dev = pdev->dev.parent;
  153. if (dev->of_node)
  154. of_clk_del_provider(dev->of_node);
  155. return 0;
  156. }
  157. EXPORT_SYMBOL_GPL(max_gen_clk_remove);