pinctrl-utils.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Utils functions to implement the pincontrol driver.
  4. *
  5. * Copyright (c) 2013, NVIDIA Corporation.
  6. *
  7. * Author: Laxman Dewangan <[email protected]>
  8. */
  9. #include <linux/device.h>
  10. #include <linux/export.h>
  11. #include <linux/kernel.h>
  12. #include <linux/pinctrl/pinctrl.h>
  13. #include <linux/of.h>
  14. #include <linux/slab.h>
  15. #include "core.h"
  16. #include "pinctrl-utils.h"
  17. int pinctrl_utils_reserve_map(struct pinctrl_dev *pctldev,
  18. struct pinctrl_map **map, unsigned *reserved_maps,
  19. unsigned *num_maps, unsigned reserve)
  20. {
  21. unsigned old_num = *reserved_maps;
  22. unsigned new_num = *num_maps + reserve;
  23. struct pinctrl_map *new_map;
  24. if (old_num >= new_num)
  25. return 0;
  26. new_map = krealloc_array(*map, new_num, sizeof(*new_map), GFP_KERNEL);
  27. if (!new_map) {
  28. dev_err(pctldev->dev, "krealloc(map) failed\n");
  29. return -ENOMEM;
  30. }
  31. memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));
  32. *map = new_map;
  33. *reserved_maps = new_num;
  34. return 0;
  35. }
  36. EXPORT_SYMBOL_GPL(pinctrl_utils_reserve_map);
  37. int pinctrl_utils_add_map_mux(struct pinctrl_dev *pctldev,
  38. struct pinctrl_map **map, unsigned *reserved_maps,
  39. unsigned *num_maps, const char *group,
  40. const char *function)
  41. {
  42. if (WARN_ON(*num_maps == *reserved_maps))
  43. return -ENOSPC;
  44. (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
  45. (*map)[*num_maps].data.mux.group = group;
  46. (*map)[*num_maps].data.mux.function = function;
  47. (*num_maps)++;
  48. return 0;
  49. }
  50. EXPORT_SYMBOL_GPL(pinctrl_utils_add_map_mux);
  51. int pinctrl_utils_add_map_configs(struct pinctrl_dev *pctldev,
  52. struct pinctrl_map **map, unsigned *reserved_maps,
  53. unsigned *num_maps, const char *group,
  54. unsigned long *configs, unsigned num_configs,
  55. enum pinctrl_map_type type)
  56. {
  57. unsigned long *dup_configs;
  58. if (WARN_ON(*num_maps == *reserved_maps))
  59. return -ENOSPC;
  60. dup_configs = kmemdup(configs, num_configs * sizeof(*dup_configs),
  61. GFP_KERNEL);
  62. if (!dup_configs)
  63. return -ENOMEM;
  64. (*map)[*num_maps].type = type;
  65. (*map)[*num_maps].data.configs.group_or_pin = group;
  66. (*map)[*num_maps].data.configs.configs = dup_configs;
  67. (*map)[*num_maps].data.configs.num_configs = num_configs;
  68. (*num_maps)++;
  69. return 0;
  70. }
  71. EXPORT_SYMBOL_GPL(pinctrl_utils_add_map_configs);
  72. int pinctrl_utils_add_config(struct pinctrl_dev *pctldev,
  73. unsigned long **configs, unsigned *num_configs,
  74. unsigned long config)
  75. {
  76. unsigned old_num = *num_configs;
  77. unsigned new_num = old_num + 1;
  78. unsigned long *new_configs;
  79. new_configs = krealloc(*configs, sizeof(*new_configs) * new_num,
  80. GFP_KERNEL);
  81. if (!new_configs) {
  82. dev_err(pctldev->dev, "krealloc(configs) failed\n");
  83. return -ENOMEM;
  84. }
  85. new_configs[old_num] = config;
  86. *configs = new_configs;
  87. *num_configs = new_num;
  88. return 0;
  89. }
  90. EXPORT_SYMBOL_GPL(pinctrl_utils_add_config);
  91. void pinctrl_utils_free_map(struct pinctrl_dev *pctldev,
  92. struct pinctrl_map *map, unsigned num_maps)
  93. {
  94. int i;
  95. for (i = 0; i < num_maps; i++) {
  96. switch (map[i].type) {
  97. case PIN_MAP_TYPE_CONFIGS_GROUP:
  98. case PIN_MAP_TYPE_CONFIGS_PIN:
  99. kfree(map[i].data.configs.configs);
  100. break;
  101. default:
  102. break;
  103. }
  104. }
  105. kfree(map);
  106. }
  107. EXPORT_SYMBOL_GPL(pinctrl_utils_free_map);