gpio.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
  7. */
  8. #include <linux/export.h>
  9. #include <linux/ssb/ssb.h>
  10. #include <linux/ssb/ssb_driver_chipcommon.h>
  11. #include <linux/ssb/ssb_driver_extif.h>
  12. #include <asm/mach-bcm47xx/bcm47xx.h>
  13. #include <asm/mach-bcm47xx/gpio.h>
  14. #if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES)
  15. static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES);
  16. #else
  17. static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);
  18. #endif
  19. int gpio_request(unsigned gpio, const char *tag)
  20. {
  21. switch (bcm47xx_bus_type) {
  22. #ifdef CONFIG_BCM47XX_SSB
  23. case BCM47XX_BUS_TYPE_SSB:
  24. if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
  25. ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
  26. return -EINVAL;
  27. if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
  28. ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
  29. return -EINVAL;
  30. if (test_and_set_bit(gpio, gpio_in_use))
  31. return -EBUSY;
  32. return 0;
  33. #endif
  34. #ifdef CONFIG_BCM47XX_BCMA
  35. case BCM47XX_BUS_TYPE_BCMA:
  36. if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
  37. return -EINVAL;
  38. if (test_and_set_bit(gpio, gpio_in_use))
  39. return -EBUSY;
  40. return 0;
  41. #endif
  42. }
  43. return -EINVAL;
  44. }
  45. EXPORT_SYMBOL(gpio_request);
  46. void gpio_free(unsigned gpio)
  47. {
  48. switch (bcm47xx_bus_type) {
  49. #ifdef CONFIG_BCM47XX_SSB
  50. case BCM47XX_BUS_TYPE_SSB:
  51. if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
  52. ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
  53. return;
  54. if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
  55. ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
  56. return;
  57. clear_bit(gpio, gpio_in_use);
  58. return;
  59. #endif
  60. #ifdef CONFIG_BCM47XX_BCMA
  61. case BCM47XX_BUS_TYPE_BCMA:
  62. if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
  63. return;
  64. clear_bit(gpio, gpio_in_use);
  65. return;
  66. #endif
  67. }
  68. }
  69. EXPORT_SYMBOL(gpio_free);
  70. int gpio_to_irq(unsigned gpio)
  71. {
  72. switch (bcm47xx_bus_type) {
  73. #ifdef CONFIG_BCM47XX_SSB
  74. case BCM47XX_BUS_TYPE_SSB:
  75. if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco))
  76. return ssb_mips_irq(bcm47xx_bus.ssb.chipco.dev) + 2;
  77. else if (ssb_extif_available(&bcm47xx_bus.ssb.extif))
  78. return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2;
  79. else
  80. return -EINVAL;
  81. #endif
  82. #ifdef CONFIG_BCM47XX_BCMA
  83. case BCM47XX_BUS_TYPE_BCMA:
  84. return bcma_core_mips_irq(bcm47xx_bus.bcma.bus.drv_cc.core) + 2;
  85. #endif
  86. }
  87. return -EINVAL;
  88. }
  89. EXPORT_SYMBOL_GPL(gpio_to_irq);