mt6397-irq.c 5.1 KB

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