qcom-pm8xxx.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
  4. */
  5. #define pr_fmt(fmt) "%s: " fmt, __func__
  6. #include <linux/kernel.h>
  7. #include <linux/interrupt.h>
  8. #include <linux/irqchip/chained_irq.h>
  9. #include <linux/irq.h>
  10. #include <linux/irqdomain.h>
  11. #include <linux/module.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/slab.h>
  14. #include <linux/err.h>
  15. #include <linux/ssbi.h>
  16. #include <linux/regmap.h>
  17. #include <linux/of_platform.h>
  18. #include <linux/mfd/core.h>
  19. #define SSBI_REG_ADDR_IRQ_BASE 0x1BB
  20. #define SSBI_REG_ADDR_IRQ_ROOT (SSBI_REG_ADDR_IRQ_BASE + 0)
  21. #define SSBI_REG_ADDR_IRQ_M_STATUS1 (SSBI_REG_ADDR_IRQ_BASE + 1)
  22. #define SSBI_REG_ADDR_IRQ_M_STATUS2 (SSBI_REG_ADDR_IRQ_BASE + 2)
  23. #define SSBI_REG_ADDR_IRQ_M_STATUS3 (SSBI_REG_ADDR_IRQ_BASE + 3)
  24. #define SSBI_REG_ADDR_IRQ_M_STATUS4 (SSBI_REG_ADDR_IRQ_BASE + 4)
  25. #define SSBI_REG_ADDR_IRQ_BLK_SEL (SSBI_REG_ADDR_IRQ_BASE + 5)
  26. #define SSBI_REG_ADDR_IRQ_IT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 6)
  27. #define SSBI_REG_ADDR_IRQ_CONFIG (SSBI_REG_ADDR_IRQ_BASE + 7)
  28. #define SSBI_REG_ADDR_IRQ_RT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 8)
  29. #define PM8821_SSBI_REG_ADDR_IRQ_BASE 0x100
  30. #define PM8821_SSBI_REG_ADDR_IRQ_MASTER0 (PM8821_SSBI_REG_ADDR_IRQ_BASE + 0x30)
  31. #define PM8821_SSBI_REG_ADDR_IRQ_MASTER1 (PM8821_SSBI_REG_ADDR_IRQ_BASE + 0xb0)
  32. #define PM8821_SSBI_REG(m, b, offset) \
  33. ((m == 0) ? \
  34. (PM8821_SSBI_REG_ADDR_IRQ_MASTER0 + b + offset) : \
  35. (PM8821_SSBI_REG_ADDR_IRQ_MASTER1 + b + offset))
  36. #define PM8821_SSBI_ADDR_IRQ_ROOT(m, b) PM8821_SSBI_REG(m, b, 0x0)
  37. #define PM8821_SSBI_ADDR_IRQ_CLEAR(m, b) PM8821_SSBI_REG(m, b, 0x01)
  38. #define PM8821_SSBI_ADDR_IRQ_MASK(m, b) PM8821_SSBI_REG(m, b, 0x08)
  39. #define PM8821_SSBI_ADDR_IRQ_RT_STATUS(m, b) PM8821_SSBI_REG(m, b, 0x0f)
  40. #define PM8821_BLOCKS_PER_MASTER 7
  41. #define PM_IRQF_LVL_SEL 0x01 /* level select */
  42. #define PM_IRQF_MASK_FE 0x02 /* mask falling edge */
  43. #define PM_IRQF_MASK_RE 0x04 /* mask rising edge */
  44. #define PM_IRQF_CLR 0x08 /* clear interrupt */
  45. #define PM_IRQF_BITS_MASK 0x70
  46. #define PM_IRQF_BITS_SHIFT 4
  47. #define PM_IRQF_WRITE 0x80
  48. #define PM_IRQF_MASK_ALL (PM_IRQF_MASK_FE | \
  49. PM_IRQF_MASK_RE)
  50. #define REG_HWREV 0x002 /* PMIC4 revision */
  51. #define REG_HWREV_2 0x0E8 /* PMIC4 revision 2 */
  52. #define PM8XXX_NR_IRQS 256
  53. #define PM8821_NR_IRQS 112
  54. struct pm_irq_data {
  55. int num_irqs;
  56. struct irq_chip *irq_chip;
  57. irq_handler_t irq_handler;
  58. };
  59. struct pm_irq_chip {
  60. struct regmap *regmap;
  61. spinlock_t pm_irq_lock;
  62. struct irq_domain *irqdomain;
  63. unsigned int num_blocks;
  64. unsigned int num_masters;
  65. const struct pm_irq_data *pm_irq_data;
  66. /* MUST BE AT THE END OF THIS STRUCT */
  67. u8 config[];
  68. };
  69. static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp,
  70. unsigned int *ip)
  71. {
  72. int rc;
  73. spin_lock(&chip->pm_irq_lock);
  74. rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
  75. if (rc) {
  76. pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
  77. goto bail;
  78. }
  79. rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_IT_STATUS, ip);
  80. if (rc)
  81. pr_err("Failed Reading Status rc=%d\n", rc);
  82. bail:
  83. spin_unlock(&chip->pm_irq_lock);
  84. return rc;
  85. }
  86. static int
  87. pm8xxx_config_irq(struct pm_irq_chip *chip, unsigned int bp, unsigned int cp)
  88. {
  89. int rc;
  90. spin_lock(&chip->pm_irq_lock);
  91. rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
  92. if (rc) {
  93. pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
  94. goto bail;
  95. }
  96. cp |= PM_IRQF_WRITE;
  97. rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_CONFIG, cp);
  98. if (rc)
  99. pr_err("Failed Configuring IRQ rc=%d\n", rc);
  100. bail:
  101. spin_unlock(&chip->pm_irq_lock);
  102. return rc;
  103. }
  104. static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block)
  105. {
  106. int pmirq, i, ret = 0;
  107. unsigned int bits;
  108. ret = pm8xxx_read_block_irq(chip, block, &bits);
  109. if (ret) {
  110. pr_err("Failed reading %d block ret=%d", block, ret);
  111. return ret;
  112. }
  113. if (!bits) {
  114. pr_err("block bit set in master but no irqs: %d", block);
  115. return 0;
  116. }
  117. /* Check IRQ bits */
  118. for (i = 0; i < 8; i++) {
  119. if (bits & (1 << i)) {
  120. pmirq = block * 8 + i;
  121. generic_handle_domain_irq(chip->irqdomain, pmirq);
  122. }
  123. }
  124. return 0;
  125. }
  126. static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master)
  127. {
  128. unsigned int blockbits;
  129. int block_number, i, ret = 0;
  130. ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_M_STATUS1 + master,
  131. &blockbits);
  132. if (ret) {
  133. pr_err("Failed to read master %d ret=%d\n", master, ret);
  134. return ret;
  135. }
  136. if (!blockbits) {
  137. pr_err("master bit set in root but no blocks: %d", master);
  138. return 0;
  139. }
  140. for (i = 0; i < 8; i++)
  141. if (blockbits & (1 << i)) {
  142. block_number = master * 8 + i; /* block # */
  143. ret |= pm8xxx_irq_block_handler(chip, block_number);
  144. }
  145. return ret;
  146. }
  147. static irqreturn_t pm8xxx_irq_handler(int irq, void *data)
  148. {
  149. struct pm_irq_chip *chip = data;
  150. unsigned int root;
  151. int i, ret, masters = 0;
  152. ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_ROOT, &root);
  153. if (ret) {
  154. pr_err("Can't read root status ret=%d\n", ret);
  155. return IRQ_NONE;
  156. }
  157. /* on pm8xxx series masters start from bit 1 of the root */
  158. masters = root >> 1;
  159. /* Read allowed masters for blocks. */
  160. for (i = 0; i < chip->num_masters; i++)
  161. if (masters & (1 << i))
  162. pm8xxx_irq_master_handler(chip, i);
  163. return IRQ_HANDLED;
  164. }
  165. static void pm8821_irq_block_handler(struct pm_irq_chip *chip,
  166. int master, int block)
  167. {
  168. int pmirq, i, ret;
  169. unsigned int bits;
  170. ret = regmap_read(chip->regmap,
  171. PM8821_SSBI_ADDR_IRQ_ROOT(master, block), &bits);
  172. if (ret) {
  173. pr_err("Reading block %d failed ret=%d", block, ret);
  174. return;
  175. }
  176. /* Convert block offset to global block number */
  177. block += (master * PM8821_BLOCKS_PER_MASTER) - 1;
  178. /* Check IRQ bits */
  179. for (i = 0; i < 8; i++) {
  180. if (bits & BIT(i)) {
  181. pmirq = block * 8 + i;
  182. generic_handle_domain_irq(chip->irqdomain, pmirq);
  183. }
  184. }
  185. }
  186. static inline void pm8821_irq_master_handler(struct pm_irq_chip *chip,
  187. int master, u8 master_val)
  188. {
  189. int block;
  190. for (block = 1; block < 8; block++)
  191. if (master_val & BIT(block))
  192. pm8821_irq_block_handler(chip, master, block);
  193. }
  194. static irqreturn_t pm8821_irq_handler(int irq, void *data)
  195. {
  196. struct pm_irq_chip *chip = data;
  197. unsigned int master;
  198. int ret;
  199. ret = regmap_read(chip->regmap,
  200. PM8821_SSBI_REG_ADDR_IRQ_MASTER0, &master);
  201. if (ret) {
  202. pr_err("Failed to read master 0 ret=%d\n", ret);
  203. return IRQ_NONE;
  204. }
  205. /* bits 1 through 7 marks the first 7 blocks in master 0 */
  206. if (master & GENMASK(7, 1))
  207. pm8821_irq_master_handler(chip, 0, master);
  208. /* bit 0 marks if master 1 contains any bits */
  209. if (!(master & BIT(0)))
  210. return IRQ_NONE;
  211. ret = regmap_read(chip->regmap,
  212. PM8821_SSBI_REG_ADDR_IRQ_MASTER1, &master);
  213. if (ret) {
  214. pr_err("Failed to read master 1 ret=%d\n", ret);
  215. return IRQ_NONE;
  216. }
  217. pm8821_irq_master_handler(chip, 1, master);
  218. return IRQ_HANDLED;
  219. }
  220. static void pm8xxx_irq_mask_ack(struct irq_data *d)
  221. {
  222. struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
  223. unsigned int pmirq = irqd_to_hwirq(d);
  224. u8 block, config;
  225. block = pmirq / 8;
  226. config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR;
  227. pm8xxx_config_irq(chip, block, config);
  228. }
  229. static void pm8xxx_irq_unmask(struct irq_data *d)
  230. {
  231. struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
  232. unsigned int pmirq = irqd_to_hwirq(d);
  233. u8 block, config;
  234. block = pmirq / 8;
  235. config = chip->config[pmirq];
  236. pm8xxx_config_irq(chip, block, config);
  237. }
  238. static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
  239. {
  240. struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
  241. unsigned int pmirq = irqd_to_hwirq(d);
  242. int irq_bit;
  243. u8 block, config;
  244. block = pmirq / 8;
  245. irq_bit = pmirq % 8;
  246. chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT)
  247. | PM_IRQF_MASK_ALL;
  248. if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
  249. if (flow_type & IRQF_TRIGGER_RISING)
  250. chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
  251. if (flow_type & IRQF_TRIGGER_FALLING)
  252. chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
  253. } else {
  254. chip->config[pmirq] |= PM_IRQF_LVL_SEL;
  255. if (flow_type & IRQF_TRIGGER_HIGH)
  256. chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
  257. else
  258. chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
  259. }
  260. config = chip->config[pmirq] | PM_IRQF_CLR;
  261. return pm8xxx_config_irq(chip, block, config);
  262. }
  263. static int pm8xxx_irq_get_irqchip_state(struct irq_data *d,
  264. enum irqchip_irq_state which,
  265. bool *state)
  266. {
  267. struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
  268. unsigned int pmirq = irqd_to_hwirq(d);
  269. unsigned int bits;
  270. int irq_bit;
  271. u8 block;
  272. int rc;
  273. if (which != IRQCHIP_STATE_LINE_LEVEL)
  274. return -EINVAL;
  275. block = pmirq / 8;
  276. irq_bit = pmirq % 8;
  277. spin_lock(&chip->pm_irq_lock);
  278. rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, block);
  279. if (rc) {
  280. pr_err("Failed Selecting Block %d rc=%d\n", block, rc);
  281. goto bail;
  282. }
  283. rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits);
  284. if (rc) {
  285. pr_err("Failed Reading Status rc=%d\n", rc);
  286. goto bail;
  287. }
  288. *state = !!(bits & BIT(irq_bit));
  289. bail:
  290. spin_unlock(&chip->pm_irq_lock);
  291. return rc;
  292. }
  293. static struct irq_chip pm8xxx_irq_chip = {
  294. .name = "pm8xxx",
  295. .irq_mask_ack = pm8xxx_irq_mask_ack,
  296. .irq_unmask = pm8xxx_irq_unmask,
  297. .irq_set_type = pm8xxx_irq_set_type,
  298. .irq_get_irqchip_state = pm8xxx_irq_get_irqchip_state,
  299. .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
  300. };
  301. static void pm8xxx_irq_domain_map(struct pm_irq_chip *chip,
  302. struct irq_domain *domain, unsigned int irq,
  303. irq_hw_number_t hwirq, unsigned int type)
  304. {
  305. irq_domain_set_info(domain, irq, hwirq, chip->pm_irq_data->irq_chip,
  306. chip, handle_level_irq, NULL, NULL);
  307. irq_set_noprobe(irq);
  308. }
  309. static int pm8xxx_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
  310. unsigned int nr_irqs, void *data)
  311. {
  312. struct pm_irq_chip *chip = domain->host_data;
  313. struct irq_fwspec *fwspec = data;
  314. irq_hw_number_t hwirq;
  315. unsigned int type;
  316. int ret, i;
  317. ret = irq_domain_translate_twocell(domain, fwspec, &hwirq, &type);
  318. if (ret)
  319. return ret;
  320. for (i = 0; i < nr_irqs; i++)
  321. pm8xxx_irq_domain_map(chip, domain, virq + i, hwirq + i, type);
  322. return 0;
  323. }
  324. static const struct irq_domain_ops pm8xxx_irq_domain_ops = {
  325. .alloc = pm8xxx_irq_domain_alloc,
  326. .free = irq_domain_free_irqs_common,
  327. .translate = irq_domain_translate_twocell,
  328. };
  329. static void pm8821_irq_mask_ack(struct irq_data *d)
  330. {
  331. struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
  332. unsigned int pmirq = irqd_to_hwirq(d);
  333. u8 block, master;
  334. int irq_bit, rc;
  335. block = pmirq / 8;
  336. master = block / PM8821_BLOCKS_PER_MASTER;
  337. irq_bit = pmirq % 8;
  338. block %= PM8821_BLOCKS_PER_MASTER;
  339. rc = regmap_update_bits(chip->regmap,
  340. PM8821_SSBI_ADDR_IRQ_MASK(master, block),
  341. BIT(irq_bit), BIT(irq_bit));
  342. if (rc) {
  343. pr_err("Failed to mask IRQ:%d rc=%d\n", pmirq, rc);
  344. return;
  345. }
  346. rc = regmap_update_bits(chip->regmap,
  347. PM8821_SSBI_ADDR_IRQ_CLEAR(master, block),
  348. BIT(irq_bit), BIT(irq_bit));
  349. if (rc)
  350. pr_err("Failed to CLEAR IRQ:%d rc=%d\n", pmirq, rc);
  351. }
  352. static void pm8821_irq_unmask(struct irq_data *d)
  353. {
  354. struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
  355. unsigned int pmirq = irqd_to_hwirq(d);
  356. int irq_bit, rc;
  357. u8 block, master;
  358. block = pmirq / 8;
  359. master = block / PM8821_BLOCKS_PER_MASTER;
  360. irq_bit = pmirq % 8;
  361. block %= PM8821_BLOCKS_PER_MASTER;
  362. rc = regmap_update_bits(chip->regmap,
  363. PM8821_SSBI_ADDR_IRQ_MASK(master, block),
  364. BIT(irq_bit), ~BIT(irq_bit));
  365. if (rc)
  366. pr_err("Failed to read/write unmask IRQ:%d rc=%d\n", pmirq, rc);
  367. }
  368. static int pm8821_irq_get_irqchip_state(struct irq_data *d,
  369. enum irqchip_irq_state which,
  370. bool *state)
  371. {
  372. struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
  373. int rc, pmirq = irqd_to_hwirq(d);
  374. u8 block, irq_bit, master;
  375. unsigned int bits;
  376. block = pmirq / 8;
  377. master = block / PM8821_BLOCKS_PER_MASTER;
  378. irq_bit = pmirq % 8;
  379. block %= PM8821_BLOCKS_PER_MASTER;
  380. rc = regmap_read(chip->regmap,
  381. PM8821_SSBI_ADDR_IRQ_RT_STATUS(master, block), &bits);
  382. if (rc) {
  383. pr_err("Reading Status of IRQ %d failed rc=%d\n", pmirq, rc);
  384. return rc;
  385. }
  386. *state = !!(bits & BIT(irq_bit));
  387. return rc;
  388. }
  389. static struct irq_chip pm8821_irq_chip = {
  390. .name = "pm8821",
  391. .irq_mask_ack = pm8821_irq_mask_ack,
  392. .irq_unmask = pm8821_irq_unmask,
  393. .irq_get_irqchip_state = pm8821_irq_get_irqchip_state,
  394. .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
  395. };
  396. static const struct regmap_config ssbi_regmap_config = {
  397. .reg_bits = 16,
  398. .val_bits = 8,
  399. .max_register = 0x3ff,
  400. .fast_io = true,
  401. .reg_read = ssbi_reg_read,
  402. .reg_write = ssbi_reg_write
  403. };
  404. static const struct pm_irq_data pm8xxx_data = {
  405. .num_irqs = PM8XXX_NR_IRQS,
  406. .irq_chip = &pm8xxx_irq_chip,
  407. .irq_handler = pm8xxx_irq_handler,
  408. };
  409. static const struct pm_irq_data pm8821_data = {
  410. .num_irqs = PM8821_NR_IRQS,
  411. .irq_chip = &pm8821_irq_chip,
  412. .irq_handler = pm8821_irq_handler,
  413. };
  414. static const struct of_device_id pm8xxx_id_table[] = {
  415. { .compatible = "qcom,pm8018", .data = &pm8xxx_data},
  416. { .compatible = "qcom,pm8058", .data = &pm8xxx_data},
  417. { .compatible = "qcom,pm8821", .data = &pm8821_data},
  418. { .compatible = "qcom,pm8921", .data = &pm8xxx_data},
  419. { }
  420. };
  421. MODULE_DEVICE_TABLE(of, pm8xxx_id_table);
  422. static int pm8xxx_probe(struct platform_device *pdev)
  423. {
  424. const struct pm_irq_data *data;
  425. struct regmap *regmap;
  426. int irq, rc;
  427. unsigned int val;
  428. u32 rev;
  429. struct pm_irq_chip *chip;
  430. data = of_device_get_match_data(&pdev->dev);
  431. if (!data) {
  432. dev_err(&pdev->dev, "No matching driver data found\n");
  433. return -EINVAL;
  434. }
  435. irq = platform_get_irq(pdev, 0);
  436. if (irq < 0)
  437. return irq;
  438. regmap = devm_regmap_init(&pdev->dev, NULL, pdev->dev.parent,
  439. &ssbi_regmap_config);
  440. if (IS_ERR(regmap))
  441. return PTR_ERR(regmap);
  442. /* Read PMIC chip revision */
  443. rc = regmap_read(regmap, REG_HWREV, &val);
  444. if (rc) {
  445. pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);
  446. return rc;
  447. }
  448. pr_info("PMIC revision 1: %02X\n", val);
  449. rev = val;
  450. /* Read PMIC chip revision 2 */
  451. rc = regmap_read(regmap, REG_HWREV_2, &val);
  452. if (rc) {
  453. pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",
  454. REG_HWREV_2, rc);
  455. return rc;
  456. }
  457. pr_info("PMIC revision 2: %02X\n", val);
  458. rev |= val << BITS_PER_BYTE;
  459. chip = devm_kzalloc(&pdev->dev,
  460. struct_size(chip, config, data->num_irqs),
  461. GFP_KERNEL);
  462. if (!chip)
  463. return -ENOMEM;
  464. platform_set_drvdata(pdev, chip);
  465. chip->regmap = regmap;
  466. chip->num_blocks = DIV_ROUND_UP(data->num_irqs, 8);
  467. chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
  468. chip->pm_irq_data = data;
  469. spin_lock_init(&chip->pm_irq_lock);
  470. chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node,
  471. data->num_irqs,
  472. &pm8xxx_irq_domain_ops,
  473. chip);
  474. if (!chip->irqdomain)
  475. return -ENODEV;
  476. rc = devm_request_irq(&pdev->dev, irq, data->irq_handler, 0, dev_name(&pdev->dev), chip);
  477. if (rc)
  478. return rc;
  479. irq_set_irq_wake(irq, 1);
  480. rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
  481. if (rc)
  482. irq_domain_remove(chip->irqdomain);
  483. return rc;
  484. }
  485. static int pm8xxx_remove_child(struct device *dev, void *unused)
  486. {
  487. platform_device_unregister(to_platform_device(dev));
  488. return 0;
  489. }
  490. static int pm8xxx_remove(struct platform_device *pdev)
  491. {
  492. struct pm_irq_chip *chip = platform_get_drvdata(pdev);
  493. device_for_each_child(&pdev->dev, NULL, pm8xxx_remove_child);
  494. irq_domain_remove(chip->irqdomain);
  495. return 0;
  496. }
  497. static struct platform_driver pm8xxx_driver = {
  498. .probe = pm8xxx_probe,
  499. .remove = pm8xxx_remove,
  500. .driver = {
  501. .name = "pm8xxx-core",
  502. .of_match_table = pm8xxx_id_table,
  503. },
  504. };
  505. static int __init pm8xxx_init(void)
  506. {
  507. return platform_driver_register(&pm8xxx_driver);
  508. }
  509. subsys_initcall(pm8xxx_init);
  510. static void __exit pm8xxx_exit(void)
  511. {
  512. platform_driver_unregister(&pm8xxx_driver);
  513. }
  514. module_exit(pm8xxx_exit);
  515. MODULE_LICENSE("GPL v2");
  516. MODULE_DESCRIPTION("PMIC 8xxx core driver");
  517. MODULE_VERSION("1.0");
  518. MODULE_ALIAS("platform:pm8xxx-core");