pinconf.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. /*
  2. * Core driver for the pin config portions of the pin control subsystem
  3. *
  4. * Copyright (C) 2011 ST-Ericsson SA
  5. * Written on behalf of Linaro for ST-Ericsson
  6. *
  7. * Author: Linus Walleij <linus.walleij@linaro.org>
  8. *
  9. * License terms: GNU General Public License (GPL) version 2
  10. */
  11. #define pr_fmt(fmt) "pinconfig core: " fmt
  12. #include <linux/kernel.h>
  13. #include <linux/module.h>
  14. #include <linux/init.h>
  15. #include <linux/device.h>
  16. #include <linux/slab.h>
  17. #include <linux/debugfs.h>
  18. #include <linux/seq_file.h>
  19. #include <linux/uaccess.h>
  20. #include <linux/pinctrl/machine.h>
  21. #include <linux/pinctrl/pinctrl.h>
  22. #include <linux/pinctrl/pinconf.h>
  23. #include "core.h"
  24. #include "pinconf.h"
  25. int pinconf_check_ops(struct pinctrl_dev *pctldev)
  26. {
  27. const struct pinconf_ops *ops = pctldev->desc->confops;
  28. /* We must be able to read out pin status */
  29. if (!ops->pin_config_get && !ops->pin_config_group_get) {
  30. dev_err(pctldev->dev,
  31. "pinconf must be able to read out pin status\n");
  32. return -EINVAL;
  33. }
  34. /* We have to be able to config the pins in SOME way */
  35. if (!ops->pin_config_set && !ops->pin_config_group_set) {
  36. dev_err(pctldev->dev,
  37. "pinconf has to be able to set a pins config\n");
  38. return -EINVAL;
  39. }
  40. return 0;
  41. }
  42. int pinconf_validate_map(struct pinctrl_map const *map, int i)
  43. {
  44. if (!map->data.configs.group_or_pin) {
  45. pr_err("failed to register map %s (%d): no group/pin given\n",
  46. map->name, i);
  47. return -EINVAL;
  48. }
  49. if (!map->data.configs.num_configs ||
  50. !map->data.configs.configs) {
  51. pr_err("failed to register map %s (%d): no configs given\n",
  52. map->name, i);
  53. return -EINVAL;
  54. }
  55. return 0;
  56. }
  57. int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
  58. unsigned long *config)
  59. {
  60. const struct pinconf_ops *ops = pctldev->desc->confops;
  61. if (!ops || !ops->pin_config_get) {
  62. dev_err(pctldev->dev, "cannot get pin configuration, missing "
  63. "pin_config_get() function in driver\n");
  64. return -EINVAL;
  65. }
  66. return ops->pin_config_get(pctldev, pin, config);
  67. }
  68. /**
  69. * pin_config_get() - get the configuration of a single pin parameter
  70. * @dev_name: name of the pin controller device for this pin
  71. * @name: name of the pin to get the config for
  72. * @config: the config pointed to by this argument will be filled in with the
  73. * current pin state, it can be used directly by drivers as a numeral, or
  74. * it can be dereferenced to any struct.
  75. */
  76. int pin_config_get(const char *dev_name, const char *name,
  77. unsigned long *config)
  78. {
  79. struct pinctrl_dev *pctldev;
  80. int pin;
  81. pctldev = get_pinctrl_dev_from_devname(dev_name);
  82. if (!pctldev) {
  83. pin = -EINVAL;
  84. return pin;
  85. }
  86. mutex_lock(&pctldev->mutex);
  87. pin = pin_get_from_name(pctldev, name);
  88. if (pin < 0)
  89. goto unlock;
  90. pin = pin_config_get_for_pin(pctldev, pin, config);
  91. unlock:
  92. mutex_unlock(&pctldev->mutex);
  93. return pin;
  94. }
  95. EXPORT_SYMBOL(pin_config_get);
  96. static int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
  97. unsigned long config)
  98. {
  99. const struct pinconf_ops *ops = pctldev->desc->confops;
  100. int ret;
  101. if (!ops || !ops->pin_config_set) {
  102. dev_err(pctldev->dev, "cannot configure pin, missing "
  103. "config function in driver\n");
  104. return -EINVAL;
  105. }
  106. ret = ops->pin_config_set(pctldev, pin, config);
  107. if (ret) {
  108. dev_err(pctldev->dev,
  109. "unable to set pin configuration on pin %d\n", pin);
  110. return ret;
  111. }
  112. return 0;
  113. }
  114. /**
  115. * pin_config_set() - set the configuration of a single pin parameter
  116. * @dev_name: name of pin controller device for this pin
  117. * @name: name of the pin to set the config for
  118. * @config: the config in this argument will contain the desired pin state, it
  119. * can be used directly by drivers as a numeral, or it can be dereferenced
  120. * to any struct.
  121. */
  122. int pin_config_set(const char *dev_name, const char *name,
  123. unsigned long config)
  124. {
  125. struct pinctrl_dev *pctldev;
  126. int pin, ret;
  127. pctldev = get_pinctrl_dev_from_devname(dev_name);
  128. if (!pctldev) {
  129. ret = -EINVAL;
  130. return ret;
  131. }
  132. mutex_lock(&pctldev->mutex);
  133. pin = pin_get_from_name(pctldev, name);
  134. if (pin < 0) {
  135. ret = pin;
  136. goto unlock;
  137. }
  138. ret = pin_config_set_for_pin(pctldev, pin, config);
  139. unlock:
  140. mutex_unlock(&pctldev->mutex);
  141. return ret;
  142. }
  143. EXPORT_SYMBOL(pin_config_set);
  144. int pin_config_group_get(const char *dev_name, const char *pin_group,
  145. unsigned long *config)
  146. {
  147. struct pinctrl_dev *pctldev;
  148. const struct pinconf_ops *ops;
  149. int selector, ret;
  150. pctldev = get_pinctrl_dev_from_devname(dev_name);
  151. if (!pctldev) {
  152. ret = -EINVAL;
  153. return ret;
  154. }
  155. mutex_lock(&pctldev->mutex);
  156. ops = pctldev->desc->confops;
  157. if (!ops || !ops->pin_config_group_get) {
  158. dev_err(pctldev->dev, "cannot get configuration for pin "
  159. "group, missing group config get function in "
  160. "driver\n");
  161. ret = -EINVAL;
  162. goto unlock;
  163. }
  164. selector = pinctrl_get_group_selector(pctldev, pin_group);
  165. if (selector < 0) {
  166. ret = selector;
  167. goto unlock;
  168. }
  169. ret = ops->pin_config_group_get(pctldev, selector, config);
  170. unlock:
  171. mutex_unlock(&pctldev->mutex);
  172. return ret;
  173. }
  174. EXPORT_SYMBOL(pin_config_group_get);
  175. int pin_config_group_set(const char *dev_name, const char *pin_group,
  176. unsigned long config)
  177. {
  178. struct pinctrl_dev *pctldev;
  179. const struct pinconf_ops *ops;
  180. const struct pinctrl_ops *pctlops;
  181. int selector;
  182. const unsigned *pins;
  183. unsigned num_pins;
  184. int ret;
  185. int i;
  186. pctldev = get_pinctrl_dev_from_devname(dev_name);
  187. if (!pctldev) {
  188. ret = -EINVAL;
  189. return ret;
  190. }
  191. mutex_lock(&pctldev->mutex);
  192. ops = pctldev->desc->confops;
  193. pctlops = pctldev->desc->pctlops;
  194. if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) {
  195. dev_err(pctldev->dev, "cannot configure pin group, missing "
  196. "config function in driver\n");
  197. ret = -EINVAL;
  198. goto unlock;
  199. }
  200. selector = pinctrl_get_group_selector(pctldev, pin_group);
  201. if (selector < 0) {
  202. ret = selector;
  203. goto unlock;
  204. }
  205. ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins);
  206. if (ret) {
  207. dev_err(pctldev->dev, "cannot configure pin group, error "
  208. "getting pins\n");
  209. goto unlock;
  210. }
  211. /*
  212. * If the pin controller supports handling entire groups we use that
  213. * capability.
  214. */
  215. if (ops->pin_config_group_set) {
  216. ret = ops->pin_config_group_set(pctldev, selector, config);
  217. /*
  218. * If the pin controller prefer that a certain group be handled
  219. * pin-by-pin as well, it returns -EAGAIN.
  220. */
  221. if (ret != -EAGAIN)
  222. goto unlock;
  223. }
  224. /*
  225. * If the controller cannot handle entire groups, we configure each pin
  226. * individually.
  227. */
  228. if (!ops->pin_config_set) {
  229. ret = 0;
  230. goto unlock;
  231. }
  232. for (i = 0; i < num_pins; i++) {
  233. ret = ops->pin_config_set(pctldev, pins[i], config);
  234. if (ret < 0)
  235. goto unlock;
  236. }
  237. ret = 0;
  238. unlock:
  239. mutex_unlock(&pctldev->mutex);
  240. return ret;
  241. }
  242. EXPORT_SYMBOL(pin_config_group_set);
  243. int pinconf_map_to_setting(struct pinctrl_map const *map,
  244. struct pinctrl_setting *setting)
  245. {
  246. struct pinctrl_dev *pctldev = setting->pctldev;
  247. int pin;
  248. switch (setting->type) {
  249. case PIN_MAP_TYPE_CONFIGS_PIN:
  250. pin = pin_get_from_name(pctldev,
  251. map->data.configs.group_or_pin);
  252. if (pin < 0) {
  253. dev_err(pctldev->dev, "could not map pin config for \"%s\"",
  254. map->data.configs.group_or_pin);
  255. return pin;
  256. }
  257. setting->data.configs.group_or_pin = pin;
  258. break;
  259. case PIN_MAP_TYPE_CONFIGS_GROUP:
  260. pin = pinctrl_get_group_selector(pctldev,
  261. map->data.configs.group_or_pin);
  262. if (pin < 0) {
  263. dev_err(pctldev->dev, "could not map group config for \"%s\"",
  264. map->data.configs.group_or_pin);
  265. return pin;
  266. }
  267. setting->data.configs.group_or_pin = pin;
  268. break;
  269. default:
  270. return -EINVAL;
  271. }
  272. setting->data.configs.num_configs = map->data.configs.num_configs;
  273. setting->data.configs.configs = map->data.configs.configs;
  274. return 0;
  275. }
  276. void pinconf_free_setting(struct pinctrl_setting const *setting)
  277. {
  278. }
  279. int pinconf_apply_setting(struct pinctrl_setting const *setting)
  280. {
  281. struct pinctrl_dev *pctldev = setting->pctldev;
  282. const struct pinconf_ops *ops = pctldev->desc->confops;
  283. int i, ret;
  284. if (!ops) {
  285. dev_err(pctldev->dev, "missing confops\n");
  286. return -EINVAL;
  287. }
  288. switch (setting->type) {
  289. case PIN_MAP_TYPE_CONFIGS_PIN:
  290. if (!ops->pin_config_set) {
  291. dev_err(pctldev->dev, "missing pin_config_set op\n");
  292. return -EINVAL;
  293. }
  294. for (i = 0; i < setting->data.configs.num_configs; i++) {
  295. ret = ops->pin_config_set(pctldev,
  296. setting->data.configs.group_or_pin,
  297. setting->data.configs.configs[i]);
  298. if (ret < 0) {
  299. dev_err(pctldev->dev,
  300. "pin_config_set op failed for pin %d config %08lx\n",
  301. setting->data.configs.group_or_pin,
  302. setting->data.configs.configs[i]);
  303. return ret;
  304. }
  305. }
  306. break;
  307. case PIN_MAP_TYPE_CONFIGS_GROUP:
  308. if (!ops->pin_config_group_set) {
  309. dev_err(pctldev->dev,
  310. "missing pin_config_group_set op\n");
  311. return -EINVAL;
  312. }
  313. for (i = 0; i < setting->data.configs.num_configs; i++) {
  314. ret = ops->pin_config_group_set(pctldev,
  315. setting->data.configs.group_or_pin,
  316. setting->data.configs.configs[i]);
  317. if (ret < 0) {
  318. dev_err(pctldev->dev,
  319. "pin_config_group_set op failed for group %d config %08lx\n",
  320. setting->data.configs.group_or_pin,
  321. setting->data.configs.configs[i]);
  322. return ret;
  323. }
  324. }
  325. break;
  326. default:
  327. return -EINVAL;
  328. }
  329. return 0;
  330. }
  331. #ifdef CONFIG_DEBUG_FS
  332. void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map)
  333. {
  334. struct pinctrl_dev *pctldev;
  335. const struct pinconf_ops *confops;
  336. int i;
  337. pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
  338. if (pctldev)
  339. confops = pctldev->desc->confops;
  340. else
  341. confops = NULL;
  342. switch (map->type) {
  343. case PIN_MAP_TYPE_CONFIGS_PIN:
  344. seq_printf(s, "pin ");
  345. break;
  346. case PIN_MAP_TYPE_CONFIGS_GROUP:
  347. seq_printf(s, "group ");
  348. break;
  349. default:
  350. break;
  351. }
  352. seq_printf(s, "%s\n", map->data.configs.group_or_pin);
  353. for (i = 0; i < map->data.configs.num_configs; i++) {
  354. seq_printf(s, "config ");
  355. if (confops && confops->pin_config_config_dbg_show)
  356. confops->pin_config_config_dbg_show(pctldev, s,
  357. map->data.configs.configs[i]);
  358. else
  359. seq_printf(s, "%08lx", map->data.configs.configs[i]);
  360. seq_printf(s, "\n");
  361. }
  362. }
  363. void pinconf_show_setting(struct seq_file *s,
  364. struct pinctrl_setting const *setting)
  365. {
  366. struct pinctrl_dev *pctldev = setting->pctldev;
  367. const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
  368. const struct pinconf_ops *confops = pctldev->desc->confops;
  369. struct pin_desc *desc;
  370. int i;
  371. switch (setting->type) {
  372. case PIN_MAP_TYPE_CONFIGS_PIN:
  373. desc = pin_desc_get(setting->pctldev,
  374. setting->data.configs.group_or_pin);
  375. seq_printf(s, "pin %s (%d)",
  376. desc->name ? desc->name : "unnamed",
  377. setting->data.configs.group_or_pin);
  378. break;
  379. case PIN_MAP_TYPE_CONFIGS_GROUP:
  380. seq_printf(s, "group %s (%d)",
  381. pctlops->get_group_name(pctldev,
  382. setting->data.configs.group_or_pin),
  383. setting->data.configs.group_or_pin);
  384. break;
  385. default:
  386. break;
  387. }
  388. /*
  389. * FIXME: We should really get the pin controler to dump the config
  390. * values, so they can be decoded to something meaningful.
  391. */
  392. for (i = 0; i < setting->data.configs.num_configs; i++) {
  393. seq_printf(s, " ");
  394. if (confops && confops->pin_config_config_dbg_show)
  395. confops->pin_config_config_dbg_show(pctldev, s,
  396. setting->data.configs.configs[i]);
  397. else
  398. seq_printf(s, "%08lx",
  399. setting->data.configs.configs[i]);
  400. }
  401. seq_printf(s, "\n");
  402. }
  403. static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
  404. struct seq_file *s, int pin)
  405. {
  406. const struct pinconf_ops *ops = pctldev->desc->confops;
  407. /* no-op when not using generic pin config */
  408. pinconf_generic_dump_pin(pctldev, s, pin);
  409. if (ops && ops->pin_config_dbg_show)
  410. ops->pin_config_dbg_show(pctldev, s, pin);
  411. }
  412. static int pinconf_pins_show(struct seq_file *s, void *what)
  413. {
  414. struct pinctrl_dev *pctldev = s->private;
  415. const struct pinconf_ops *ops = pctldev->desc->confops;
  416. unsigned i, pin;
  417. if (!ops || !ops->pin_config_get)
  418. return 0;
  419. seq_puts(s, "Pin config settings per pin\n");
  420. seq_puts(s, "Format: pin (name): configs\n");
  421. mutex_lock(&pctldev->mutex);
  422. /* The pin number can be retrived from the pin controller descriptor */
  423. for (i = 0; i < pctldev->desc->npins; i++) {
  424. struct pin_desc *desc;
  425. pin = pctldev->desc->pins[i].number;
  426. desc = pin_desc_get(pctldev, pin);
  427. /* Skip if we cannot search the pin */
  428. if (desc == NULL)
  429. continue;
  430. seq_printf(s, "pin %d (%s):", pin,
  431. desc->name ? desc->name : "unnamed");
  432. pinconf_dump_pin(pctldev, s, pin);
  433. seq_printf(s, "\n");
  434. }
  435. mutex_unlock(&pctldev->mutex);
  436. return 0;
  437. }
  438. static void pinconf_dump_group(struct pinctrl_dev *pctldev,
  439. struct seq_file *s, unsigned selector,
  440. const char *gname)
  441. {
  442. const struct pinconf_ops *ops = pctldev->desc->confops;
  443. /* no-op when not using generic pin config */
  444. pinconf_generic_dump_group(pctldev, s, gname);
  445. if (ops && ops->pin_config_group_dbg_show)
  446. ops->pin_config_group_dbg_show(pctldev, s, selector);
  447. }
  448. static int pinconf_groups_show(struct seq_file *s, void *what)
  449. {
  450. struct pinctrl_dev *pctldev = s->private;
  451. const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
  452. const struct pinconf_ops *ops = pctldev->desc->confops;
  453. unsigned ngroups = pctlops->get_groups_count(pctldev);
  454. unsigned selector = 0;
  455. if (!ops || !ops->pin_config_group_get)
  456. return 0;
  457. seq_puts(s, "Pin config settings per pin group\n");
  458. seq_puts(s, "Format: group (name): configs\n");
  459. while (selector < ngroups) {
  460. const char *gname = pctlops->get_group_name(pctldev, selector);
  461. seq_printf(s, "%u (%s):", selector, gname);
  462. pinconf_dump_group(pctldev, s, selector, gname);
  463. seq_printf(s, "\n");
  464. selector++;
  465. }
  466. return 0;
  467. }
  468. static int pinconf_pins_open(struct inode *inode, struct file *file)
  469. {
  470. return single_open(file, pinconf_pins_show, inode->i_private);
  471. }
  472. static int pinconf_groups_open(struct inode *inode, struct file *file)
  473. {
  474. return single_open(file, pinconf_groups_show, inode->i_private);
  475. }
  476. static const struct file_operations pinconf_pins_ops = {
  477. .open = pinconf_pins_open,
  478. .read = seq_read,
  479. .llseek = seq_lseek,
  480. .release = single_release,
  481. };
  482. static const struct file_operations pinconf_groups_ops = {
  483. .open = pinconf_groups_open,
  484. .read = seq_read,
  485. .llseek = seq_lseek,
  486. .release = single_release,
  487. };
  488. #define MAX_NAME_LEN 15
  489. struct dbg_cfg {
  490. enum pinctrl_map_type map_type;
  491. char dev_name[MAX_NAME_LEN+1];
  492. char state_name[MAX_NAME_LEN+1];
  493. char pin_name[MAX_NAME_LEN+1];
  494. };
  495. /*
  496. * Goal is to keep this structure as global in order to simply read the
  497. * pinconf-config file after a write to check config is as expected
  498. */
  499. static struct dbg_cfg pinconf_dbg_conf;
  500. /**
  501. * pinconf_dbg_config_print() - display the pinctrl config from the pinctrl
  502. * map, of the dev/pin/state that was last written to pinconf-config file.
  503. * @s: string filled in with config description
  504. * @d: not used
  505. */
  506. static int pinconf_dbg_config_print(struct seq_file *s, void *d)
  507. {
  508. struct pinctrl_maps *maps_node;
  509. const struct pinctrl_map *map;
  510. struct pinctrl_dev *pctldev = NULL;
  511. const struct pinconf_ops *confops = NULL;
  512. const struct pinctrl_map_configs *configs;
  513. struct dbg_cfg *dbg = &pinconf_dbg_conf;
  514. int i, j;
  515. bool found = false;
  516. unsigned long config;
  517. mutex_lock(&pctldev->mutex);
  518. /* Parse the pinctrl map and look for the elected pin/state */
  519. for_each_maps(maps_node, i, map) {
  520. if (map->type != dbg->map_type)
  521. continue;
  522. if (strcmp(map->dev_name, dbg->dev_name))
  523. continue;
  524. if (strcmp(map->name, dbg->state_name))
  525. continue;
  526. for (j = 0; j < map->data.configs.num_configs; j++) {
  527. if (!strcmp(map->data.configs.group_or_pin,
  528. dbg->pin_name)) {
  529. /*
  530. * We found the right pin / state, read the
  531. * config and he pctldev for later use
  532. */
  533. configs = &map->data.configs;
  534. pctldev = get_pinctrl_dev_from_devname
  535. (map->ctrl_dev_name);
  536. found = true;
  537. break;
  538. }
  539. }
  540. }
  541. if (!found) {
  542. seq_printf(s, "No config found for dev/state/pin, expected:\n");
  543. seq_printf(s, "Searched dev:%s\n", dbg->dev_name);
  544. seq_printf(s, "Searched state:%s\n", dbg->state_name);
  545. seq_printf(s, "Searched pin:%s\n", dbg->pin_name);
  546. seq_printf(s, "Use: modify config_pin <devname> "\
  547. "<state> <pinname> <value>\n");
  548. goto exit;
  549. }
  550. config = *(configs->configs);
  551. seq_printf(s, "Dev %s has config of %s in state %s: 0x%08lX\n",
  552. dbg->dev_name, dbg->pin_name,
  553. dbg->state_name, config);
  554. if (pctldev)
  555. confops = pctldev->desc->confops;
  556. if (confops && confops->pin_config_config_dbg_show)
  557. confops->pin_config_config_dbg_show(pctldev, s, config);
  558. exit:
  559. mutex_unlock(&pctldev->mutex);
  560. return 0;
  561. }
  562. /**
  563. * pinconf_dbg_config_write() - modify the pinctrl config in the pinctrl
  564. * map, of a dev/pin/state entry based on user entries to pinconf-config
  565. * @user_buf: contains the modification request with expected format:
  566. * modify config_pin <devicename> <state> <pinname> <newvalue>
  567. * modify is literal string, alternatives like add/delete not supported yet
  568. * config_pin is literal, alternatives like config_mux not supported yet
  569. * <devicename> <state> <pinname> are values that should match the pinctrl-maps
  570. * <newvalue> reflects the new config and is driver dependant
  571. */
  572. static int pinconf_dbg_config_write(struct file *file,
  573. const char __user *user_buf, size_t count, loff_t *ppos)
  574. {
  575. struct pinctrl_maps *maps_node;
  576. const struct pinctrl_map *map;
  577. struct pinctrl_dev *pctldev = NULL;
  578. const struct pinconf_ops *confops = NULL;
  579. struct dbg_cfg *dbg = &pinconf_dbg_conf;
  580. const struct pinctrl_map_configs *configs;
  581. char config[MAX_NAME_LEN+1];
  582. bool found = false;
  583. char buf[128];
  584. char *b = &buf[0];
  585. int buf_size;
  586. char *token;
  587. int i;
  588. /* Get userspace string and assure termination */
  589. buf_size = min(count, (sizeof(buf)-1));
  590. if (copy_from_user(buf, user_buf, buf_size))
  591. return -EFAULT;
  592. buf[buf_size] = 0;
  593. /*
  594. * need to parse entry and extract parameters:
  595. * modify configs_pin devicename state pinname newvalue
  596. */
  597. /* Get arg: 'modify' */
  598. token = strsep(&b, " ");
  599. if (!token)
  600. return -EINVAL;
  601. if (strcmp(token, "modify"))
  602. return -EINVAL;
  603. /* Get arg type: "config_pin" type supported so far */
  604. token = strsep(&b, " ");
  605. if (!token)
  606. return -EINVAL;
  607. if (strcmp(token, "config_pin"))
  608. return -EINVAL;
  609. dbg->map_type = PIN_MAP_TYPE_CONFIGS_PIN;
  610. /* get arg 'device_name' */
  611. token = strsep(&b, " ");
  612. if (token == NULL)
  613. return -EINVAL;
  614. if (strlen(token) >= MAX_NAME_LEN)
  615. return -EINVAL;
  616. strncpy(dbg->dev_name, token, MAX_NAME_LEN);
  617. /* get arg 'state_name' */
  618. token = strsep(&b, " ");
  619. if (token == NULL)
  620. return -EINVAL;
  621. if (strlen(token) >= MAX_NAME_LEN)
  622. return -EINVAL;
  623. strncpy(dbg->state_name, token, MAX_NAME_LEN);
  624. /* get arg 'pin_name' */
  625. token = strsep(&b, " ");
  626. if (token == NULL)
  627. return -EINVAL;
  628. if (strlen(token) >= MAX_NAME_LEN)
  629. return -EINVAL;
  630. strncpy(dbg->pin_name, token, MAX_NAME_LEN);
  631. /* get new_value of config' */
  632. token = strsep(&b, " ");
  633. if (token == NULL)
  634. return -EINVAL;
  635. if (strlen(token) >= MAX_NAME_LEN)
  636. return -EINVAL;
  637. strncpy(config, token, MAX_NAME_LEN);
  638. mutex_lock(&pinctrl_maps_mutex);
  639. /* Parse the pinctrl map and look for the selected dev/state/pin */
  640. for_each_maps(maps_node, i, map) {
  641. if (strcmp(map->dev_name, dbg->dev_name))
  642. continue;
  643. if (map->type != dbg->map_type)
  644. continue;
  645. if (strcmp(map->name, dbg->state_name))
  646. continue;
  647. /* we found the right pin / state, so overwrite config */
  648. if (!strcmp(map->data.configs.group_or_pin, dbg->pin_name)) {
  649. found = true;
  650. pctldev = get_pinctrl_dev_from_devname(
  651. map->ctrl_dev_name);
  652. configs = &map->data.configs;
  653. break;
  654. }
  655. }
  656. if (!found) {
  657. count = -EINVAL;
  658. goto exit;
  659. }
  660. if (pctldev)
  661. confops = pctldev->desc->confops;
  662. if (confops && confops->pin_config_dbg_parse_modify) {
  663. for (i = 0; i < configs->num_configs; i++) {
  664. confops->pin_config_dbg_parse_modify(pctldev,
  665. config,
  666. &configs->configs[i]);
  667. }
  668. }
  669. exit:
  670. mutex_unlock(&pinctrl_maps_mutex);
  671. return count;
  672. }
  673. static int pinconf_dbg_config_open(struct inode *inode, struct file *file)
  674. {
  675. return single_open(file, pinconf_dbg_config_print, inode->i_private);
  676. }
  677. static const struct file_operations pinconf_dbg_pinconfig_fops = {
  678. .open = pinconf_dbg_config_open,
  679. .write = pinconf_dbg_config_write,
  680. .read = seq_read,
  681. .llseek = seq_lseek,
  682. .release = single_release,
  683. .owner = THIS_MODULE,
  684. };
  685. void pinconf_init_device_debugfs(struct dentry *devroot,
  686. struct pinctrl_dev *pctldev)
  687. {
  688. debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO,
  689. devroot, pctldev, &pinconf_pins_ops);
  690. debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO,
  691. devroot, pctldev, &pinconf_groups_ops);
  692. debugfs_create_file("pinconf-config", (S_IRUGO | S_IWUSR | S_IWGRP),
  693. devroot, pctldev, &pinconf_dbg_pinconfig_fops);
  694. }
  695. #endif