Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * MFD core driver for Intel Broxton Whiskey Cove PMIC
0004  *
0005  * Copyright (C) 2015-2017, 2022 Intel Corporation. All rights reserved.
0006  */
0007 
0008 #include <linux/acpi.h>
0009 #include <linux/bits.h>
0010 #include <linux/delay.h>
0011 #include <linux/err.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/kernel.h>
0014 #include <linux/mfd/core.h>
0015 #include <linux/mfd/intel_soc_pmic.h>
0016 #include <linux/mfd/intel_soc_pmic_bxtwc.h>
0017 #include <linux/module.h>
0018 
0019 #include <asm/intel_scu_ipc.h>
0020 
0021 /* PMIC device registers */
0022 #define REG_ADDR_MASK       GENMASK(15, 8)
0023 #define REG_ADDR_SHIFT      8
0024 #define REG_OFFSET_MASK     GENMASK(7, 0)
0025 
0026 /* Interrupt Status Registers */
0027 #define BXTWC_IRQLVL1       0x4E02
0028 
0029 #define BXTWC_PWRBTNIRQ     0x4E03
0030 #define BXTWC_THRM0IRQ      0x4E04
0031 #define BXTWC_THRM1IRQ      0x4E05
0032 #define BXTWC_THRM2IRQ      0x4E06
0033 #define BXTWC_BCUIRQ        0x4E07
0034 #define BXTWC_ADCIRQ        0x4E08
0035 #define BXTWC_CHGR0IRQ      0x4E09
0036 #define BXTWC_CHGR1IRQ      0x4E0A
0037 #define BXTWC_GPIOIRQ0      0x4E0B
0038 #define BXTWC_GPIOIRQ1      0x4E0C
0039 #define BXTWC_CRITIRQ       0x4E0D
0040 #define BXTWC_TMUIRQ        0x4FB6
0041 
0042 /* Interrupt MASK Registers */
0043 #define BXTWC_MIRQLVL1      0x4E0E
0044 #define BXTWC_MIRQLVL1_MCHGR    BIT(5)
0045 
0046 #define BXTWC_MPWRBTNIRQ    0x4E0F
0047 #define BXTWC_MTHRM0IRQ     0x4E12
0048 #define BXTWC_MTHRM1IRQ     0x4E13
0049 #define BXTWC_MTHRM2IRQ     0x4E14
0050 #define BXTWC_MBCUIRQ       0x4E15
0051 #define BXTWC_MADCIRQ       0x4E16
0052 #define BXTWC_MCHGR0IRQ     0x4E17
0053 #define BXTWC_MCHGR1IRQ     0x4E18
0054 #define BXTWC_MGPIO0IRQ     0x4E19
0055 #define BXTWC_MGPIO1IRQ     0x4E1A
0056 #define BXTWC_MCRITIRQ      0x4E1B
0057 #define BXTWC_MTMUIRQ       0x4FB7
0058 
0059 /* Whiskey Cove PMIC share same ACPI ID between different platforms */
0060 #define BROXTON_PMIC_WC_HRV 4
0061 
0062 #define PMC_PMIC_ACCESS     0xFF
0063 #define PMC_PMIC_READ       0x0
0064 #define PMC_PMIC_WRITE      0x1
0065 
0066 enum bxtwc_irqs {
0067     BXTWC_PWRBTN_LVL1_IRQ = 0,
0068     BXTWC_TMU_LVL1_IRQ,
0069     BXTWC_THRM_LVL1_IRQ,
0070     BXTWC_BCU_LVL1_IRQ,
0071     BXTWC_ADC_LVL1_IRQ,
0072     BXTWC_CHGR_LVL1_IRQ,
0073     BXTWC_GPIO_LVL1_IRQ,
0074     BXTWC_CRIT_LVL1_IRQ,
0075 };
0076 
0077 enum bxtwc_irqs_pwrbtn {
0078     BXTWC_PWRBTN_IRQ = 0,
0079     BXTWC_UIBTN_IRQ,
0080 };
0081 
0082 enum bxtwc_irqs_bcu {
0083     BXTWC_BCU_IRQ = 0,
0084 };
0085 
0086 enum bxtwc_irqs_adc {
0087     BXTWC_ADC_IRQ = 0,
0088 };
0089 
0090 enum bxtwc_irqs_chgr {
0091     BXTWC_USBC_IRQ = 0,
0092     BXTWC_CHGR0_IRQ,
0093     BXTWC_CHGR1_IRQ,
0094 };
0095 
0096 enum bxtwc_irqs_tmu {
0097     BXTWC_TMU_IRQ = 0,
0098 };
0099 
0100 enum bxtwc_irqs_crit {
0101     BXTWC_CRIT_IRQ = 0,
0102 };
0103 
0104 static const struct regmap_irq bxtwc_regmap_irqs[] = {
0105     REGMAP_IRQ_REG(BXTWC_PWRBTN_LVL1_IRQ, 0, BIT(0)),
0106     REGMAP_IRQ_REG(BXTWC_TMU_LVL1_IRQ, 0, BIT(1)),
0107     REGMAP_IRQ_REG(BXTWC_THRM_LVL1_IRQ, 0, BIT(2)),
0108     REGMAP_IRQ_REG(BXTWC_BCU_LVL1_IRQ, 0, BIT(3)),
0109     REGMAP_IRQ_REG(BXTWC_ADC_LVL1_IRQ, 0, BIT(4)),
0110     REGMAP_IRQ_REG(BXTWC_CHGR_LVL1_IRQ, 0, BIT(5)),
0111     REGMAP_IRQ_REG(BXTWC_GPIO_LVL1_IRQ, 0, BIT(6)),
0112     REGMAP_IRQ_REG(BXTWC_CRIT_LVL1_IRQ, 0, BIT(7)),
0113 };
0114 
0115 static const struct regmap_irq bxtwc_regmap_irqs_pwrbtn[] = {
0116     REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 0, BIT(0)),
0117 };
0118 
0119 static const struct regmap_irq bxtwc_regmap_irqs_bcu[] = {
0120     REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 0, GENMASK(4, 0)),
0121 };
0122 
0123 static const struct regmap_irq bxtwc_regmap_irqs_adc[] = {
0124     REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 0, GENMASK(7, 0)),
0125 };
0126 
0127 static const struct regmap_irq bxtwc_regmap_irqs_chgr[] = {
0128     REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, BIT(5)),
0129     REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 0, GENMASK(4, 0)),
0130     REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 1, GENMASK(4, 0)),
0131 };
0132 
0133 static const struct regmap_irq bxtwc_regmap_irqs_tmu[] = {
0134     REGMAP_IRQ_REG(BXTWC_TMU_IRQ, 0, GENMASK(2, 1)),
0135 };
0136 
0137 static const struct regmap_irq bxtwc_regmap_irqs_crit[] = {
0138     REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 0, GENMASK(1, 0)),
0139 };
0140 
0141 static struct regmap_irq_chip bxtwc_regmap_irq_chip = {
0142     .name = "bxtwc_irq_chip",
0143     .status_base = BXTWC_IRQLVL1,
0144     .mask_base = BXTWC_MIRQLVL1,
0145     .irqs = bxtwc_regmap_irqs,
0146     .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs),
0147     .num_regs = 1,
0148 };
0149 
0150 static struct regmap_irq_chip bxtwc_regmap_irq_chip_pwrbtn = {
0151     .name = "bxtwc_irq_chip_pwrbtn",
0152     .status_base = BXTWC_PWRBTNIRQ,
0153     .mask_base = BXTWC_MPWRBTNIRQ,
0154     .irqs = bxtwc_regmap_irqs_pwrbtn,
0155     .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_pwrbtn),
0156     .num_regs = 1,
0157 };
0158 
0159 static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = {
0160     .name = "bxtwc_irq_chip_tmu",
0161     .status_base = BXTWC_TMUIRQ,
0162     .mask_base = BXTWC_MTMUIRQ,
0163     .irqs = bxtwc_regmap_irqs_tmu,
0164     .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_tmu),
0165     .num_regs = 1,
0166 };
0167 
0168 static struct regmap_irq_chip bxtwc_regmap_irq_chip_bcu = {
0169     .name = "bxtwc_irq_chip_bcu",
0170     .status_base = BXTWC_BCUIRQ,
0171     .mask_base = BXTWC_MBCUIRQ,
0172     .irqs = bxtwc_regmap_irqs_bcu,
0173     .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_bcu),
0174     .num_regs = 1,
0175 };
0176 
0177 static struct regmap_irq_chip bxtwc_regmap_irq_chip_adc = {
0178     .name = "bxtwc_irq_chip_adc",
0179     .status_base = BXTWC_ADCIRQ,
0180     .mask_base = BXTWC_MADCIRQ,
0181     .irqs = bxtwc_regmap_irqs_adc,
0182     .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_adc),
0183     .num_regs = 1,
0184 };
0185 
0186 static struct regmap_irq_chip bxtwc_regmap_irq_chip_chgr = {
0187     .name = "bxtwc_irq_chip_chgr",
0188     .status_base = BXTWC_CHGR0IRQ,
0189     .mask_base = BXTWC_MCHGR0IRQ,
0190     .irqs = bxtwc_regmap_irqs_chgr,
0191     .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_chgr),
0192     .num_regs = 2,
0193 };
0194 
0195 static struct regmap_irq_chip bxtwc_regmap_irq_chip_crit = {
0196     .name = "bxtwc_irq_chip_crit",
0197     .status_base = BXTWC_CRITIRQ,
0198     .mask_base = BXTWC_MCRITIRQ,
0199     .irqs = bxtwc_regmap_irqs_crit,
0200     .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_crit),
0201     .num_regs = 1,
0202 };
0203 
0204 static const struct resource gpio_resources[] = {
0205     DEFINE_RES_IRQ_NAMED(BXTWC_GPIO_LVL1_IRQ, "GPIO"),
0206 };
0207 
0208 static const struct resource adc_resources[] = {
0209     DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"),
0210 };
0211 
0212 static const struct resource usbc_resources[] = {
0213     DEFINE_RES_IRQ(BXTWC_USBC_IRQ),
0214 };
0215 
0216 static const struct resource charger_resources[] = {
0217     DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"),
0218     DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"),
0219 };
0220 
0221 static const struct resource thermal_resources[] = {
0222     DEFINE_RES_IRQ(BXTWC_THRM_LVL1_IRQ),
0223 };
0224 
0225 static const struct resource bcu_resources[] = {
0226     DEFINE_RES_IRQ_NAMED(BXTWC_BCU_IRQ, "BCU"),
0227 };
0228 
0229 static const struct resource tmu_resources[] = {
0230     DEFINE_RES_IRQ_NAMED(BXTWC_TMU_IRQ, "TMU"),
0231 };
0232 
0233 static struct mfd_cell bxt_wc_dev[] = {
0234     {
0235         .name = "bxt_wcove_gpadc",
0236         .num_resources = ARRAY_SIZE(adc_resources),
0237         .resources = adc_resources,
0238     },
0239     {
0240         .name = "bxt_wcove_thermal",
0241         .num_resources = ARRAY_SIZE(thermal_resources),
0242         .resources = thermal_resources,
0243     },
0244     {
0245         .name = "bxt_wcove_usbc",
0246         .num_resources = ARRAY_SIZE(usbc_resources),
0247         .resources = usbc_resources,
0248     },
0249     {
0250         .name = "bxt_wcove_ext_charger",
0251         .num_resources = ARRAY_SIZE(charger_resources),
0252         .resources = charger_resources,
0253     },
0254     {
0255         .name = "bxt_wcove_bcu",
0256         .num_resources = ARRAY_SIZE(bcu_resources),
0257         .resources = bcu_resources,
0258     },
0259     {
0260         .name = "bxt_wcove_tmu",
0261         .num_resources = ARRAY_SIZE(tmu_resources),
0262         .resources = tmu_resources,
0263     },
0264 
0265     {
0266         .name = "bxt_wcove_gpio",
0267         .num_resources = ARRAY_SIZE(gpio_resources),
0268         .resources = gpio_resources,
0269     },
0270     {
0271         .name = "bxt_wcove_region",
0272     },
0273 };
0274 
0275 static int regmap_ipc_byte_reg_read(void *context, unsigned int reg,
0276                     unsigned int *val)
0277 {
0278     int ret;
0279     int i2c_addr;
0280     u8 ipc_in[2];
0281     u8 ipc_out[4];
0282     struct intel_soc_pmic *pmic = context;
0283 
0284     if (!pmic)
0285         return -EINVAL;
0286 
0287     if (reg & REG_ADDR_MASK)
0288         i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
0289     else
0290         i2c_addr = BXTWC_DEVICE1_ADDR;
0291 
0292     reg &= REG_OFFSET_MASK;
0293 
0294     ipc_in[0] = reg;
0295     ipc_in[1] = i2c_addr;
0296     ret = intel_scu_ipc_dev_command(pmic->scu, PMC_PMIC_ACCESS,
0297                     PMC_PMIC_READ, ipc_in, sizeof(ipc_in),
0298                     ipc_out, sizeof(ipc_out));
0299     if (ret)
0300         return ret;
0301 
0302     *val = ipc_out[0];
0303 
0304     return 0;
0305 }
0306 
0307 static int regmap_ipc_byte_reg_write(void *context, unsigned int reg,
0308                        unsigned int val)
0309 {
0310     int i2c_addr;
0311     u8 ipc_in[3];
0312     struct intel_soc_pmic *pmic = context;
0313 
0314     if (!pmic)
0315         return -EINVAL;
0316 
0317     if (reg & REG_ADDR_MASK)
0318         i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT;
0319     else
0320         i2c_addr = BXTWC_DEVICE1_ADDR;
0321 
0322     reg &= REG_OFFSET_MASK;
0323 
0324     ipc_in[0] = reg;
0325     ipc_in[1] = i2c_addr;
0326     ipc_in[2] = val;
0327     return intel_scu_ipc_dev_command(pmic->scu, PMC_PMIC_ACCESS,
0328                      PMC_PMIC_WRITE, ipc_in, sizeof(ipc_in),
0329                      NULL, 0);
0330 }
0331 
0332 /* sysfs interfaces to r/w PMIC registers, required by initial script */
0333 static unsigned long bxtwc_reg_addr;
0334 static ssize_t addr_show(struct device *dev,
0335              struct device_attribute *attr, char *buf)
0336 {
0337     return sysfs_emit(buf, "0x%lx\n", bxtwc_reg_addr);
0338 }
0339 
0340 static ssize_t addr_store(struct device *dev,
0341               struct device_attribute *attr, const char *buf, size_t count)
0342 {
0343     int ret;
0344 
0345     ret = kstrtoul(buf, 0, &bxtwc_reg_addr);
0346     if (ret)
0347         return ret;
0348 
0349     return count;
0350 }
0351 
0352 static ssize_t val_show(struct device *dev,
0353             struct device_attribute *attr, char *buf)
0354 {
0355     int ret;
0356     unsigned int val;
0357     struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
0358 
0359     ret = regmap_read(pmic->regmap, bxtwc_reg_addr, &val);
0360     if (ret) {
0361         dev_err(dev, "Failed to read 0x%lx\n", bxtwc_reg_addr);
0362         return ret;
0363     }
0364 
0365     return sysfs_emit(buf, "0x%02x\n", val);
0366 }
0367 
0368 static ssize_t val_store(struct device *dev,
0369              struct device_attribute *attr, const char *buf, size_t count)
0370 {
0371     int ret;
0372     unsigned int val;
0373     struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
0374 
0375     ret = kstrtouint(buf, 0, &val);
0376     if (ret)
0377         return ret;
0378 
0379     ret = regmap_write(pmic->regmap, bxtwc_reg_addr, val);
0380     if (ret) {
0381         dev_err(dev, "Failed to write value 0x%02x to address 0x%lx",
0382             val, bxtwc_reg_addr);
0383         return ret;
0384     }
0385     return count;
0386 }
0387 
0388 static DEVICE_ATTR_ADMIN_RW(addr);
0389 static DEVICE_ATTR_ADMIN_RW(val);
0390 static struct attribute *bxtwc_attrs[] = {
0391     &dev_attr_addr.attr,
0392     &dev_attr_val.attr,
0393     NULL
0394 };
0395 
0396 static const struct attribute_group bxtwc_group = {
0397     .attrs = bxtwc_attrs,
0398 };
0399 
0400 static const struct attribute_group *bxtwc_groups[] = {
0401     &bxtwc_group,
0402     NULL
0403 };
0404 
0405 static const struct regmap_config bxtwc_regmap_config = {
0406     .reg_bits = 16,
0407     .val_bits = 8,
0408     .reg_write = regmap_ipc_byte_reg_write,
0409     .reg_read = regmap_ipc_byte_reg_read,
0410 };
0411 
0412 static int bxtwc_add_chained_irq_chip(struct intel_soc_pmic *pmic,
0413                 struct regmap_irq_chip_data *pdata,
0414                 int pirq, int irq_flags,
0415                 const struct regmap_irq_chip *chip,
0416                 struct regmap_irq_chip_data **data)
0417 {
0418     int irq;
0419 
0420     irq = regmap_irq_get_virq(pdata, pirq);
0421     if (irq < 0)
0422         return dev_err_probe(pmic->dev, irq, "Failed to get parent vIRQ(%d) for chip %s\n",
0423                      pirq, chip->name);
0424 
0425     return devm_regmap_add_irq_chip(pmic->dev, pmic->regmap, irq, irq_flags,
0426                     0, chip, data);
0427 }
0428 
0429 static int bxtwc_probe(struct platform_device *pdev)
0430 {
0431     struct device *dev = &pdev->dev;
0432     int ret;
0433     acpi_status status;
0434     unsigned long long hrv;
0435     struct intel_soc_pmic *pmic;
0436 
0437     status = acpi_evaluate_integer(ACPI_HANDLE(dev), "_HRV", NULL, &hrv);
0438     if (ACPI_FAILURE(status))
0439         return dev_err_probe(dev, -ENODEV, "Failed to get PMIC hardware revision\n");
0440     if (hrv != BROXTON_PMIC_WC_HRV)
0441         return dev_err_probe(dev, -ENODEV, "Invalid PMIC hardware revision: %llu\n", hrv);
0442 
0443     pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
0444     if (!pmic)
0445         return -ENOMEM;
0446 
0447     ret = platform_get_irq(pdev, 0);
0448     if (ret < 0)
0449         return ret;
0450     pmic->irq = ret;
0451 
0452     platform_set_drvdata(pdev, pmic);
0453     pmic->dev = dev;
0454 
0455     pmic->scu = devm_intel_scu_ipc_dev_get(dev);
0456     if (!pmic->scu)
0457         return -EPROBE_DEFER;
0458 
0459     pmic->regmap = devm_regmap_init(dev, NULL, pmic, &bxtwc_regmap_config);
0460     if (IS_ERR(pmic->regmap))
0461         return dev_err_probe(dev, PTR_ERR(pmic->regmap), "Failed to initialise regmap\n");
0462 
0463     ret = devm_regmap_add_irq_chip(dev, pmic->regmap, pmic->irq,
0464                        IRQF_ONESHOT | IRQF_SHARED,
0465                        0, &bxtwc_regmap_irq_chip,
0466                        &pmic->irq_chip_data);
0467     if (ret)
0468         return dev_err_probe(dev, ret, "Failed to add IRQ chip\n");
0469 
0470     ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
0471                      BXTWC_PWRBTN_LVL1_IRQ,
0472                      IRQF_ONESHOT,
0473                      &bxtwc_regmap_irq_chip_pwrbtn,
0474                      &pmic->irq_chip_data_pwrbtn);
0475     if (ret)
0476         return dev_err_probe(dev, ret, "Failed to add PWRBTN IRQ chip\n");
0477 
0478     ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
0479                      BXTWC_TMU_LVL1_IRQ,
0480                      IRQF_ONESHOT,
0481                      &bxtwc_regmap_irq_chip_tmu,
0482                      &pmic->irq_chip_data_tmu);
0483     if (ret)
0484         return dev_err_probe(dev, ret, "Failed to add TMU IRQ chip\n");
0485 
0486     /* Add chained IRQ handler for BCU IRQs */
0487     ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
0488                      BXTWC_BCU_LVL1_IRQ,
0489                      IRQF_ONESHOT,
0490                      &bxtwc_regmap_irq_chip_bcu,
0491                      &pmic->irq_chip_data_bcu);
0492     if (ret)
0493         return dev_err_probe(dev, ret, "Failed to add BUC IRQ chip\n");
0494 
0495     /* Add chained IRQ handler for ADC IRQs */
0496     ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
0497                      BXTWC_ADC_LVL1_IRQ,
0498                      IRQF_ONESHOT,
0499                      &bxtwc_regmap_irq_chip_adc,
0500                      &pmic->irq_chip_data_adc);
0501     if (ret)
0502         return dev_err_probe(dev, ret, "Failed to add ADC IRQ chip\n");
0503 
0504     /* Add chained IRQ handler for CHGR IRQs */
0505     ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
0506                      BXTWC_CHGR_LVL1_IRQ,
0507                      IRQF_ONESHOT,
0508                      &bxtwc_regmap_irq_chip_chgr,
0509                      &pmic->irq_chip_data_chgr);
0510     if (ret)
0511         return dev_err_probe(dev, ret, "Failed to add CHGR IRQ chip\n");
0512 
0513     /* Add chained IRQ handler for CRIT IRQs */
0514     ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
0515                      BXTWC_CRIT_LVL1_IRQ,
0516                      IRQF_ONESHOT,
0517                      &bxtwc_regmap_irq_chip_crit,
0518                      &pmic->irq_chip_data_crit);
0519     if (ret)
0520         return dev_err_probe(dev, ret, "Failed to add CRIT IRQ chip\n");
0521 
0522     ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, bxt_wc_dev, ARRAY_SIZE(bxt_wc_dev),
0523                    NULL, 0, NULL);
0524     if (ret)
0525         return dev_err_probe(dev, ret, "Failed to add devices\n");
0526 
0527     /*
0528      * There is a known H/W bug. Upon reset, BIT 5 of register
0529      * BXTWC_CHGR_LVL1_IRQ is 0 which is the expected value. However,
0530      * later it's set to 1(masked) automatically by hardware. So we
0531      * place the software workaround here to unmask it again in order
0532      * to re-enable the charger interrupt.
0533      */
0534     regmap_update_bits(pmic->regmap, BXTWC_MIRQLVL1, BXTWC_MIRQLVL1_MCHGR, 0);
0535 
0536     return 0;
0537 }
0538 
0539 static void bxtwc_shutdown(struct platform_device *pdev)
0540 {
0541     struct intel_soc_pmic *pmic = platform_get_drvdata(pdev);
0542 
0543     disable_irq(pmic->irq);
0544 }
0545 
0546 static int bxtwc_suspend(struct device *dev)
0547 {
0548     struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
0549 
0550     disable_irq(pmic->irq);
0551 
0552     return 0;
0553 }
0554 
0555 static int bxtwc_resume(struct device *dev)
0556 {
0557     struct intel_soc_pmic *pmic = dev_get_drvdata(dev);
0558 
0559     enable_irq(pmic->irq);
0560     return 0;
0561 }
0562 
0563 static DEFINE_SIMPLE_DEV_PM_OPS(bxtwc_pm_ops, bxtwc_suspend, bxtwc_resume);
0564 
0565 static const struct acpi_device_id bxtwc_acpi_ids[] = {
0566     { "INT34D3", },
0567     { }
0568 };
0569 MODULE_DEVICE_TABLE(acpi, bxtwc_acpi_ids);
0570 
0571 static struct platform_driver bxtwc_driver = {
0572     .probe = bxtwc_probe,
0573     .shutdown = bxtwc_shutdown,
0574     .driver = {
0575         .name   = "BXTWC PMIC",
0576         .pm     = pm_sleep_ptr(&bxtwc_pm_ops),
0577         .acpi_match_table = bxtwc_acpi_ids,
0578         .dev_groups = bxtwc_groups,
0579     },
0580 };
0581 
0582 module_platform_driver(bxtwc_driver);
0583 
0584 MODULE_LICENSE("GPL v2");
0585 MODULE_AUTHOR("Qipeng Zha <qipeng.zha@intel.com>");