1 /* 2 * MFD core driver for Intel Broxton Whiskey Cove PMIC 3 * 4 * Copyright (C) 2015 Intel Corporation. All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 */ 15 16 #include <linux/module.h> 17 #include <linux/acpi.h> 18 #include <linux/err.h> 19 #include <linux/delay.h> 20 #include <linux/interrupt.h> 21 #include <linux/kernel.h> 22 #include <linux/mfd/core.h> 23 #include <linux/mfd/intel_soc_pmic.h> 24 #include <linux/mfd/intel_soc_pmic_bxtwc.h> 25 #include <asm/intel_pmc_ipc.h> 26 27 /* PMIC device registers */ 28 #define REG_ADDR_MASK 0xFF00 29 #define REG_ADDR_SHIFT 8 30 #define REG_OFFSET_MASK 0xFF 31 32 /* Interrupt Status Registers */ 33 #define BXTWC_IRQLVL1 0x4E02 34 #define BXTWC_PWRBTNIRQ 0x4E03 35 36 #define BXTWC_THRM0IRQ 0x4E04 37 #define BXTWC_THRM1IRQ 0x4E05 38 #define BXTWC_THRM2IRQ 0x4E06 39 #define BXTWC_BCUIRQ 0x4E07 40 #define BXTWC_ADCIRQ 0x4E08 41 #define BXTWC_CHGR0IRQ 0x4E09 42 #define BXTWC_CHGR1IRQ 0x4E0A 43 #define BXTWC_GPIOIRQ0 0x4E0B 44 #define BXTWC_GPIOIRQ1 0x4E0C 45 #define BXTWC_CRITIRQ 0x4E0D 46 #define BXTWC_TMUIRQ 0x4FB6 47 48 /* Interrupt MASK Registers */ 49 #define BXTWC_MIRQLVL1 0x4E0E 50 #define BXTWC_MPWRTNIRQ 0x4E0F 51 52 #define BXTWC_MIRQLVL1_MCHGR BIT(5) 53 54 #define BXTWC_MTHRM0IRQ 0x4E12 55 #define BXTWC_MTHRM1IRQ 0x4E13 56 #define BXTWC_MTHRM2IRQ 0x4E14 57 #define BXTWC_MBCUIRQ 0x4E15 58 #define BXTWC_MADCIRQ 0x4E16 59 #define BXTWC_MCHGR0IRQ 0x4E17 60 #define BXTWC_MCHGR1IRQ 0x4E18 61 #define BXTWC_MGPIO0IRQ 0x4E19 62 #define BXTWC_MGPIO1IRQ 0x4E1A 63 #define BXTWC_MCRITIRQ 0x4E1B 64 #define BXTWC_MTMUIRQ 0x4FB7 65 66 /* Whiskey Cove PMIC share same ACPI ID between different platforms */ 67 #define BROXTON_PMIC_WC_HRV 4 68 69 /* Manage in two IRQ chips since mask registers are not consecutive */ 70 enum bxtwc_irqs { 71 /* Level 1 */ 72 BXTWC_PWRBTN_LVL1_IRQ = 0, 73 BXTWC_TMU_LVL1_IRQ, 74 BXTWC_THRM_LVL1_IRQ, 75 BXTWC_BCU_LVL1_IRQ, 76 BXTWC_ADC_LVL1_IRQ, 77 BXTWC_CHGR_LVL1_IRQ, 78 BXTWC_GPIO_LVL1_IRQ, 79 BXTWC_CRIT_LVL1_IRQ, 80 81 /* Level 2 */ 82 BXTWC_PWRBTN_IRQ, 83 }; 84 85 enum bxtwc_irqs_bcu { 86 BXTWC_BCU_IRQ = 0, 87 }; 88 89 enum bxtwc_irqs_adc { 90 BXTWC_ADC_IRQ = 0, 91 }; 92 93 enum bxtwc_irqs_chgr { 94 BXTWC_USBC_IRQ = 0, 95 BXTWC_CHGR0_IRQ, 96 BXTWC_CHGR1_IRQ, 97 }; 98 99 enum bxtwc_irqs_tmu { 100 BXTWC_TMU_IRQ = 0, 101 }; 102 103 enum bxtwc_irqs_crit { 104 BXTWC_CRIT_IRQ = 0, 105 }; 106 107 static const struct regmap_irq bxtwc_regmap_irqs[] = { 108 REGMAP_IRQ_REG(BXTWC_PWRBTN_LVL1_IRQ, 0, BIT(0)), 109 REGMAP_IRQ_REG(BXTWC_TMU_LVL1_IRQ, 0, BIT(1)), 110 REGMAP_IRQ_REG(BXTWC_THRM_LVL1_IRQ, 0, BIT(2)), 111 REGMAP_IRQ_REG(BXTWC_BCU_LVL1_IRQ, 0, BIT(3)), 112 REGMAP_IRQ_REG(BXTWC_ADC_LVL1_IRQ, 0, BIT(4)), 113 REGMAP_IRQ_REG(BXTWC_CHGR_LVL1_IRQ, 0, BIT(5)), 114 REGMAP_IRQ_REG(BXTWC_GPIO_LVL1_IRQ, 0, BIT(6)), 115 REGMAP_IRQ_REG(BXTWC_CRIT_LVL1_IRQ, 0, BIT(7)), 116 REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 1, 0x03), 117 }; 118 119 static const struct regmap_irq bxtwc_regmap_irqs_bcu[] = { 120 REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 0, 0x1f), 121 }; 122 123 static const struct regmap_irq bxtwc_regmap_irqs_adc[] = { 124 REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 0, 0xff), 125 }; 126 127 static const struct regmap_irq bxtwc_regmap_irqs_chgr[] = { 128 REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, BIT(5)), 129 REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 0, 0x1f), 130 REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 1, 0x1f), 131 }; 132 133 static const struct regmap_irq bxtwc_regmap_irqs_tmu[] = { 134 REGMAP_IRQ_REG(BXTWC_TMU_IRQ, 0, 0x06), 135 }; 136 137 static const struct regmap_irq bxtwc_regmap_irqs_crit[] = { 138 REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 0, 0x03), 139 }; 140 141 static struct regmap_irq_chip bxtwc_regmap_irq_chip = { 142 .name = "bxtwc_irq_chip", 143 .status_base = BXTWC_IRQLVL1, 144 .mask_base = BXTWC_MIRQLVL1, 145 .irqs = bxtwc_regmap_irqs, 146 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs), 147 .num_regs = 2, 148 }; 149 150 static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = { 151 .name = "bxtwc_irq_chip_tmu", 152 .status_base = BXTWC_TMUIRQ, 153 .mask_base = BXTWC_MTMUIRQ, 154 .irqs = bxtwc_regmap_irqs_tmu, 155 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_tmu), 156 .num_regs = 1, 157 }; 158 159 static struct regmap_irq_chip bxtwc_regmap_irq_chip_bcu = { 160 .name = "bxtwc_irq_chip_bcu", 161 .status_base = BXTWC_BCUIRQ, 162 .mask_base = BXTWC_MBCUIRQ, 163 .irqs = bxtwc_regmap_irqs_bcu, 164 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_bcu), 165 .num_regs = 1, 166 }; 167 168 static struct regmap_irq_chip bxtwc_regmap_irq_chip_adc = { 169 .name = "bxtwc_irq_chip_adc", 170 .status_base = BXTWC_ADCIRQ, 171 .mask_base = BXTWC_MADCIRQ, 172 .irqs = bxtwc_regmap_irqs_adc, 173 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_adc), 174 .num_regs = 1, 175 }; 176 177 static struct regmap_irq_chip bxtwc_regmap_irq_chip_chgr = { 178 .name = "bxtwc_irq_chip_chgr", 179 .status_base = BXTWC_CHGR0IRQ, 180 .mask_base = BXTWC_MCHGR0IRQ, 181 .irqs = bxtwc_regmap_irqs_chgr, 182 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_chgr), 183 .num_regs = 2, 184 }; 185 186 static struct regmap_irq_chip bxtwc_regmap_irq_chip_crit = { 187 .name = "bxtwc_irq_chip_crit", 188 .status_base = BXTWC_CRITIRQ, 189 .mask_base = BXTWC_MCRITIRQ, 190 .irqs = bxtwc_regmap_irqs_crit, 191 .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_crit), 192 .num_regs = 1, 193 }; 194 195 static struct resource gpio_resources[] = { 196 DEFINE_RES_IRQ_NAMED(BXTWC_GPIO_LVL1_IRQ, "GPIO"), 197 }; 198 199 static struct resource adc_resources[] = { 200 DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"), 201 }; 202 203 static struct resource usbc_resources[] = { 204 DEFINE_RES_IRQ(BXTWC_USBC_IRQ), 205 }; 206 207 static struct resource charger_resources[] = { 208 DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"), 209 DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"), 210 }; 211 212 static struct resource thermal_resources[] = { 213 DEFINE_RES_IRQ(BXTWC_THRM_LVL1_IRQ), 214 }; 215 216 static struct resource bcu_resources[] = { 217 DEFINE_RES_IRQ_NAMED(BXTWC_BCU_IRQ, "BCU"), 218 }; 219 220 static struct resource tmu_resources[] = { 221 DEFINE_RES_IRQ_NAMED(BXTWC_TMU_IRQ, "TMU"), 222 }; 223 224 static struct mfd_cell bxt_wc_dev[] = { 225 { 226 .name = "bxt_wcove_gpadc", 227 .num_resources = ARRAY_SIZE(adc_resources), 228 .resources = adc_resources, 229 }, 230 { 231 .name = "bxt_wcove_thermal", 232 .num_resources = ARRAY_SIZE(thermal_resources), 233 .resources = thermal_resources, 234 }, 235 { 236 .name = "bxt_wcove_usbc", 237 .num_resources = ARRAY_SIZE(usbc_resources), 238 .resources = usbc_resources, 239 }, 240 { 241 .name = "bxt_wcove_ext_charger", 242 .num_resources = ARRAY_SIZE(charger_resources), 243 .resources = charger_resources, 244 }, 245 { 246 .name = "bxt_wcove_bcu", 247 .num_resources = ARRAY_SIZE(bcu_resources), 248 .resources = bcu_resources, 249 }, 250 { 251 .name = "bxt_wcove_tmu", 252 .num_resources = ARRAY_SIZE(tmu_resources), 253 .resources = tmu_resources, 254 }, 255 256 { 257 .name = "bxt_wcove_gpio", 258 .num_resources = ARRAY_SIZE(gpio_resources), 259 .resources = gpio_resources, 260 }, 261 { 262 .name = "bxt_wcove_region", 263 }, 264 }; 265 266 static int regmap_ipc_byte_reg_read(void *context, unsigned int reg, 267 unsigned int *val) 268 { 269 int ret; 270 int i2c_addr; 271 u8 ipc_in[2]; 272 u8 ipc_out[4]; 273 struct intel_soc_pmic *pmic = context; 274 275 if (!pmic) 276 return -EINVAL; 277 278 if (reg & REG_ADDR_MASK) 279 i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT; 280 else 281 i2c_addr = BXTWC_DEVICE1_ADDR; 282 283 reg &= REG_OFFSET_MASK; 284 285 ipc_in[0] = reg; 286 ipc_in[1] = i2c_addr; 287 ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS, 288 PMC_IPC_PMIC_ACCESS_READ, 289 ipc_in, sizeof(ipc_in), (u32 *)ipc_out, 1); 290 if (ret) { 291 dev_err(pmic->dev, "Failed to read from PMIC\n"); 292 return ret; 293 } 294 *val = ipc_out[0]; 295 296 return 0; 297 } 298 299 static int regmap_ipc_byte_reg_write(void *context, unsigned int reg, 300 unsigned int val) 301 { 302 int ret; 303 int i2c_addr; 304 u8 ipc_in[3]; 305 struct intel_soc_pmic *pmic = context; 306 307 if (!pmic) 308 return -EINVAL; 309 310 if (reg & REG_ADDR_MASK) 311 i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT; 312 else 313 i2c_addr = BXTWC_DEVICE1_ADDR; 314 315 reg &= REG_OFFSET_MASK; 316 317 ipc_in[0] = reg; 318 ipc_in[1] = i2c_addr; 319 ipc_in[2] = val; 320 ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS, 321 PMC_IPC_PMIC_ACCESS_WRITE, 322 ipc_in, sizeof(ipc_in), NULL, 0); 323 if (ret) { 324 dev_err(pmic->dev, "Failed to write to PMIC\n"); 325 return ret; 326 } 327 328 return 0; 329 } 330 331 /* sysfs interfaces to r/w PMIC registers, required by initial script */ 332 static unsigned long bxtwc_reg_addr; 333 static ssize_t bxtwc_reg_show(struct device *dev, 334 struct device_attribute *attr, char *buf) 335 { 336 return sprintf(buf, "0x%lx\n", bxtwc_reg_addr); 337 } 338 339 static ssize_t bxtwc_reg_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 349 static ssize_t bxtwc_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 365 static ssize_t bxtwc_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 385 static DEVICE_ATTR(addr, S_IWUSR | S_IRUSR, bxtwc_reg_show, bxtwc_reg_store); 386 static DEVICE_ATTR(val, S_IWUSR | S_IRUSR, bxtwc_val_show, bxtwc_val_store); 387 static struct attribute *bxtwc_attrs[] = { 388 &dev_attr_addr.attr, 389 &dev_attr_val.attr, 390 NULL 391 }; 392 393 static const struct attribute_group bxtwc_group = { 394 .attrs = bxtwc_attrs, 395 }; 396 397 static 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 404 static 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 424 static 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 dev_err(&pdev->dev, "Invalid IRQ\n"); 451 return ret; 452 } 453 pmic->irq = ret; 454 455 dev_set_drvdata(&pdev->dev, pmic); 456 pmic->dev = &pdev->dev; 457 458 pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic, 459 &bxtwc_regmap_config); 460 if (IS_ERR(pmic->regmap)) { 461 ret = PTR_ERR(pmic->regmap); 462 dev_err(&pdev->dev, "Failed to initialise regmap: %d\n", ret); 463 return ret; 464 } 465 466 ret = devm_regmap_add_irq_chip(&pdev->dev, pmic->regmap, pmic->irq, 467 IRQF_ONESHOT | IRQF_SHARED, 468 0, &bxtwc_regmap_irq_chip, 469 &pmic->irq_chip_data); 470 if (ret) { 471 dev_err(&pdev->dev, "Failed to add IRQ chip\n"); 472 return ret; 473 } 474 475 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, 476 BXTWC_TMU_LVL1_IRQ, 477 IRQF_ONESHOT, 478 &bxtwc_regmap_irq_chip_tmu, 479 &pmic->irq_chip_data_tmu); 480 if (ret) { 481 dev_err(&pdev->dev, "Failed to add TMU IRQ chip\n"); 482 return ret; 483 } 484 485 /* Add chained IRQ handler for BCU IRQs */ 486 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, 487 BXTWC_BCU_LVL1_IRQ, 488 IRQF_ONESHOT, 489 &bxtwc_regmap_irq_chip_bcu, 490 &pmic->irq_chip_data_bcu); 491 492 493 if (ret) { 494 dev_err(&pdev->dev, "Failed to add BUC IRQ chip\n"); 495 return ret; 496 } 497 498 /* Add chained IRQ handler for ADC IRQs */ 499 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, 500 BXTWC_ADC_LVL1_IRQ, 501 IRQF_ONESHOT, 502 &bxtwc_regmap_irq_chip_adc, 503 &pmic->irq_chip_data_adc); 504 505 506 if (ret) { 507 dev_err(&pdev->dev, "Failed to add ADC IRQ chip\n"); 508 return ret; 509 } 510 511 /* Add chained IRQ handler for CHGR IRQs */ 512 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, 513 BXTWC_CHGR_LVL1_IRQ, 514 IRQF_ONESHOT, 515 &bxtwc_regmap_irq_chip_chgr, 516 &pmic->irq_chip_data_chgr); 517 518 519 if (ret) { 520 dev_err(&pdev->dev, "Failed to add CHGR IRQ chip\n"); 521 return ret; 522 } 523 524 /* Add chained IRQ handler for CRIT IRQs */ 525 ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, 526 BXTWC_CRIT_LVL1_IRQ, 527 IRQF_ONESHOT, 528 &bxtwc_regmap_irq_chip_crit, 529 &pmic->irq_chip_data_crit); 530 531 532 if (ret) { 533 dev_err(&pdev->dev, "Failed to add CRIT IRQ chip\n"); 534 return ret; 535 } 536 537 ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev, 538 ARRAY_SIZE(bxt_wc_dev), NULL, 0, NULL); 539 if (ret) { 540 dev_err(&pdev->dev, "Failed to add devices\n"); 541 return ret; 542 } 543 544 ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group); 545 if (ret) { 546 dev_err(&pdev->dev, "Failed to create sysfs group %d\n", ret); 547 return ret; 548 } 549 550 /* 551 * There is known hw bug. Upon reset BIT 5 of register 552 * BXTWC_CHGR_LVL1_IRQ is 0 which is the expected value. However, 553 * later it's set to 1(masked) automatically by hardware. So we 554 * have the software workaround here to unmaksed it in order to let 555 * charger interrutp work. 556 */ 557 regmap_update_bits(pmic->regmap, BXTWC_MIRQLVL1, 558 BXTWC_MIRQLVL1_MCHGR, 0); 559 560 return 0; 561 } 562 563 static int bxtwc_remove(struct platform_device *pdev) 564 { 565 sysfs_remove_group(&pdev->dev.kobj, &bxtwc_group); 566 567 return 0; 568 } 569 570 static void bxtwc_shutdown(struct platform_device *pdev) 571 { 572 struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev); 573 574 disable_irq(pmic->irq); 575 } 576 577 #ifdef CONFIG_PM_SLEEP 578 static int bxtwc_suspend(struct device *dev) 579 { 580 struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 581 582 disable_irq(pmic->irq); 583 584 return 0; 585 } 586 587 static int bxtwc_resume(struct device *dev) 588 { 589 struct intel_soc_pmic *pmic = dev_get_drvdata(dev); 590 591 enable_irq(pmic->irq); 592 return 0; 593 } 594 #endif 595 static SIMPLE_DEV_PM_OPS(bxtwc_pm_ops, bxtwc_suspend, bxtwc_resume); 596 597 static const struct acpi_device_id bxtwc_acpi_ids[] = { 598 { "INT34D3", }, 599 { } 600 }; 601 MODULE_DEVICE_TABLE(acpi, bxtwc_acpi_ids); 602 603 static struct platform_driver bxtwc_driver = { 604 .probe = bxtwc_probe, 605 .remove = bxtwc_remove, 606 .shutdown = bxtwc_shutdown, 607 .driver = { 608 .name = "BXTWC PMIC", 609 .pm = &bxtwc_pm_ops, 610 .acpi_match_table = ACPI_PTR(bxtwc_acpi_ids), 611 }, 612 }; 613 614 module_platform_driver(bxtwc_driver); 615 616 MODULE_LICENSE("GPL v2"); 617 MODULE_AUTHOR("Qipeng Zha<qipeng.zha@intel.com>"); 618