tps65910-irq.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /*
  2. * tps65910-irq.c -- TI TPS6591x
  3. *
  4. * Copyright 2010 Texas Instruments Inc.
  5. *
  6. * Author: Graeme Gregory <gg@slimlogic.co.uk>
  7. * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
  8. *
  9. * This program is free software; you can redistribute it and/or modify it
  10. * under the terms of the GNU General Public License as published by the
  11. * Free Software Foundation; either version 2 of the License, or (at your
  12. * option) any later version.
  13. *
  14. */
  15. #include <linux/kernel.h>
  16. #include <linux/module.h>
  17. #include <linux/init.h>
  18. #include <linux/bug.h>
  19. #include <linux/device.h>
  20. #include <linux/interrupt.h>
  21. #include <linux/irq.h>
  22. #include <linux/irqdomain.h>
  23. #include <linux/gpio.h>
  24. #include <linux/mfd/tps65910.h>
  25. /*
  26. * This is a threaded IRQ handler so can access I2C/SPI. Since all
  27. * interrupts are clear on read the IRQ line will be reasserted and
  28. * the physical IRQ will be handled again if another interrupt is
  29. * asserted while we run - in the normal course of events this is a
  30. * rare occurrence so we save I2C/SPI reads. We're also assuming that
  31. * it's rare to get lots of interrupts firing simultaneously so try to
  32. * minimise I/O.
  33. */
  34. static irqreturn_t tps65910_irq(int irq, void *irq_data)
  35. {
  36. struct tps65910 *tps65910 = irq_data;
  37. unsigned int reg;
  38. u32 irq_sts;
  39. u32 irq_mask;
  40. int i;
  41. tps65910_reg_read(tps65910, TPS65910_INT_STS, &reg);
  42. irq_sts = reg;
  43. tps65910_reg_read(tps65910, TPS65910_INT_STS2, &reg);
  44. irq_sts |= reg << 8;
  45. switch (tps65910_chip_id(tps65910)) {
  46. case TPS65911:
  47. tps65910_reg_read(tps65910, TPS65910_INT_STS3, &reg);
  48. irq_sts |= reg << 16;
  49. }
  50. tps65910_reg_read(tps65910, TPS65910_INT_MSK, &reg);
  51. irq_mask = reg;
  52. tps65910_reg_read(tps65910, TPS65910_INT_MSK2, &reg);
  53. irq_mask |= reg << 8;
  54. switch (tps65910_chip_id(tps65910)) {
  55. case TPS65911:
  56. tps65910_reg_read(tps65910, TPS65910_INT_MSK3, &reg);
  57. irq_mask |= reg << 16;
  58. }
  59. irq_sts &= ~irq_mask;
  60. if (!irq_sts)
  61. return IRQ_NONE;
  62. for (i = 0; i < tps65910->irq_num; i++) {
  63. if (!(irq_sts & (1 << i)))
  64. continue;
  65. handle_nested_irq(irq_find_mapping(tps65910->domain, i));
  66. }
  67. /* Write the STS register back to clear IRQs we handled */
  68. reg = irq_sts & 0xFF;
  69. irq_sts >>= 8;
  70. tps65910_reg_write(tps65910, TPS65910_INT_STS, reg);
  71. reg = irq_sts & 0xFF;
  72. tps65910_reg_write(tps65910, TPS65910_INT_STS2, reg);
  73. switch (tps65910_chip_id(tps65910)) {
  74. case TPS65911:
  75. reg = irq_sts >> 8;
  76. tps65910_reg_write(tps65910, TPS65910_INT_STS3, reg);
  77. }
  78. return IRQ_HANDLED;
  79. }
  80. static void tps65910_irq_lock(struct irq_data *data)
  81. {
  82. struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
  83. mutex_lock(&tps65910->irq_lock);
  84. }
  85. static void tps65910_irq_sync_unlock(struct irq_data *data)
  86. {
  87. struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
  88. u32 reg_mask;
  89. unsigned int reg;
  90. tps65910_reg_read(tps65910, TPS65910_INT_MSK, &reg);
  91. reg_mask = reg;
  92. tps65910_reg_read(tps65910, TPS65910_INT_MSK2, &reg);
  93. reg_mask |= reg << 8;
  94. switch (tps65910_chip_id(tps65910)) {
  95. case TPS65911:
  96. tps65910_reg_read(tps65910, TPS65910_INT_MSK3, &reg);
  97. reg_mask |= reg << 16;
  98. }
  99. if (tps65910->irq_mask != reg_mask) {
  100. reg = tps65910->irq_mask & 0xFF;
  101. tps65910_reg_write(tps65910, TPS65910_INT_MSK, reg);
  102. reg = tps65910->irq_mask >> 8 & 0xFF;
  103. tps65910_reg_write(tps65910, TPS65910_INT_MSK2, reg);
  104. switch (tps65910_chip_id(tps65910)) {
  105. case TPS65911:
  106. reg = tps65910->irq_mask >> 16;
  107. tps65910_reg_write(tps65910, TPS65910_INT_MSK3, reg);
  108. }
  109. }
  110. mutex_unlock(&tps65910->irq_lock);
  111. }
  112. static void tps65910_irq_enable(struct irq_data *data)
  113. {
  114. struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
  115. tps65910->irq_mask &= ~(1 << data->hwirq);
  116. }
  117. static void tps65910_irq_disable(struct irq_data *data)
  118. {
  119. struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
  120. tps65910->irq_mask |= (1 << data->hwirq);
  121. }
  122. #ifdef CONFIG_PM_SLEEP
  123. static int tps65910_irq_set_wake(struct irq_data *data, unsigned int enable)
  124. {
  125. struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
  126. return irq_set_irq_wake(tps65910->chip_irq, enable);
  127. }
  128. #else
  129. #define tps65910_irq_set_wake NULL
  130. #endif
  131. static struct irq_chip tps65910_irq_chip = {
  132. .name = "tps65910",
  133. .irq_bus_lock = tps65910_irq_lock,
  134. .irq_bus_sync_unlock = tps65910_irq_sync_unlock,
  135. .irq_disable = tps65910_irq_disable,
  136. .irq_enable = tps65910_irq_enable,
  137. .irq_set_wake = tps65910_irq_set_wake,
  138. };
  139. static int tps65910_irq_map(struct irq_domain *h, unsigned int virq,
  140. irq_hw_number_t hw)
  141. {
  142. struct tps65910 *tps65910 = h->host_data;
  143. irq_set_chip_data(virq, tps65910);
  144. irq_set_chip_and_handler(virq, &tps65910_irq_chip, handle_edge_irq);
  145. irq_set_nested_thread(virq, 1);
  146. /* ARM needs us to explicitly flag the IRQ as valid
  147. * and will set them noprobe when we do so. */
  148. #ifdef CONFIG_ARM
  149. set_irq_flags(virq, IRQF_VALID);
  150. #else
  151. irq_set_noprobe(virq);
  152. #endif
  153. return 0;
  154. }
  155. static struct irq_domain_ops tps65910_domain_ops = {
  156. .map = tps65910_irq_map,
  157. .xlate = irq_domain_xlate_twocell,
  158. };
  159. int tps65910_irq_init(struct tps65910 *tps65910, int irq,
  160. struct tps65910_platform_data *pdata)
  161. {
  162. int ret;
  163. int flags = IRQF_ONESHOT;
  164. if (!irq) {
  165. dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n");
  166. return -EINVAL;
  167. }
  168. if (!pdata) {
  169. dev_warn(tps65910->dev, "No interrupt support, no pdata\n");
  170. return -EINVAL;
  171. }
  172. switch (tps65910_chip_id(tps65910)) {
  173. case TPS65910:
  174. tps65910->irq_num = TPS65910_NUM_IRQ;
  175. break;
  176. case TPS65911:
  177. tps65910->irq_num = TPS65911_NUM_IRQ;
  178. break;
  179. }
  180. if (pdata->irq_base > 0) {
  181. pdata->irq_base = irq_alloc_descs(pdata->irq_base, 0,
  182. tps65910->irq_num, -1);
  183. if (pdata->irq_base < 0) {
  184. dev_warn(tps65910->dev, "Failed to alloc IRQs: %d\n",
  185. pdata->irq_base);
  186. return pdata->irq_base;
  187. }
  188. }
  189. tps65910->irq_mask = 0xFFFFFF;
  190. mutex_init(&tps65910->irq_lock);
  191. tps65910->chip_irq = irq;
  192. tps65910->irq_base = pdata->irq_base;
  193. if (pdata->irq_base > 0)
  194. tps65910->domain = irq_domain_add_legacy(tps65910->dev->of_node,
  195. tps65910->irq_num,
  196. pdata->irq_base,
  197. 0,
  198. &tps65910_domain_ops, tps65910);
  199. else
  200. tps65910->domain = irq_domain_add_linear(tps65910->dev->of_node,
  201. tps65910->irq_num,
  202. &tps65910_domain_ops, tps65910);
  203. if (!tps65910->domain) {
  204. dev_err(tps65910->dev, "Failed to create IRQ domain\n");
  205. return -ENOMEM;
  206. }
  207. ret = request_threaded_irq(irq, NULL, tps65910_irq, flags,
  208. "tps65910", tps65910);
  209. irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
  210. if (ret != 0)
  211. dev_err(tps65910->dev, "Failed to request IRQ: %d\n", ret);
  212. return ret;
  213. }
  214. int tps65910_irq_exit(struct tps65910 *tps65910)
  215. {
  216. if (tps65910->chip_irq)
  217. free_irq(tps65910->chip_irq, tps65910);
  218. return 0;
  219. }