pins.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * Copyright (C) ST-Ericsson SA 2010
  3. *
  4. * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
  5. * License terms: GNU General Public License (GPL), version 2
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/string.h>
  9. #include <linux/device.h>
  10. #include <linux/mutex.h>
  11. #include <linux/spinlock.h>
  12. #include <linux/err.h>
  13. #include <plat/pincfg.h>
  14. #include "pins.h"
  15. static LIST_HEAD(pin_lookups);
  16. static DEFINE_MUTEX(pin_lookups_mutex);
  17. static DEFINE_SPINLOCK(pins_lock);
  18. void __init ux500_pins_add(struct ux500_pin_lookup *pl, size_t num)
  19. {
  20. mutex_lock(&pin_lookups_mutex);
  21. while (num--) {
  22. list_add_tail(&pl->node, &pin_lookups);
  23. pl++;
  24. }
  25. mutex_unlock(&pin_lookups_mutex);
  26. }
  27. struct ux500_pins *ux500_pins_get(const char *name)
  28. {
  29. struct ux500_pins *pins = NULL;
  30. struct ux500_pin_lookup *pl;
  31. mutex_lock(&pin_lookups_mutex);
  32. list_for_each_entry(pl, &pin_lookups, node) {
  33. if (!strcmp(pl->name, name)) {
  34. pins = pl->pins;
  35. goto out;
  36. }
  37. }
  38. out:
  39. mutex_unlock(&pin_lookups_mutex);
  40. return pins;
  41. }
  42. int ux500_pins_enable(struct ux500_pins *pins)
  43. {
  44. unsigned long flags;
  45. int ret = 0;
  46. spin_lock_irqsave(&pins_lock, flags);
  47. if (pins->usage++ == 0)
  48. ret = nmk_config_pins(pins->cfg, pins->num);
  49. spin_unlock_irqrestore(&pins_lock, flags);
  50. return ret;
  51. }
  52. int ux500_pins_disable(struct ux500_pins *pins)
  53. {
  54. unsigned long flags;
  55. int ret = 0;
  56. spin_lock_irqsave(&pins_lock, flags);
  57. if (WARN_ON(pins->usage == 0))
  58. goto out;
  59. if (--pins->usage == 0)
  60. ret = nmk_config_pins_sleep(pins->cfg, pins->num);
  61. out:
  62. spin_unlock_irqrestore(&pins_lock, flags);
  63. return ret;
  64. }
  65. void ux500_pins_put(struct ux500_pins *pins)
  66. {
  67. WARN_ON(!pins);
  68. }