reset.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright (c) 2014 MediaTek Inc.
  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. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/mfd/syscon.h>
  14. #include <linux/module.h>
  15. #include <linux/of.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/regmap.h>
  18. #include <linux/reset-controller.h>
  19. #include <linux/slab.h>
  20. #include "clk-mtk.h"
  21. struct mtk_reset {
  22. struct regmap *regmap;
  23. int regofs;
  24. struct reset_controller_dev rcdev;
  25. };
  26. static int mtk_reset_assert(struct reset_controller_dev *rcdev,
  27. unsigned long id)
  28. {
  29. struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
  30. return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
  31. BIT(id % 32), ~0);
  32. }
  33. static int mtk_reset_deassert(struct reset_controller_dev *rcdev,
  34. unsigned long id)
  35. {
  36. struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev);
  37. return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2),
  38. BIT(id % 32), 0);
  39. }
  40. static int mtk_reset(struct reset_controller_dev *rcdev,
  41. unsigned long id)
  42. {
  43. int ret;
  44. ret = mtk_reset_assert(rcdev, id);
  45. if (ret)
  46. return ret;
  47. return mtk_reset_deassert(rcdev, id);
  48. }
  49. static struct reset_control_ops mtk_reset_ops = {
  50. .assert = mtk_reset_assert,
  51. .deassert = mtk_reset_deassert,
  52. .reset = mtk_reset,
  53. };
  54. void mtk_register_reset_controller(struct device_node *np,
  55. unsigned int num_regs, int regofs)
  56. {
  57. struct mtk_reset *data;
  58. int ret;
  59. struct regmap *regmap;
  60. regmap = syscon_node_to_regmap(np);
  61. if (IS_ERR(regmap)) {
  62. pr_err("Cannot find regmap for %s: %ld\n", np->full_name,
  63. PTR_ERR(regmap));
  64. return;
  65. }
  66. data = kzalloc(sizeof(*data), GFP_KERNEL);
  67. if (!data)
  68. return;
  69. data->regmap = regmap;
  70. data->regofs = regofs;
  71. data->rcdev.owner = THIS_MODULE;
  72. data->rcdev.nr_resets = num_regs * 32;
  73. data->rcdev.ops = &mtk_reset_ops;
  74. data->rcdev.of_node = np;
  75. ret = reset_controller_register(&data->rcdev);
  76. if (ret) {
  77. pr_err("could not register reset controller: %d\n", ret);
  78. kfree(data);
  79. return;
  80. }
  81. }