sec-irq.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. // SPDX-License-Identifier: GPL-2.0+
  2. //
  3. // Copyright (c) 2011-2014 Samsung Electronics Co., Ltd
  4. // http://www.samsung.com
  5. #include <linux/device.h>
  6. #include <linux/interrupt.h>
  7. #include <linux/irq.h>
  8. #include <linux/module.h>
  9. #include <linux/regmap.h>
  10. #include <linux/mfd/samsung/core.h>
  11. #include <linux/mfd/samsung/irq.h>
  12. #include <linux/mfd/samsung/s2mps11.h>
  13. #include <linux/mfd/samsung/s2mps14.h>
  14. #include <linux/mfd/samsung/s2mpu02.h>
  15. #include <linux/mfd/samsung/s5m8763.h>
  16. #include <linux/mfd/samsung/s5m8767.h>
  17. static const struct regmap_irq s2mps11_irqs[] = {
  18. [S2MPS11_IRQ_PWRONF] = {
  19. .reg_offset = 0,
  20. .mask = S2MPS11_IRQ_PWRONF_MASK,
  21. },
  22. [S2MPS11_IRQ_PWRONR] = {
  23. .reg_offset = 0,
  24. .mask = S2MPS11_IRQ_PWRONR_MASK,
  25. },
  26. [S2MPS11_IRQ_JIGONBF] = {
  27. .reg_offset = 0,
  28. .mask = S2MPS11_IRQ_JIGONBF_MASK,
  29. },
  30. [S2MPS11_IRQ_JIGONBR] = {
  31. .reg_offset = 0,
  32. .mask = S2MPS11_IRQ_JIGONBR_MASK,
  33. },
  34. [S2MPS11_IRQ_ACOKBF] = {
  35. .reg_offset = 0,
  36. .mask = S2MPS11_IRQ_ACOKBF_MASK,
  37. },
  38. [S2MPS11_IRQ_ACOKBR] = {
  39. .reg_offset = 0,
  40. .mask = S2MPS11_IRQ_ACOKBR_MASK,
  41. },
  42. [S2MPS11_IRQ_PWRON1S] = {
  43. .reg_offset = 0,
  44. .mask = S2MPS11_IRQ_PWRON1S_MASK,
  45. },
  46. [S2MPS11_IRQ_MRB] = {
  47. .reg_offset = 0,
  48. .mask = S2MPS11_IRQ_MRB_MASK,
  49. },
  50. [S2MPS11_IRQ_RTC60S] = {
  51. .reg_offset = 1,
  52. .mask = S2MPS11_IRQ_RTC60S_MASK,
  53. },
  54. [S2MPS11_IRQ_RTCA1] = {
  55. .reg_offset = 1,
  56. .mask = S2MPS11_IRQ_RTCA1_MASK,
  57. },
  58. [S2MPS11_IRQ_RTCA0] = {
  59. .reg_offset = 1,
  60. .mask = S2MPS11_IRQ_RTCA0_MASK,
  61. },
  62. [S2MPS11_IRQ_SMPL] = {
  63. .reg_offset = 1,
  64. .mask = S2MPS11_IRQ_SMPL_MASK,
  65. },
  66. [S2MPS11_IRQ_RTC1S] = {
  67. .reg_offset = 1,
  68. .mask = S2MPS11_IRQ_RTC1S_MASK,
  69. },
  70. [S2MPS11_IRQ_WTSR] = {
  71. .reg_offset = 1,
  72. .mask = S2MPS11_IRQ_WTSR_MASK,
  73. },
  74. [S2MPS11_IRQ_INT120C] = {
  75. .reg_offset = 2,
  76. .mask = S2MPS11_IRQ_INT120C_MASK,
  77. },
  78. [S2MPS11_IRQ_INT140C] = {
  79. .reg_offset = 2,
  80. .mask = S2MPS11_IRQ_INT140C_MASK,
  81. },
  82. };
  83. static const struct regmap_irq s2mps14_irqs[] = {
  84. [S2MPS14_IRQ_PWRONF] = {
  85. .reg_offset = 0,
  86. .mask = S2MPS11_IRQ_PWRONF_MASK,
  87. },
  88. [S2MPS14_IRQ_PWRONR] = {
  89. .reg_offset = 0,
  90. .mask = S2MPS11_IRQ_PWRONR_MASK,
  91. },
  92. [S2MPS14_IRQ_JIGONBF] = {
  93. .reg_offset = 0,
  94. .mask = S2MPS11_IRQ_JIGONBF_MASK,
  95. },
  96. [S2MPS14_IRQ_JIGONBR] = {
  97. .reg_offset = 0,
  98. .mask = S2MPS11_IRQ_JIGONBR_MASK,
  99. },
  100. [S2MPS14_IRQ_ACOKBF] = {
  101. .reg_offset = 0,
  102. .mask = S2MPS11_IRQ_ACOKBF_MASK,
  103. },
  104. [S2MPS14_IRQ_ACOKBR] = {
  105. .reg_offset = 0,
  106. .mask = S2MPS11_IRQ_ACOKBR_MASK,
  107. },
  108. [S2MPS14_IRQ_PWRON1S] = {
  109. .reg_offset = 0,
  110. .mask = S2MPS11_IRQ_PWRON1S_MASK,
  111. },
  112. [S2MPS14_IRQ_MRB] = {
  113. .reg_offset = 0,
  114. .mask = S2MPS11_IRQ_MRB_MASK,
  115. },
  116. [S2MPS14_IRQ_RTC60S] = {
  117. .reg_offset = 1,
  118. .mask = S2MPS11_IRQ_RTC60S_MASK,
  119. },
  120. [S2MPS14_IRQ_RTCA1] = {
  121. .reg_offset = 1,
  122. .mask = S2MPS11_IRQ_RTCA1_MASK,
  123. },
  124. [S2MPS14_IRQ_RTCA0] = {
  125. .reg_offset = 1,
  126. .mask = S2MPS11_IRQ_RTCA0_MASK,
  127. },
  128. [S2MPS14_IRQ_SMPL] = {
  129. .reg_offset = 1,
  130. .mask = S2MPS11_IRQ_SMPL_MASK,
  131. },
  132. [S2MPS14_IRQ_RTC1S] = {
  133. .reg_offset = 1,
  134. .mask = S2MPS11_IRQ_RTC1S_MASK,
  135. },
  136. [S2MPS14_IRQ_WTSR] = {
  137. .reg_offset = 1,
  138. .mask = S2MPS11_IRQ_WTSR_MASK,
  139. },
  140. [S2MPS14_IRQ_INT120C] = {
  141. .reg_offset = 2,
  142. .mask = S2MPS11_IRQ_INT120C_MASK,
  143. },
  144. [S2MPS14_IRQ_INT140C] = {
  145. .reg_offset = 2,
  146. .mask = S2MPS11_IRQ_INT140C_MASK,
  147. },
  148. [S2MPS14_IRQ_TSD] = {
  149. .reg_offset = 2,
  150. .mask = S2MPS14_IRQ_TSD_MASK,
  151. },
  152. };
  153. static const struct regmap_irq s2mpu02_irqs[] = {
  154. [S2MPU02_IRQ_PWRONF] = {
  155. .reg_offset = 0,
  156. .mask = S2MPS11_IRQ_PWRONF_MASK,
  157. },
  158. [S2MPU02_IRQ_PWRONR] = {
  159. .reg_offset = 0,
  160. .mask = S2MPS11_IRQ_PWRONR_MASK,
  161. },
  162. [S2MPU02_IRQ_JIGONBF] = {
  163. .reg_offset = 0,
  164. .mask = S2MPS11_IRQ_JIGONBF_MASK,
  165. },
  166. [S2MPU02_IRQ_JIGONBR] = {
  167. .reg_offset = 0,
  168. .mask = S2MPS11_IRQ_JIGONBR_MASK,
  169. },
  170. [S2MPU02_IRQ_ACOKBF] = {
  171. .reg_offset = 0,
  172. .mask = S2MPS11_IRQ_ACOKBF_MASK,
  173. },
  174. [S2MPU02_IRQ_ACOKBR] = {
  175. .reg_offset = 0,
  176. .mask = S2MPS11_IRQ_ACOKBR_MASK,
  177. },
  178. [S2MPU02_IRQ_PWRON1S] = {
  179. .reg_offset = 0,
  180. .mask = S2MPS11_IRQ_PWRON1S_MASK,
  181. },
  182. [S2MPU02_IRQ_MRB] = {
  183. .reg_offset = 0,
  184. .mask = S2MPS11_IRQ_MRB_MASK,
  185. },
  186. [S2MPU02_IRQ_RTC60S] = {
  187. .reg_offset = 1,
  188. .mask = S2MPS11_IRQ_RTC60S_MASK,
  189. },
  190. [S2MPU02_IRQ_RTCA1] = {
  191. .reg_offset = 1,
  192. .mask = S2MPS11_IRQ_RTCA1_MASK,
  193. },
  194. [S2MPU02_IRQ_RTCA0] = {
  195. .reg_offset = 1,
  196. .mask = S2MPS11_IRQ_RTCA0_MASK,
  197. },
  198. [S2MPU02_IRQ_SMPL] = {
  199. .reg_offset = 1,
  200. .mask = S2MPS11_IRQ_SMPL_MASK,
  201. },
  202. [S2MPU02_IRQ_RTC1S] = {
  203. .reg_offset = 1,
  204. .mask = S2MPS11_IRQ_RTC1S_MASK,
  205. },
  206. [S2MPU02_IRQ_WTSR] = {
  207. .reg_offset = 1,
  208. .mask = S2MPS11_IRQ_WTSR_MASK,
  209. },
  210. [S2MPU02_IRQ_INT120C] = {
  211. .reg_offset = 2,
  212. .mask = S2MPS11_IRQ_INT120C_MASK,
  213. },
  214. [S2MPU02_IRQ_INT140C] = {
  215. .reg_offset = 2,
  216. .mask = S2MPS11_IRQ_INT140C_MASK,
  217. },
  218. [S2MPU02_IRQ_TSD] = {
  219. .reg_offset = 2,
  220. .mask = S2MPS14_IRQ_TSD_MASK,
  221. },
  222. };
  223. static const struct regmap_irq s5m8767_irqs[] = {
  224. [S5M8767_IRQ_PWRR] = {
  225. .reg_offset = 0,
  226. .mask = S5M8767_IRQ_PWRR_MASK,
  227. },
  228. [S5M8767_IRQ_PWRF] = {
  229. .reg_offset = 0,
  230. .mask = S5M8767_IRQ_PWRF_MASK,
  231. },
  232. [S5M8767_IRQ_PWR1S] = {
  233. .reg_offset = 0,
  234. .mask = S5M8767_IRQ_PWR1S_MASK,
  235. },
  236. [S5M8767_IRQ_JIGR] = {
  237. .reg_offset = 0,
  238. .mask = S5M8767_IRQ_JIGR_MASK,
  239. },
  240. [S5M8767_IRQ_JIGF] = {
  241. .reg_offset = 0,
  242. .mask = S5M8767_IRQ_JIGF_MASK,
  243. },
  244. [S5M8767_IRQ_LOWBAT2] = {
  245. .reg_offset = 0,
  246. .mask = S5M8767_IRQ_LOWBAT2_MASK,
  247. },
  248. [S5M8767_IRQ_LOWBAT1] = {
  249. .reg_offset = 0,
  250. .mask = S5M8767_IRQ_LOWBAT1_MASK,
  251. },
  252. [S5M8767_IRQ_MRB] = {
  253. .reg_offset = 1,
  254. .mask = S5M8767_IRQ_MRB_MASK,
  255. },
  256. [S5M8767_IRQ_DVSOK2] = {
  257. .reg_offset = 1,
  258. .mask = S5M8767_IRQ_DVSOK2_MASK,
  259. },
  260. [S5M8767_IRQ_DVSOK3] = {
  261. .reg_offset = 1,
  262. .mask = S5M8767_IRQ_DVSOK3_MASK,
  263. },
  264. [S5M8767_IRQ_DVSOK4] = {
  265. .reg_offset = 1,
  266. .mask = S5M8767_IRQ_DVSOK4_MASK,
  267. },
  268. [S5M8767_IRQ_RTC60S] = {
  269. .reg_offset = 2,
  270. .mask = S5M8767_IRQ_RTC60S_MASK,
  271. },
  272. [S5M8767_IRQ_RTCA1] = {
  273. .reg_offset = 2,
  274. .mask = S5M8767_IRQ_RTCA1_MASK,
  275. },
  276. [S5M8767_IRQ_RTCA2] = {
  277. .reg_offset = 2,
  278. .mask = S5M8767_IRQ_RTCA2_MASK,
  279. },
  280. [S5M8767_IRQ_SMPL] = {
  281. .reg_offset = 2,
  282. .mask = S5M8767_IRQ_SMPL_MASK,
  283. },
  284. [S5M8767_IRQ_RTC1S] = {
  285. .reg_offset = 2,
  286. .mask = S5M8767_IRQ_RTC1S_MASK,
  287. },
  288. [S5M8767_IRQ_WTSR] = {
  289. .reg_offset = 2,
  290. .mask = S5M8767_IRQ_WTSR_MASK,
  291. },
  292. };
  293. static const struct regmap_irq s5m8763_irqs[] = {
  294. [S5M8763_IRQ_DCINF] = {
  295. .reg_offset = 0,
  296. .mask = S5M8763_IRQ_DCINF_MASK,
  297. },
  298. [S5M8763_IRQ_DCINR] = {
  299. .reg_offset = 0,
  300. .mask = S5M8763_IRQ_DCINR_MASK,
  301. },
  302. [S5M8763_IRQ_JIGF] = {
  303. .reg_offset = 0,
  304. .mask = S5M8763_IRQ_JIGF_MASK,
  305. },
  306. [S5M8763_IRQ_JIGR] = {
  307. .reg_offset = 0,
  308. .mask = S5M8763_IRQ_JIGR_MASK,
  309. },
  310. [S5M8763_IRQ_PWRONF] = {
  311. .reg_offset = 0,
  312. .mask = S5M8763_IRQ_PWRONF_MASK,
  313. },
  314. [S5M8763_IRQ_PWRONR] = {
  315. .reg_offset = 0,
  316. .mask = S5M8763_IRQ_PWRONR_MASK,
  317. },
  318. [S5M8763_IRQ_WTSREVNT] = {
  319. .reg_offset = 1,
  320. .mask = S5M8763_IRQ_WTSREVNT_MASK,
  321. },
  322. [S5M8763_IRQ_SMPLEVNT] = {
  323. .reg_offset = 1,
  324. .mask = S5M8763_IRQ_SMPLEVNT_MASK,
  325. },
  326. [S5M8763_IRQ_ALARM1] = {
  327. .reg_offset = 1,
  328. .mask = S5M8763_IRQ_ALARM1_MASK,
  329. },
  330. [S5M8763_IRQ_ALARM0] = {
  331. .reg_offset = 1,
  332. .mask = S5M8763_IRQ_ALARM0_MASK,
  333. },
  334. [S5M8763_IRQ_ONKEY1S] = {
  335. .reg_offset = 2,
  336. .mask = S5M8763_IRQ_ONKEY1S_MASK,
  337. },
  338. [S5M8763_IRQ_TOPOFFR] = {
  339. .reg_offset = 2,
  340. .mask = S5M8763_IRQ_TOPOFFR_MASK,
  341. },
  342. [S5M8763_IRQ_DCINOVPR] = {
  343. .reg_offset = 2,
  344. .mask = S5M8763_IRQ_DCINOVPR_MASK,
  345. },
  346. [S5M8763_IRQ_CHGRSTF] = {
  347. .reg_offset = 2,
  348. .mask = S5M8763_IRQ_CHGRSTF_MASK,
  349. },
  350. [S5M8763_IRQ_DONER] = {
  351. .reg_offset = 2,
  352. .mask = S5M8763_IRQ_DONER_MASK,
  353. },
  354. [S5M8763_IRQ_CHGFAULT] = {
  355. .reg_offset = 2,
  356. .mask = S5M8763_IRQ_CHGFAULT_MASK,
  357. },
  358. [S5M8763_IRQ_LOBAT1] = {
  359. .reg_offset = 3,
  360. .mask = S5M8763_IRQ_LOBAT1_MASK,
  361. },
  362. [S5M8763_IRQ_LOBAT2] = {
  363. .reg_offset = 3,
  364. .mask = S5M8763_IRQ_LOBAT2_MASK,
  365. },
  366. };
  367. static const struct regmap_irq_chip s2mps11_irq_chip = {
  368. .name = "s2mps11",
  369. .irqs = s2mps11_irqs,
  370. .num_irqs = ARRAY_SIZE(s2mps11_irqs),
  371. .num_regs = 3,
  372. .status_base = S2MPS11_REG_INT1,
  373. .mask_base = S2MPS11_REG_INT1M,
  374. .ack_base = S2MPS11_REG_INT1,
  375. };
  376. #define S2MPS1X_IRQ_CHIP_COMMON_DATA \
  377. .irqs = s2mps14_irqs, \
  378. .num_irqs = ARRAY_SIZE(s2mps14_irqs), \
  379. .num_regs = 3, \
  380. .status_base = S2MPS14_REG_INT1, \
  381. .mask_base = S2MPS14_REG_INT1M, \
  382. .ack_base = S2MPS14_REG_INT1 \
  383. static const struct regmap_irq_chip s2mps13_irq_chip = {
  384. .name = "s2mps13",
  385. S2MPS1X_IRQ_CHIP_COMMON_DATA,
  386. };
  387. static const struct regmap_irq_chip s2mps14_irq_chip = {
  388. .name = "s2mps14",
  389. S2MPS1X_IRQ_CHIP_COMMON_DATA,
  390. };
  391. static const struct regmap_irq_chip s2mps15_irq_chip = {
  392. .name = "s2mps15",
  393. S2MPS1X_IRQ_CHIP_COMMON_DATA,
  394. };
  395. static const struct regmap_irq_chip s2mpu02_irq_chip = {
  396. .name = "s2mpu02",
  397. .irqs = s2mpu02_irqs,
  398. .num_irqs = ARRAY_SIZE(s2mpu02_irqs),
  399. .num_regs = 3,
  400. .status_base = S2MPU02_REG_INT1,
  401. .mask_base = S2MPU02_REG_INT1M,
  402. .ack_base = S2MPU02_REG_INT1,
  403. };
  404. static const struct regmap_irq_chip s5m8767_irq_chip = {
  405. .name = "s5m8767",
  406. .irqs = s5m8767_irqs,
  407. .num_irqs = ARRAY_SIZE(s5m8767_irqs),
  408. .num_regs = 3,
  409. .status_base = S5M8767_REG_INT1,
  410. .mask_base = S5M8767_REG_INT1M,
  411. .ack_base = S5M8767_REG_INT1,
  412. };
  413. static const struct regmap_irq_chip s5m8763_irq_chip = {
  414. .name = "s5m8763",
  415. .irqs = s5m8763_irqs,
  416. .num_irqs = ARRAY_SIZE(s5m8763_irqs),
  417. .num_regs = 4,
  418. .status_base = S5M8763_REG_IRQ1,
  419. .mask_base = S5M8763_REG_IRQM1,
  420. .ack_base = S5M8763_REG_IRQ1,
  421. };
  422. int sec_irq_init(struct sec_pmic_dev *sec_pmic)
  423. {
  424. int ret = 0;
  425. int type = sec_pmic->device_type;
  426. const struct regmap_irq_chip *sec_irq_chip;
  427. if (!sec_pmic->irq) {
  428. dev_warn(sec_pmic->dev,
  429. "No interrupt specified, no interrupts\n");
  430. return 0;
  431. }
  432. switch (type) {
  433. case S5M8763X:
  434. sec_irq_chip = &s5m8763_irq_chip;
  435. break;
  436. case S5M8767X:
  437. sec_irq_chip = &s5m8767_irq_chip;
  438. break;
  439. case S2MPA01:
  440. sec_irq_chip = &s2mps14_irq_chip;
  441. break;
  442. case S2MPS11X:
  443. sec_irq_chip = &s2mps11_irq_chip;
  444. break;
  445. case S2MPS13X:
  446. sec_irq_chip = &s2mps13_irq_chip;
  447. break;
  448. case S2MPS14X:
  449. sec_irq_chip = &s2mps14_irq_chip;
  450. break;
  451. case S2MPS15X:
  452. sec_irq_chip = &s2mps15_irq_chip;
  453. break;
  454. case S2MPU02:
  455. sec_irq_chip = &s2mpu02_irq_chip;
  456. break;
  457. default:
  458. dev_err(sec_pmic->dev, "Unknown device type %lu\n",
  459. sec_pmic->device_type);
  460. return -EINVAL;
  461. }
  462. ret = devm_regmap_add_irq_chip(sec_pmic->dev, sec_pmic->regmap_pmic,
  463. sec_pmic->irq, IRQF_ONESHOT,
  464. 0, sec_irq_chip, &sec_pmic->irq_data);
  465. if (ret != 0) {
  466. dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret);
  467. return ret;
  468. }
  469. /*
  470. * The rtc-s5m driver requests S2MPS14_IRQ_RTCA0 also for S2MPS11
  471. * so the interrupt number must be consistent.
  472. */
  473. BUILD_BUG_ON(((enum s2mps14_irq)S2MPS11_IRQ_RTCA0) != S2MPS14_IRQ_RTCA0);
  474. return 0;
  475. }
  476. EXPORT_SYMBOL_GPL(sec_irq_init);
  477. MODULE_AUTHOR("Sangbeom Kim <[email protected]>");
  478. MODULE_AUTHOR("Chanwoo Choi <[email protected]>");
  479. MODULE_AUTHOR("Krzysztof Kozlowski <[email protected]>");
  480. MODULE_DESCRIPTION("Interrupt support for the S5M MFD");
  481. MODULE_LICENSE("GPL");