linux/drivers/mfd/intel_soc_pmic_bxtwc.c
<<
>>
Prefs
   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>");
 630