driver_gpio.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /*
  2. * Broadcom specific AMBA
  3. * GPIO driver
  4. *
  5. * Copyright 2011, Broadcom Corporation
  6. * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
  7. *
  8. * Licensed under the GNU/GPL. See COPYING for details.
  9. */
  10. #include <linux/gpio.h>
  11. #include <linux/irq.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/irqdomain.h>
  14. #include <linux/export.h>
  15. #include <linux/bcma/bcma.h>
  16. #include "bcma_private.h"
  17. static inline struct bcma_drv_cc *bcma_gpio_get_cc(struct gpio_chip *chip)
  18. {
  19. return container_of(chip, struct bcma_drv_cc, gpio);
  20. }
  21. static int bcma_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
  22. {
  23. struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
  24. return !!bcma_chipco_gpio_in(cc, 1 << gpio);
  25. }
  26. static void bcma_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
  27. int value)
  28. {
  29. struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
  30. bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0);
  31. }
  32. static int bcma_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
  33. {
  34. struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
  35. bcma_chipco_gpio_outen(cc, 1 << gpio, 0);
  36. return 0;
  37. }
  38. static int bcma_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
  39. int value)
  40. {
  41. struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
  42. bcma_chipco_gpio_outen(cc, 1 << gpio, 1 << gpio);
  43. bcma_chipco_gpio_out(cc, 1 << gpio, value ? 1 << gpio : 0);
  44. return 0;
  45. }
  46. static int bcma_gpio_request(struct gpio_chip *chip, unsigned gpio)
  47. {
  48. struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
  49. bcma_chipco_gpio_control(cc, 1 << gpio, 0);
  50. /* clear pulldown */
  51. bcma_chipco_gpio_pulldown(cc, 1 << gpio, 0);
  52. /* Set pullup */
  53. bcma_chipco_gpio_pullup(cc, 1 << gpio, 1 << gpio);
  54. return 0;
  55. }
  56. static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio)
  57. {
  58. struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
  59. /* clear pullup */
  60. bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
  61. }
  62. #if IS_BUILTIN(CONFIG_BCM47XX)
  63. static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
  64. {
  65. struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
  66. if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
  67. return irq_find_mapping(cc->irq_domain, gpio);
  68. else
  69. return -EINVAL;
  70. }
  71. static void bcma_gpio_irq_unmask(struct irq_data *d)
  72. {
  73. struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d);
  74. int gpio = irqd_to_hwirq(d);
  75. u32 val = bcma_chipco_gpio_in(cc, BIT(gpio));
  76. bcma_chipco_gpio_polarity(cc, BIT(gpio), val);
  77. bcma_chipco_gpio_intmask(cc, BIT(gpio), BIT(gpio));
  78. }
  79. static void bcma_gpio_irq_mask(struct irq_data *d)
  80. {
  81. struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d);
  82. int gpio = irqd_to_hwirq(d);
  83. bcma_chipco_gpio_intmask(cc, BIT(gpio), 0);
  84. }
  85. static struct irq_chip bcma_gpio_irq_chip = {
  86. .name = "BCMA-GPIO",
  87. .irq_mask = bcma_gpio_irq_mask,
  88. .irq_unmask = bcma_gpio_irq_unmask,
  89. };
  90. static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id)
  91. {
  92. struct bcma_drv_cc *cc = dev_id;
  93. u32 val = bcma_cc_read32(cc, BCMA_CC_GPIOIN);
  94. u32 mask = bcma_cc_read32(cc, BCMA_CC_GPIOIRQ);
  95. u32 pol = bcma_cc_read32(cc, BCMA_CC_GPIOPOL);
  96. unsigned long irqs = (val ^ pol) & mask;
  97. int gpio;
  98. if (!irqs)
  99. return IRQ_NONE;
  100. for_each_set_bit(gpio, &irqs, cc->gpio.ngpio)
  101. generic_handle_irq(bcma_gpio_to_irq(&cc->gpio, gpio));
  102. bcma_chipco_gpio_polarity(cc, irqs, val & irqs);
  103. return IRQ_HANDLED;
  104. }
  105. static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc)
  106. {
  107. struct gpio_chip *chip = &cc->gpio;
  108. int gpio, hwirq, err;
  109. if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
  110. return 0;
  111. cc->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
  112. &irq_domain_simple_ops, cc);
  113. if (!cc->irq_domain) {
  114. err = -ENODEV;
  115. goto err_irq_domain;
  116. }
  117. for (gpio = 0; gpio < chip->ngpio; gpio++) {
  118. int irq = irq_create_mapping(cc->irq_domain, gpio);
  119. irq_set_chip_data(irq, cc);
  120. irq_set_chip_and_handler(irq, &bcma_gpio_irq_chip,
  121. handle_simple_irq);
  122. }
  123. hwirq = bcma_core_irq(cc->core, 0);
  124. err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio",
  125. cc);
  126. if (err)
  127. goto err_req_irq;
  128. bcma_chipco_gpio_intmask(cc, ~0, 0);
  129. bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO);
  130. return 0;
  131. err_req_irq:
  132. for (gpio = 0; gpio < chip->ngpio; gpio++) {
  133. int irq = irq_find_mapping(cc->irq_domain, gpio);
  134. irq_dispose_mapping(irq);
  135. }
  136. irq_domain_remove(cc->irq_domain);
  137. err_irq_domain:
  138. return err;
  139. }
  140. static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc)
  141. {
  142. struct gpio_chip *chip = &cc->gpio;
  143. int gpio;
  144. if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC)
  145. return;
  146. bcma_cc_mask32(cc, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO);
  147. free_irq(bcma_core_irq(cc->core, 0), cc);
  148. for (gpio = 0; gpio < chip->ngpio; gpio++) {
  149. int irq = irq_find_mapping(cc->irq_domain, gpio);
  150. irq_dispose_mapping(irq);
  151. }
  152. irq_domain_remove(cc->irq_domain);
  153. }
  154. #else
  155. static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc)
  156. {
  157. return 0;
  158. }
  159. static void bcma_gpio_irq_domain_exit(struct bcma_drv_cc *cc)
  160. {
  161. }
  162. #endif
  163. int bcma_gpio_init(struct bcma_drv_cc *cc)
  164. {
  165. struct gpio_chip *chip = &cc->gpio;
  166. int err;
  167. chip->label = "bcma_gpio";
  168. chip->owner = THIS_MODULE;
  169. chip->request = bcma_gpio_request;
  170. chip->free = bcma_gpio_free;
  171. chip->get = bcma_gpio_get_value;
  172. chip->set = bcma_gpio_set_value;
  173. chip->direction_input = bcma_gpio_direction_input;
  174. chip->direction_output = bcma_gpio_direction_output;
  175. #if IS_BUILTIN(CONFIG_BCM47XX)
  176. chip->to_irq = bcma_gpio_to_irq;
  177. #endif
  178. #if IS_BUILTIN(CONFIG_OF)
  179. if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
  180. chip->of_node = cc->core->dev.of_node;
  181. #endif
  182. switch (cc->core->bus->chipinfo.id) {
  183. case BCMA_CHIP_ID_BCM5357:
  184. case BCMA_CHIP_ID_BCM53572:
  185. chip->ngpio = 32;
  186. break;
  187. default:
  188. chip->ngpio = 16;
  189. }
  190. /* There is just one SoC in one device and its GPIO addresses should be
  191. * deterministic to address them more easily. The other buses could get
  192. * a random base number. */
  193. if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
  194. chip->base = 0;
  195. else
  196. chip->base = -1;
  197. err = bcma_gpio_irq_domain_init(cc);
  198. if (err)
  199. return err;
  200. err = gpiochip_add(chip);
  201. if (err) {
  202. bcma_gpio_irq_domain_exit(cc);
  203. return err;
  204. }
  205. return 0;
  206. }
  207. int bcma_gpio_unregister(struct bcma_drv_cc *cc)
  208. {
  209. bcma_gpio_irq_domain_exit(cc);
  210. gpiochip_remove(&cc->gpio);
  211. return 0;
  212. }