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