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