cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qcom-pm8xxx.c (15956B)


      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
     65struct pm_irq_data {
     66	int num_irqs;
     67	struct irq_chip *irq_chip;
     68	irq_handler_t irq_handler;
     69};
     70
     71struct 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
     82static 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);
     97bail:
     98	spin_unlock(&chip->pm_irq_lock);
     99	return rc;
    100}
    101
    102static int
    103pm8xxx_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);
    118bail:
    119	spin_unlock(&chip->pm_irq_lock);
    120	return rc;
    121}
    122
    123static 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
    148static 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
    172static 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
    195static 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
    220static 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
    230static 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
    263static 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
    275static 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
    287static 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
    317static 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));
    348bail:
    349	spin_unlock(&chip->pm_irq_lock);
    350
    351	return rc;
    352}
    353
    354static 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
    363static 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
    372static 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
    391static 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
    397static 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
    424static 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
    444static 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
    470static 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
    478static 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
    487static 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
    493static 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
    499static 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};
    506MODULE_DEVICE_TABLE(of, pm8xxx_id_table);
    507
    508static 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
    584static int pm8xxx_remove_child(struct device *dev, void *unused)
    585{
    586	platform_device_unregister(to_platform_device(dev));
    587	return 0;
    588}
    589
    590static 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
    600static 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
    609static int __init pm8xxx_init(void)
    610{
    611	return platform_driver_register(&pm8xxx_driver);
    612}
    613subsys_initcall(pm8xxx_init);
    614
    615static void __exit pm8xxx_exit(void)
    616{
    617	platform_driver_unregister(&pm8xxx_driver);
    618}
    619module_exit(pm8xxx_exit);
    620
    621MODULE_LICENSE("GPL v2");
    622MODULE_DESCRIPTION("PMIC 8xxx core driver");
    623MODULE_VERSION("1.0");
    624MODULE_ALIAS("platform:pm8xxx-core");