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

intel_soc_pmic_bxtwc.c (15129B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * MFD core driver for Intel Broxton Whiskey Cove PMIC
      4 *
      5 * Copyright (C) 2015 Intel Corporation. All rights reserved.
      6 */
      7
      8#include <linux/acpi.h>
      9#include <linux/delay.h>
     10#include <linux/err.h>
     11#include <linux/interrupt.h>
     12#include <linux/kernel.h>
     13#include <linux/mfd/core.h>
     14#include <linux/mfd/intel_soc_pmic.h>
     15#include <linux/mfd/intel_soc_pmic_bxtwc.h>
     16#include <linux/module.h>
     17
     18#include <asm/intel_scu_ipc.h>
     19
     20/* PMIC device registers */
     21#define REG_ADDR_MASK		0xFF00
     22#define REG_ADDR_SHIFT		8
     23#define REG_OFFSET_MASK		0xFF
     24
     25/* Interrupt Status Registers */
     26#define BXTWC_IRQLVL1		0x4E02
     27
     28#define BXTWC_PWRBTNIRQ		0x4E03
     29#define BXTWC_THRM0IRQ		0x4E04
     30#define BXTWC_THRM1IRQ		0x4E05
     31#define BXTWC_THRM2IRQ		0x4E06
     32#define BXTWC_BCUIRQ		0x4E07
     33#define BXTWC_ADCIRQ		0x4E08
     34#define BXTWC_CHGR0IRQ		0x4E09
     35#define BXTWC_CHGR1IRQ		0x4E0A
     36#define BXTWC_GPIOIRQ0		0x4E0B
     37#define BXTWC_GPIOIRQ1		0x4E0C
     38#define BXTWC_CRITIRQ		0x4E0D
     39#define BXTWC_TMUIRQ		0x4FB6
     40
     41/* Interrupt MASK Registers */
     42#define BXTWC_MIRQLVL1		0x4E0E
     43#define BXTWC_MIRQLVL1_MCHGR	BIT(5)
     44
     45#define BXTWC_MPWRBTNIRQ	0x4E0F
     46#define BXTWC_MTHRM0IRQ		0x4E12
     47#define BXTWC_MTHRM1IRQ		0x4E13
     48#define BXTWC_MTHRM2IRQ		0x4E14
     49#define BXTWC_MBCUIRQ		0x4E15
     50#define BXTWC_MADCIRQ		0x4E16
     51#define BXTWC_MCHGR0IRQ		0x4E17
     52#define BXTWC_MCHGR1IRQ		0x4E18
     53#define BXTWC_MGPIO0IRQ		0x4E19
     54#define BXTWC_MGPIO1IRQ		0x4E1A
     55#define BXTWC_MCRITIRQ		0x4E1B
     56#define BXTWC_MTMUIRQ		0x4FB7
     57
     58/* Whiskey Cove PMIC share same ACPI ID between different platforms */
     59#define BROXTON_PMIC_WC_HRV	4
     60
     61#define PMC_PMIC_ACCESS		0xFF
     62#define PMC_PMIC_READ		0x0
     63#define PMC_PMIC_WRITE		0x1
     64
     65enum bxtwc_irqs {
     66	BXTWC_PWRBTN_LVL1_IRQ = 0,
     67	BXTWC_TMU_LVL1_IRQ,
     68	BXTWC_THRM_LVL1_IRQ,
     69	BXTWC_BCU_LVL1_IRQ,
     70	BXTWC_ADC_LVL1_IRQ,
     71	BXTWC_CHGR_LVL1_IRQ,
     72	BXTWC_GPIO_LVL1_IRQ,
     73	BXTWC_CRIT_LVL1_IRQ,
     74};
     75
     76enum bxtwc_irqs_pwrbtn {
     77	BXTWC_PWRBTN_IRQ = 0,
     78	BXTWC_UIBTN_IRQ,
     79};
     80
     81enum bxtwc_irqs_bcu {
     82	BXTWC_BCU_IRQ = 0,
     83};
     84
     85enum bxtwc_irqs_adc {
     86	BXTWC_ADC_IRQ = 0,
     87};
     88
     89enum bxtwc_irqs_chgr {
     90	BXTWC_USBC_IRQ = 0,
     91	BXTWC_CHGR0_IRQ,
     92	BXTWC_CHGR1_IRQ,
     93};
     94
     95enum bxtwc_irqs_tmu {
     96	BXTWC_TMU_IRQ = 0,
     97};
     98
     99enum bxtwc_irqs_crit {
    100	BXTWC_CRIT_IRQ = 0,
    101};
    102
    103static const struct regmap_irq bxtwc_regmap_irqs[] = {
    104	REGMAP_IRQ_REG(BXTWC_PWRBTN_LVL1_IRQ, 0, BIT(0)),
    105	REGMAP_IRQ_REG(BXTWC_TMU_LVL1_IRQ, 0, BIT(1)),
    106	REGMAP_IRQ_REG(BXTWC_THRM_LVL1_IRQ, 0, BIT(2)),
    107	REGMAP_IRQ_REG(BXTWC_BCU_LVL1_IRQ, 0, BIT(3)),
    108	REGMAP_IRQ_REG(BXTWC_ADC_LVL1_IRQ, 0, BIT(4)),
    109	REGMAP_IRQ_REG(BXTWC_CHGR_LVL1_IRQ, 0, BIT(5)),
    110	REGMAP_IRQ_REG(BXTWC_GPIO_LVL1_IRQ, 0, BIT(6)),
    111	REGMAP_IRQ_REG(BXTWC_CRIT_LVL1_IRQ, 0, BIT(7)),
    112};
    113
    114static const struct regmap_irq bxtwc_regmap_irqs_pwrbtn[] = {
    115	REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 0, 0x01),
    116};
    117
    118static const struct regmap_irq bxtwc_regmap_irqs_bcu[] = {
    119	REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 0, 0x1f),
    120};
    121
    122static const struct regmap_irq bxtwc_regmap_irqs_adc[] = {
    123	REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 0, 0xff),
    124};
    125
    126static const struct regmap_irq bxtwc_regmap_irqs_chgr[] = {
    127	REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, 0x20),
    128	REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 0, 0x1f),
    129	REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 1, 0x1f),
    130};
    131
    132static const struct regmap_irq bxtwc_regmap_irqs_tmu[] = {
    133	REGMAP_IRQ_REG(BXTWC_TMU_IRQ, 0, 0x06),
    134};
    135
    136static const struct regmap_irq bxtwc_regmap_irqs_crit[] = {
    137	REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 0, 0x03),
    138};
    139
    140static struct regmap_irq_chip bxtwc_regmap_irq_chip = {
    141	.name = "bxtwc_irq_chip",
    142	.status_base = BXTWC_IRQLVL1,
    143	.mask_base = BXTWC_MIRQLVL1,
    144	.irqs = bxtwc_regmap_irqs,
    145	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs),
    146	.num_regs = 1,
    147};
    148
    149static struct regmap_irq_chip bxtwc_regmap_irq_chip_pwrbtn = {
    150	.name = "bxtwc_irq_chip_pwrbtn",
    151	.status_base = BXTWC_PWRBTNIRQ,
    152	.mask_base = BXTWC_MPWRBTNIRQ,
    153	.irqs = bxtwc_regmap_irqs_pwrbtn,
    154	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_pwrbtn),
    155	.num_regs = 1,
    156};
    157
    158static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = {
    159	.name = "bxtwc_irq_chip_tmu",
    160	.status_base = BXTWC_TMUIRQ,
    161	.mask_base = BXTWC_MTMUIRQ,
    162	.irqs = bxtwc_regmap_irqs_tmu,
    163	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_tmu),
    164	.num_regs = 1,
    165};
    166
    167static struct regmap_irq_chip bxtwc_regmap_irq_chip_bcu = {
    168	.name = "bxtwc_irq_chip_bcu",
    169	.status_base = BXTWC_BCUIRQ,
    170	.mask_base = BXTWC_MBCUIRQ,
    171	.irqs = bxtwc_regmap_irqs_bcu,
    172	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_bcu),
    173	.num_regs = 1,
    174};
    175
    176static struct regmap_irq_chip bxtwc_regmap_irq_chip_adc = {
    177	.name = "bxtwc_irq_chip_adc",
    178	.status_base = BXTWC_ADCIRQ,
    179	.mask_base = BXTWC_MADCIRQ,
    180	.irqs = bxtwc_regmap_irqs_adc,
    181	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_adc),
    182	.num_regs = 1,
    183};
    184
    185static struct regmap_irq_chip bxtwc_regmap_irq_chip_chgr = {
    186	.name = "bxtwc_irq_chip_chgr",
    187	.status_base = BXTWC_CHGR0IRQ,
    188	.mask_base = BXTWC_MCHGR0IRQ,
    189	.irqs = bxtwc_regmap_irqs_chgr,
    190	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_chgr),
    191	.num_regs = 2,
    192};
    193
    194static struct regmap_irq_chip bxtwc_regmap_irq_chip_crit = {
    195	.name = "bxtwc_irq_chip_crit",
    196	.status_base = BXTWC_CRITIRQ,
    197	.mask_base = BXTWC_MCRITIRQ,
    198	.irqs = bxtwc_regmap_irqs_crit,
    199	.num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_crit),
    200	.num_regs = 1,
    201};
    202
    203static const struct resource gpio_resources[] = {
    204	DEFINE_RES_IRQ_NAMED(BXTWC_GPIO_LVL1_IRQ, "GPIO"),
    205};
    206
    207static const struct resource adc_resources[] = {
    208	DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"),
    209};
    210
    211static const struct resource usbc_resources[] = {
    212	DEFINE_RES_IRQ(BXTWC_USBC_IRQ),
    213};
    214
    215static const struct resource charger_resources[] = {
    216	DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"),
    217	DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"),
    218};
    219
    220static const struct resource thermal_resources[] = {
    221	DEFINE_RES_IRQ(BXTWC_THRM_LVL1_IRQ),
    222};
    223
    224static const struct resource bcu_resources[] = {
    225	DEFINE_RES_IRQ_NAMED(BXTWC_BCU_IRQ, "BCU"),
    226};
    227
    228static const struct resource tmu_resources[] = {
    229	DEFINE_RES_IRQ_NAMED(BXTWC_TMU_IRQ, "TMU"),
    230};
    231
    232static struct mfd_cell bxt_wc_dev[] = {
    233	{
    234		.name = "bxt_wcove_gpadc",
    235		.num_resources = ARRAY_SIZE(adc_resources),
    236		.resources = adc_resources,
    237	},
    238	{
    239		.name = "bxt_wcove_thermal",
    240		.num_resources = ARRAY_SIZE(thermal_resources),
    241		.resources = thermal_resources,
    242	},
    243	{
    244		.name = "bxt_wcove_usbc",
    245		.num_resources = ARRAY_SIZE(usbc_resources),
    246		.resources = usbc_resources,
    247	},
    248	{
    249		.name = "bxt_wcove_ext_charger",
    250		.num_resources = ARRAY_SIZE(charger_resources),
    251		.resources = charger_resources,
    252	},
    253	{
    254		.name = "bxt_wcove_bcu",
    255		.num_resources = ARRAY_SIZE(bcu_resources),
    256		.resources = bcu_resources,
    257	},
    258	{
    259		.name = "bxt_wcove_tmu",
    260		.num_resources = ARRAY_SIZE(tmu_resources),
    261		.resources = tmu_resources,
    262	},
    263
    264	{
    265		.name = "bxt_wcove_gpio",
    266		.num_resources = ARRAY_SIZE(gpio_resources),
    267		.resources = gpio_resources,
    268	},
    269	{
    270		.name = "bxt_wcove_region",
    271	},
    272};
    273
    274static int regmap_ipc_byte_reg_read(void *context, unsigned int reg,
    275				    unsigned int *val)
    276{
    277	int ret;
    278	int i2c_addr;
    279	u8 ipc_in[2];
    280	u8 ipc_out[4];
    281	struct intel_soc_pmic *pmic = context;
    282
    283	if (!pmic)
    284		return -EINVAL;
    285
    286	if (reg & REG_ADDR_MASK)
    287		i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
    288	else
    289		i2c_addr = BXTWC_DEVICE1_ADDR;
    290
    291	reg &= REG_OFFSET_MASK;
    292
    293	ipc_in[0] = reg;
    294	ipc_in[1] = i2c_addr;
    295	ret = intel_scu_ipc_dev_command(pmic->scu, PMC_PMIC_ACCESS,
    296					PMC_PMIC_READ, ipc_in, sizeof(ipc_in),
    297					ipc_out, sizeof(ipc_out));
    298	if (ret)
    299		return ret;
    300
    301	*val = ipc_out[0];
    302
    303	return 0;
    304}
    305
    306static int regmap_ipc_byte_reg_write(void *context, unsigned int reg,
    307				       unsigned int val)
    308{
    309	int i2c_addr;
    310	u8 ipc_in[3];
    311	struct intel_soc_pmic *pmic = context;
    312
    313	if (!pmic)
    314		return -EINVAL;
    315
    316	if (reg & REG_ADDR_MASK)
    317		i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
    318	else
    319		i2c_addr = BXTWC_DEVICE1_ADDR;
    320
    321	reg &= REG_OFFSET_MASK;
    322
    323	ipc_in[0] = reg;
    324	ipc_in[1] = i2c_addr;
    325	ipc_in[2] = val;
    326	return intel_scu_ipc_dev_command(pmic->scu, PMC_PMIC_ACCESS,
    327					 PMC_PMIC_WRITE, ipc_in, sizeof(ipc_in),
    328					 NULL, 0);
    329}
    330
    331/* sysfs interfaces to r/w PMIC registers, required by initial script */
    332static unsigned long bxtwc_reg_addr;
    333static ssize_t addr_show(struct device *dev,
    334			 struct device_attribute *attr, char *buf)
    335{
    336	return sprintf(buf, "0x%lx\n", bxtwc_reg_addr);
    337}
    338
    339static ssize_t addr_store(struct device *dev,
    340			  struct device_attribute *attr, const char *buf, size_t count)
    341{
    342	if (kstrtoul(buf, 0, &bxtwc_reg_addr)) {
    343		dev_err(dev, "Invalid register address\n");
    344		return -EINVAL;
    345	}
    346	return (ssize_t)count;
    347}
    348
    349static ssize_t val_show(struct device *dev,
    350			struct device_attribute *attr, char *buf)
    351{
    352	int ret;
    353	unsigned int val;
    354	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
    355
    356	ret = regmap_read(pmic->regmap, bxtwc_reg_addr, &val);
    357	if (ret < 0) {
    358		dev_err(dev, "Failed to read 0x%lx\n", bxtwc_reg_addr);
    359		return -EIO;
    360	}
    361
    362	return sprintf(buf, "0x%02x\n", val);
    363}
    364
    365static ssize_t val_store(struct device *dev,
    366			 struct device_attribute *attr, const char *buf, size_t count)
    367{
    368	int ret;
    369	unsigned int val;
    370	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
    371
    372	ret = kstrtouint(buf, 0, &val);
    373	if (ret)
    374		return ret;
    375
    376	ret = regmap_write(pmic->regmap, bxtwc_reg_addr, val);
    377	if (ret) {
    378		dev_err(dev, "Failed to write value 0x%02x to address 0x%lx",
    379			val, bxtwc_reg_addr);
    380		return -EIO;
    381	}
    382	return count;
    383}
    384
    385static DEVICE_ATTR_ADMIN_RW(addr);
    386static DEVICE_ATTR_ADMIN_RW(val);
    387static struct attribute *bxtwc_attrs[] = {
    388	&dev_attr_addr.attr,
    389	&dev_attr_val.attr,
    390	NULL
    391};
    392
    393static const struct attribute_group bxtwc_group = {
    394	.attrs = bxtwc_attrs,
    395};
    396
    397static const struct regmap_config bxtwc_regmap_config = {
    398	.reg_bits = 16,
    399	.val_bits = 8,
    400	.reg_write = regmap_ipc_byte_reg_write,
    401	.reg_read = regmap_ipc_byte_reg_read,
    402};
    403
    404static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic,
    405				struct regmap_irq_chip_data *pdata,
    406				int pirq, int irq_flags,
    407				const struct regmap_irq_chip *chip,
    408				struct regmap_irq_chip_data **data)
    409{
    410	int irq;
    411
    412	irq = regmap_irq_get_virq(pdata, pirq);
    413	if (irq < 0) {
    414		dev_err(pmic->dev,
    415			"Failed to get parent vIRQ(%d) for chip %s, ret:%d\n",
    416			pirq, chip->name, irq);
    417		return irq;
    418	}
    419
    420	return devm_regmap_add_irq_chip(pmic->dev, pmic->regmap, irq, irq_flags,
    421					0, chip, data);
    422}
    423
    424static int bxtwc_probe(struct platform_device *pdev)
    425{
    426	int ret;
    427	acpi_handle handle;
    428	acpi_status status;
    429	unsigned long long hrv;
    430	struct intel_soc_pmic *pmic;
    431
    432	handle = ACPI_HANDLE(&pdev->dev);
    433	status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv);
    434	if (ACPI_FAILURE(status)) {
    435		dev_err(&pdev->dev, "Failed to get PMIC hardware revision\n");
    436		return -ENODEV;
    437	}
    438	if (hrv != BROXTON_PMIC_WC_HRV) {
    439		dev_err(&pdev->dev, "Invalid PMIC hardware revision: %llu\n",
    440			hrv);
    441		return -ENODEV;
    442	}
    443
    444	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
    445	if (!pmic)
    446		return -ENOMEM;
    447
    448	ret = platform_get_irq(pdev, 0);
    449	if (ret < 0)
    450		return ret;
    451	pmic->irq = ret;
    452
    453	dev_set_drvdata(&pdev->dev, pmic);
    454	pmic->dev = &pdev->dev;
    455
    456	pmic->scu = devm_intel_scu_ipc_dev_get(&pdev->dev);
    457	if (!pmic->scu)
    458		return -EPROBE_DEFER;
    459
    460	pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic,
    461					&bxtwc_regmap_config);
    462	if (IS_ERR(pmic->regmap)) {
    463		ret = PTR_ERR(pmic->regmap);
    464		dev_err(&pdev->dev, "Failed to initialise regmap: %d\n", ret);
    465		return ret;
    466	}
    467
    468	ret = devm_regmap_add_irq_chip(&pdev->dev, pmic->regmap, pmic->irq,
    469				       IRQF_ONESHOT | IRQF_SHARED,
    470				       0, &bxtwc_regmap_irq_chip,
    471				       &pmic->irq_chip_data);
    472	if (ret) {
    473		dev_err(&pdev->dev, "Failed to add IRQ chip\n");
    474		return ret;
    475	}
    476
    477	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
    478					 BXTWC_PWRBTN_LVL1_IRQ,
    479					 IRQF_ONESHOT,
    480					 &bxtwc_regmap_irq_chip_pwrbtn,
    481					 &pmic->irq_chip_data_pwrbtn);
    482	if (ret) {
    483		dev_err(&pdev->dev, "Failed to add PWRBTN IRQ chip\n");
    484		return ret;
    485	}
    486
    487	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
    488					 BXTWC_TMU_LVL1_IRQ,
    489					 IRQF_ONESHOT,
    490					 &bxtwc_regmap_irq_chip_tmu,
    491					 &pmic->irq_chip_data_tmu);
    492	if (ret) {
    493		dev_err(&pdev->dev, "Failed to add TMU IRQ chip\n");
    494		return ret;
    495	}
    496
    497	/* Add chained IRQ handler for BCU IRQs */
    498	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
    499					 BXTWC_BCU_LVL1_IRQ,
    500					 IRQF_ONESHOT,
    501					 &bxtwc_regmap_irq_chip_bcu,
    502					 &pmic->irq_chip_data_bcu);
    503
    504
    505	if (ret) {
    506		dev_err(&pdev->dev, "Failed to add BUC IRQ chip\n");
    507		return ret;
    508	}
    509
    510	/* Add chained IRQ handler for ADC IRQs */
    511	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
    512					 BXTWC_ADC_LVL1_IRQ,
    513					 IRQF_ONESHOT,
    514					 &bxtwc_regmap_irq_chip_adc,
    515					 &pmic->irq_chip_data_adc);
    516
    517
    518	if (ret) {
    519		dev_err(&pdev->dev, "Failed to add ADC IRQ chip\n");
    520		return ret;
    521	}
    522
    523	/* Add chained IRQ handler for CHGR IRQs */
    524	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
    525					 BXTWC_CHGR_LVL1_IRQ,
    526					 IRQF_ONESHOT,
    527					 &bxtwc_regmap_irq_chip_chgr,
    528					 &pmic->irq_chip_data_chgr);
    529
    530
    531	if (ret) {
    532		dev_err(&pdev->dev, "Failed to add CHGR IRQ chip\n");
    533		return ret;
    534	}
    535
    536	/* Add chained IRQ handler for CRIT IRQs */
    537	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
    538					 BXTWC_CRIT_LVL1_IRQ,
    539					 IRQF_ONESHOT,
    540					 &bxtwc_regmap_irq_chip_crit,
    541					 &pmic->irq_chip_data_crit);
    542
    543
    544	if (ret) {
    545		dev_err(&pdev->dev, "Failed to add CRIT IRQ chip\n");
    546		return ret;
    547	}
    548
    549	ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev,
    550				   ARRAY_SIZE(bxt_wc_dev), NULL, 0, NULL);
    551	if (ret) {
    552		dev_err(&pdev->dev, "Failed to add devices\n");
    553		return ret;
    554	}
    555
    556	ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group);
    557	if (ret) {
    558		dev_err(&pdev->dev, "Failed to create sysfs group %d\n", ret);
    559		return ret;
    560	}
    561
    562	/*
    563	 * There is known hw bug. Upon reset BIT 5 of register
    564	 * BXTWC_CHGR_LVL1_IRQ is 0 which is the expected value. However,
    565	 * later it's set to 1(masked) automatically by hardware. So we
    566	 * have the software workaround here to unmaksed it in order to let
    567	 * charger interrutp work.
    568	 */
    569	regmap_update_bits(pmic->regmap, BXTWC_MIRQLVL1,
    570				BXTWC_MIRQLVL1_MCHGR, 0);
    571
    572	return 0;
    573}
    574
    575static int bxtwc_remove(struct platform_device *pdev)
    576{
    577	sysfs_remove_group(&pdev->dev.kobj, &bxtwc_group);
    578
    579	return 0;
    580}
    581
    582static void bxtwc_shutdown(struct platform_device *pdev)
    583{
    584	struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev);
    585
    586	disable_irq(pmic->irq);
    587}
    588
    589#ifdef CONFIG_PM_SLEEP
    590static int bxtwc_suspend(struct device *dev)
    591{
    592	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
    593
    594	disable_irq(pmic->irq);
    595
    596	return 0;
    597}
    598
    599static int bxtwc_resume(struct device *dev)
    600{
    601	struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
    602
    603	enable_irq(pmic->irq);
    604	return 0;
    605}
    606#endif
    607static SIMPLE_DEV_PM_OPS(bxtwc_pm_ops, bxtwc_suspend, bxtwc_resume);
    608
    609static const struct acpi_device_id bxtwc_acpi_ids[] = {
    610	{ "INT34D3", },
    611	{ }
    612};
    613MODULE_DEVICE_TABLE(acpi, bxtwc_acpi_ids);
    614
    615static struct platform_driver bxtwc_driver = {
    616	.probe = bxtwc_probe,
    617	.remove	= bxtwc_remove,
    618	.shutdown = bxtwc_shutdown,
    619	.driver	= {
    620		.name	= "BXTWC PMIC",
    621		.pm     = &bxtwc_pm_ops,
    622		.acpi_match_table = ACPI_PTR(bxtwc_acpi_ids),
    623	},
    624};
    625
    626module_platform_driver(bxtwc_driver);
    627
    628MODULE_LICENSE("GPL v2");
    629MODULE_AUTHOR("Qipeng Zha<qipeng.zha@intel.com>");