mt6397-irq.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // Copyright (c) 2019 MediaTek Inc.
  4. #include <linux/interrupt.h>
  5. #include <linux/module.h>
  6. #include <linux/of.h>
  7. #include <linux/of_device.h>
  8. #include <linux/of_irq.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/regmap.h>
  11. #include <linux/suspend.h>
  12. #include <linux/mfd/mt6323/core.h>
  13. #include <linux/mfd/mt6323/registers.h>
  14. #include <linux/mfd/mt6331/core.h>
  15. #include <linux/mfd/mt6331/registers.h>
  16. #include <linux/mfd/mt6397/core.h>
  17. #include <linux/mfd/mt6397/registers.h>
  18. static void mt6397_irq_lock(struct irq_data *data)
  19. {
  20. struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
  21. mutex_lock(&mt6397->irqlock);
  22. }
  23. static void mt6397_irq_sync_unlock(struct irq_data *data)
  24. {
  25. struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
  26. regmap_write(mt6397->regmap, mt6397->int_con[0],
  27. mt6397->irq_masks_cur[0]);
  28. regmap_write(mt6397->regmap, mt6397->int_con[1],
  29. mt6397->irq_masks_cur[1]);
  30. mutex_unlock(&mt6397->irqlock);
  31. }
  32. static void mt6397_irq_disable(struct irq_data *data)
  33. {
  34. struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
  35. int shift = data->hwirq & 0xf;
  36. int reg = data->hwirq >> 4;
  37. mt6397->irq_masks_cur[reg] &= ~BIT(shift);
  38. }
  39. static void mt6397_irq_enable(struct irq_data *data)
  40. {
  41. struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
  42. int shift = data->hwirq & 0xf;
  43. int reg = data->hwirq >> 4;
  44. mt6397->irq_masks_cur[reg] |= BIT(shift);
  45. }
  46. #ifdef CONFIG_PM_SLEEP
  47. static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
  48. {
  49. struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
  50. int shift = irq_data->hwirq & 0xf;
  51. int reg = irq_data->hwirq >> 4;
  52. if (on)
  53. mt6397->wake_mask[reg] |= BIT(shift);
  54. else
  55. mt6397->wake_mask[reg] &= ~BIT(shift);
  56. return 0;
  57. }
  58. #else
  59. #define mt6397_irq_set_wake NULL
  60. #endif
  61. static struct irq_chip mt6397_irq_chip = {
  62. .name = "mt6397-irq",
  63. .irq_bus_lock = mt6397_irq_lock,
  64. .irq_bus_sync_unlock = mt6397_irq_sync_unlock,
  65. .irq_enable = mt6397_irq_enable,
  66. .irq_disable = mt6397_irq_disable,
  67. .irq_set_wake = mt6397_irq_set_wake,
  68. };
  69. static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
  70. int irqbase)
  71. {
  72. unsigned int status = 0;
  73. int i, irq, ret;
  74. ret = regmap_read(mt6397->regmap, reg, &status);
  75. if (ret) {
  76. dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
  77. return;
  78. }
  79. for (i = 0; i < 16; i++) {
  80. if (status & BIT(i)) {
  81. irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
  82. if (irq)
  83. handle_nested_irq(irq);
  84. }
  85. }
  86. regmap_write(mt6397->regmap, reg, status);
  87. }
  88. static irqreturn_t mt6397_irq_thread(int irq, void *data)
  89. {
  90. struct mt6397_chip *mt6397 = data;
  91. mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
  92. mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
  93. return IRQ_HANDLED;
  94. }
  95. static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
  96. irq_hw_number_t hw)
  97. {
  98. struct mt6397_chip *mt6397 = d->host_data;
  99. irq_set_chip_data(irq, mt6397);
  100. irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
  101. irq_set_nested_thread(irq, 1);
  102. irq_set_noprobe(irq);
  103. return 0;
  104. }
  105. static const struct irq_domain_ops mt6397_irq_domain_ops = {
  106. .map = mt6397_irq_domain_map,
  107. };
  108. static int mt6397_irq_pm_notifier(struct notifier_block *notifier,
  109. unsigned long pm_event, void *unused)
  110. {
  111. struct mt6397_chip *chip =
  112. container_of(notifier, struct mt6397_chip, pm_nb);
  113. switch (pm_event) {
  114. case PM_SUSPEND_PREPARE:
  115. regmap_write(chip->regmap,
  116. chip->int_con[0], chip->wake_mask[0]);
  117. regmap_write(chip->regmap,
  118. chip->int_con[1], chip->wake_mask[1]);
  119. enable_irq_wake(chip->irq);
  120. break;
  121. case PM_POST_SUSPEND:
  122. regmap_write(chip->regmap,
  123. chip->int_con[0], chip->irq_masks_cur[0]);
  124. regmap_write(chip->regmap,
  125. chip->int_con[1], chip->irq_masks_cur[1]);
  126. disable_irq_wake(chip->irq);
  127. break;
  128. default:
  129. break;
  130. }
  131. return NOTIFY_DONE;
  132. }
  133. int mt6397_irq_init(struct mt6397_chip *chip)
  134. {
  135. int ret;
  136. mutex_init(&chip->irqlock);
  137. switch (chip->chip_id) {
  138. case MT6323_CHIP_ID:
  139. chip->int_con[0] = MT6323_INT_CON0;
  140. chip->int_con[1] = MT6323_INT_CON1;
  141. chip->int_status[0] = MT6323_INT_STATUS0;
  142. chip->int_status[1] = MT6323_INT_STATUS1;
  143. break;
  144. case MT6331_CHIP_ID:
  145. chip->int_con[0] = MT6331_INT_CON0;
  146. chip->int_con[1] = MT6331_INT_CON1;
  147. chip->int_status[0] = MT6331_INT_STATUS_CON0;
  148. chip->int_status[1] = MT6331_INT_STATUS_CON1;
  149. break;
  150. case MT6391_CHIP_ID:
  151. case MT6397_CHIP_ID:
  152. chip->int_con[0] = MT6397_INT_CON0;
  153. chip->int_con[1] = MT6397_INT_CON1;
  154. chip->int_status[0] = MT6397_INT_STATUS0;
  155. chip->int_status[1] = MT6397_INT_STATUS1;
  156. break;
  157. default:
  158. dev_err(chip->dev, "unsupported chip: 0x%x\n", chip->chip_id);
  159. return -ENODEV;
  160. }
  161. /* Mask all interrupt sources */
  162. regmap_write(chip->regmap, chip->int_con[0], 0x0);
  163. regmap_write(chip->regmap, chip->int_con[1], 0x0);
  164. chip->pm_nb.notifier_call = mt6397_irq_pm_notifier;
  165. chip->irq_domain = irq_domain_add_linear(chip->dev->of_node,
  166. MT6397_IRQ_NR,
  167. &mt6397_irq_domain_ops,
  168. chip);
  169. if (!chip->irq_domain) {
  170. dev_err(chip->dev, "could not create irq domain\n");
  171. return -ENOMEM;
  172. }
  173. ret = devm_request_threaded_irq(chip->dev, chip->irq, NULL,
  174. mt6397_irq_thread, IRQF_ONESHOT,
  175. "mt6397-pmic", chip);
  176. if (ret) {
  177. dev_err(chip->dev, "failed to register irq=%d; err: %d\n",
  178. chip->irq, ret);
  179. return ret;
  180. }
  181. register_pm_notifier(&chip->pm_nb);
  182. return 0;
  183. }