Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.15-rc1 1007 lines 24 kB view raw
1/* 2 * intel_pmc_ipc.c: Driver for the Intel PMC IPC mechanism 3 * 4 * (C) Copyright 2014-2015 Intel Corporation 5 * 6 * This driver is based on Intel SCU IPC driver(intel_scu_opc.c) by 7 * Sreedhara DS <sreedhara.ds@intel.com> 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * as published by the Free Software Foundation; version 2 12 * of the License. 13 * 14 * PMC running in ARC processor communicates with other entity running in IA 15 * core through IPC mechanism which in turn messaging between IA core ad PMC. 16 */ 17 18#include <linux/module.h> 19#include <linux/delay.h> 20#include <linux/errno.h> 21#include <linux/init.h> 22#include <linux/device.h> 23#include <linux/pm.h> 24#include <linux/pci.h> 25#include <linux/platform_device.h> 26#include <linux/interrupt.h> 27#include <linux/pm_qos.h> 28#include <linux/kernel.h> 29#include <linux/bitops.h> 30#include <linux/sched.h> 31#include <linux/atomic.h> 32#include <linux/notifier.h> 33#include <linux/suspend.h> 34#include <linux/acpi.h> 35#include <linux/io-64-nonatomic-lo-hi.h> 36#include <linux/spinlock.h> 37 38#include <asm/intel_pmc_ipc.h> 39 40#include <linux/platform_data/itco_wdt.h> 41 42/* 43 * IPC registers 44 * The IA write to IPC_CMD command register triggers an interrupt to the ARC, 45 * The ARC handles the interrupt and services it, writing optional data to 46 * the IPC1 registers, updates the IPC_STS response register with the status. 47 */ 48#define IPC_CMD 0x0 49#define IPC_CMD_MSI 0x100 50#define IPC_CMD_SIZE 16 51#define IPC_CMD_SUBCMD 12 52#define IPC_STATUS 0x04 53#define IPC_STATUS_IRQ 0x4 54#define IPC_STATUS_ERR 0x2 55#define IPC_STATUS_BUSY 0x1 56#define IPC_SPTR 0x08 57#define IPC_DPTR 0x0C 58#define IPC_WRITE_BUFFER 0x80 59#define IPC_READ_BUFFER 0x90 60 61/* Residency with clock rate at 19.2MHz to usecs */ 62#define S0IX_RESIDENCY_IN_USECS(d, s) \ 63({ \ 64 u64 result = 10ull * ((d) + (s)); \ 65 do_div(result, 192); \ 66 result; \ 67}) 68 69/* 70 * 16-byte buffer for sending data associated with IPC command. 71 */ 72#define IPC_DATA_BUFFER_SIZE 16 73 74#define IPC_LOOP_CNT 3000000 75#define IPC_MAX_SEC 3 76 77#define IPC_TRIGGER_MODE_IRQ true 78 79/* exported resources from IFWI */ 80#define PLAT_RESOURCE_IPC_INDEX 0 81#define PLAT_RESOURCE_IPC_SIZE 0x1000 82#define PLAT_RESOURCE_GCR_OFFSET 0x1000 83#define PLAT_RESOURCE_GCR_SIZE 0x1000 84#define PLAT_RESOURCE_BIOS_DATA_INDEX 1 85#define PLAT_RESOURCE_BIOS_IFACE_INDEX 2 86#define PLAT_RESOURCE_TELEM_SSRAM_INDEX 3 87#define PLAT_RESOURCE_ISP_DATA_INDEX 4 88#define PLAT_RESOURCE_ISP_IFACE_INDEX 5 89#define PLAT_RESOURCE_GTD_DATA_INDEX 6 90#define PLAT_RESOURCE_GTD_IFACE_INDEX 7 91#define PLAT_RESOURCE_ACPI_IO_INDEX 0 92 93/* 94 * BIOS does not create an ACPI device for each PMC function, 95 * but exports multiple resources from one ACPI device(IPC) for 96 * multiple functions. This driver is responsible to create a 97 * platform device and to export resources for those functions. 98 */ 99#define TCO_DEVICE_NAME "iTCO_wdt" 100#define SMI_EN_OFFSET 0x40 101#define SMI_EN_SIZE 4 102#define TCO_BASE_OFFSET 0x60 103#define TCO_REGS_SIZE 16 104#define PUNIT_DEVICE_NAME "intel_punit_ipc" 105#define TELEMETRY_DEVICE_NAME "intel_telemetry" 106#define TELEM_SSRAM_SIZE 240 107#define TELEM_PMC_SSRAM_OFFSET 0x1B00 108#define TELEM_PUNIT_SSRAM_OFFSET 0x1A00 109#define TCO_PMC_OFFSET 0x8 110#define TCO_PMC_SIZE 0x4 111 112/* PMC register bit definitions */ 113 114/* PMC_CFG_REG bit masks */ 115#define PMC_CFG_NO_REBOOT_MASK (1 << 4) 116#define PMC_CFG_NO_REBOOT_EN (1 << 4) 117#define PMC_CFG_NO_REBOOT_DIS (0 << 4) 118 119static struct intel_pmc_ipc_dev { 120 struct device *dev; 121 void __iomem *ipc_base; 122 bool irq_mode; 123 int irq; 124 int cmd; 125 struct completion cmd_complete; 126 127 /* The following PMC BARs share the same ACPI device with the IPC */ 128 resource_size_t acpi_io_base; 129 int acpi_io_size; 130 struct platform_device *tco_dev; 131 132 /* gcr */ 133 void __iomem *gcr_mem_base; 134 bool has_gcr_regs; 135 spinlock_t gcr_lock; 136 137 /* punit */ 138 struct platform_device *punit_dev; 139 140 /* Telemetry */ 141 resource_size_t telem_pmc_ssram_base; 142 resource_size_t telem_punit_ssram_base; 143 int telem_pmc_ssram_size; 144 int telem_punit_ssram_size; 145 u8 telem_res_inval; 146 struct platform_device *telemetry_dev; 147} ipcdev; 148 149static char *ipc_err_sources[] = { 150 [IPC_ERR_NONE] = 151 "no error", 152 [IPC_ERR_CMD_NOT_SUPPORTED] = 153 "command not supported", 154 [IPC_ERR_CMD_NOT_SERVICED] = 155 "command not serviced", 156 [IPC_ERR_UNABLE_TO_SERVICE] = 157 "unable to service", 158 [IPC_ERR_CMD_INVALID] = 159 "command invalid", 160 [IPC_ERR_CMD_FAILED] = 161 "command failed", 162 [IPC_ERR_EMSECURITY] = 163 "Invalid Battery", 164 [IPC_ERR_UNSIGNEDKERNEL] = 165 "Unsigned kernel", 166}; 167 168/* Prevent concurrent calls to the PMC */ 169static DEFINE_MUTEX(ipclock); 170 171static inline void ipc_send_command(u32 cmd) 172{ 173 ipcdev.cmd = cmd; 174 if (ipcdev.irq_mode) { 175 reinit_completion(&ipcdev.cmd_complete); 176 cmd |= IPC_CMD_MSI; 177 } 178 writel(cmd, ipcdev.ipc_base + IPC_CMD); 179} 180 181static inline u32 ipc_read_status(void) 182{ 183 return readl(ipcdev.ipc_base + IPC_STATUS); 184} 185 186static inline void ipc_data_writel(u32 data, u32 offset) 187{ 188 writel(data, ipcdev.ipc_base + IPC_WRITE_BUFFER + offset); 189} 190 191static inline u8 __maybe_unused ipc_data_readb(u32 offset) 192{ 193 return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset); 194} 195 196static inline u32 ipc_data_readl(u32 offset) 197{ 198 return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset); 199} 200 201static inline u64 gcr_data_readq(u32 offset) 202{ 203 return readq(ipcdev.gcr_mem_base + offset); 204} 205 206static inline int is_gcr_valid(u32 offset) 207{ 208 if (!ipcdev.has_gcr_regs) 209 return -EACCES; 210 211 if (offset > PLAT_RESOURCE_GCR_SIZE) 212 return -EINVAL; 213 214 return 0; 215} 216 217/** 218 * intel_pmc_gcr_read() - Read PMC GCR register 219 * @offset: offset of GCR register from GCR address base 220 * @data: data pointer for storing the register output 221 * 222 * Reads the PMC GCR register of given offset. 223 * 224 * Return: negative value on error or 0 on success. 225 */ 226int intel_pmc_gcr_read(u32 offset, u32 *data) 227{ 228 int ret; 229 230 spin_lock(&ipcdev.gcr_lock); 231 232 ret = is_gcr_valid(offset); 233 if (ret < 0) { 234 spin_unlock(&ipcdev.gcr_lock); 235 return ret; 236 } 237 238 *data = readl(ipcdev.gcr_mem_base + offset); 239 240 spin_unlock(&ipcdev.gcr_lock); 241 242 return 0; 243} 244EXPORT_SYMBOL_GPL(intel_pmc_gcr_read); 245 246/** 247 * intel_pmc_gcr_write() - Write PMC GCR register 248 * @offset: offset of GCR register from GCR address base 249 * @data: register update value 250 * 251 * Writes the PMC GCR register of given offset with given 252 * value. 253 * 254 * Return: negative value on error or 0 on success. 255 */ 256int intel_pmc_gcr_write(u32 offset, u32 data) 257{ 258 int ret; 259 260 spin_lock(&ipcdev.gcr_lock); 261 262 ret = is_gcr_valid(offset); 263 if (ret < 0) { 264 spin_unlock(&ipcdev.gcr_lock); 265 return ret; 266 } 267 268 writel(data, ipcdev.gcr_mem_base + offset); 269 270 spin_unlock(&ipcdev.gcr_lock); 271 272 return 0; 273} 274EXPORT_SYMBOL_GPL(intel_pmc_gcr_write); 275 276/** 277 * intel_pmc_gcr_update() - Update PMC GCR register bits 278 * @offset: offset of GCR register from GCR address base 279 * @mask: bit mask for update operation 280 * @val: update value 281 * 282 * Updates the bits of given GCR register as specified by 283 * @mask and @val. 284 * 285 * Return: negative value on error or 0 on success. 286 */ 287int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val) 288{ 289 u32 new_val; 290 int ret = 0; 291 292 spin_lock(&ipcdev.gcr_lock); 293 294 ret = is_gcr_valid(offset); 295 if (ret < 0) 296 goto gcr_ipc_unlock; 297 298 new_val = readl(ipcdev.gcr_mem_base + offset); 299 300 new_val &= ~mask; 301 new_val |= val & mask; 302 303 writel(new_val, ipcdev.gcr_mem_base + offset); 304 305 new_val = readl(ipcdev.gcr_mem_base + offset); 306 307 /* check whether the bit update is successful */ 308 if ((new_val & mask) != (val & mask)) { 309 ret = -EIO; 310 goto gcr_ipc_unlock; 311 } 312 313gcr_ipc_unlock: 314 spin_unlock(&ipcdev.gcr_lock); 315 return ret; 316} 317EXPORT_SYMBOL_GPL(intel_pmc_gcr_update); 318 319static int update_no_reboot_bit(void *priv, bool set) 320{ 321 u32 value = set ? PMC_CFG_NO_REBOOT_EN : PMC_CFG_NO_REBOOT_DIS; 322 323 return intel_pmc_gcr_update(PMC_GCR_PMC_CFG_REG, 324 PMC_CFG_NO_REBOOT_MASK, value); 325} 326 327static int intel_pmc_ipc_check_status(void) 328{ 329 int status; 330 int ret = 0; 331 332 if (ipcdev.irq_mode) { 333 if (0 == wait_for_completion_timeout( 334 &ipcdev.cmd_complete, IPC_MAX_SEC * HZ)) 335 ret = -ETIMEDOUT; 336 } else { 337 int loop_count = IPC_LOOP_CNT; 338 339 while ((ipc_read_status() & IPC_STATUS_BUSY) && --loop_count) 340 udelay(1); 341 if (loop_count == 0) 342 ret = -ETIMEDOUT; 343 } 344 345 status = ipc_read_status(); 346 if (ret == -ETIMEDOUT) { 347 dev_err(ipcdev.dev, 348 "IPC timed out, TS=0x%x, CMD=0x%x\n", 349 status, ipcdev.cmd); 350 return ret; 351 } 352 353 if (status & IPC_STATUS_ERR) { 354 int i; 355 356 ret = -EIO; 357 i = (status >> IPC_CMD_SIZE) & 0xFF; 358 if (i < ARRAY_SIZE(ipc_err_sources)) 359 dev_err(ipcdev.dev, 360 "IPC failed: %s, STS=0x%x, CMD=0x%x\n", 361 ipc_err_sources[i], status, ipcdev.cmd); 362 else 363 dev_err(ipcdev.dev, 364 "IPC failed: unknown, STS=0x%x, CMD=0x%x\n", 365 status, ipcdev.cmd); 366 if ((i == IPC_ERR_UNSIGNEDKERNEL) || (i == IPC_ERR_EMSECURITY)) 367 ret = -EACCES; 368 } 369 370 return ret; 371} 372 373/** 374 * intel_pmc_ipc_simple_command() - Simple IPC command 375 * @cmd: IPC command code. 376 * @sub: IPC command sub type. 377 * 378 * Send a simple IPC command to PMC when don't need to specify 379 * input/output data and source/dest pointers. 380 * 381 * Return: an IPC error code or 0 on success. 382 */ 383int intel_pmc_ipc_simple_command(int cmd, int sub) 384{ 385 int ret; 386 387 mutex_lock(&ipclock); 388 if (ipcdev.dev == NULL) { 389 mutex_unlock(&ipclock); 390 return -ENODEV; 391 } 392 ipc_send_command(sub << IPC_CMD_SUBCMD | cmd); 393 ret = intel_pmc_ipc_check_status(); 394 mutex_unlock(&ipclock); 395 396 return ret; 397} 398EXPORT_SYMBOL_GPL(intel_pmc_ipc_simple_command); 399 400/** 401 * intel_pmc_ipc_raw_cmd() - IPC command with data and pointers 402 * @cmd: IPC command code. 403 * @sub: IPC command sub type. 404 * @in: input data of this IPC command. 405 * @inlen: input data length in bytes. 406 * @out: output data of this IPC command. 407 * @outlen: output data length in dwords. 408 * @sptr: data writing to SPTR register. 409 * @dptr: data writing to DPTR register. 410 * 411 * Send an IPC command to PMC with input/output data and source/dest pointers. 412 * 413 * Return: an IPC error code or 0 on success. 414 */ 415int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out, 416 u32 outlen, u32 dptr, u32 sptr) 417{ 418 u32 wbuf[4] = { 0 }; 419 int ret; 420 int i; 421 422 if (inlen > IPC_DATA_BUFFER_SIZE || outlen > IPC_DATA_BUFFER_SIZE / 4) 423 return -EINVAL; 424 425 mutex_lock(&ipclock); 426 if (ipcdev.dev == NULL) { 427 mutex_unlock(&ipclock); 428 return -ENODEV; 429 } 430 memcpy(wbuf, in, inlen); 431 writel(dptr, ipcdev.ipc_base + IPC_DPTR); 432 writel(sptr, ipcdev.ipc_base + IPC_SPTR); 433 /* The input data register is 32bit register and inlen is in Byte */ 434 for (i = 0; i < ((inlen + 3) / 4); i++) 435 ipc_data_writel(wbuf[i], 4 * i); 436 ipc_send_command((inlen << IPC_CMD_SIZE) | 437 (sub << IPC_CMD_SUBCMD) | cmd); 438 ret = intel_pmc_ipc_check_status(); 439 if (!ret) { 440 /* out is read from 32bit register and outlen is in 32bit */ 441 for (i = 0; i < outlen; i++) 442 *out++ = ipc_data_readl(4 * i); 443 } 444 mutex_unlock(&ipclock); 445 446 return ret; 447} 448EXPORT_SYMBOL_GPL(intel_pmc_ipc_raw_cmd); 449 450/** 451 * intel_pmc_ipc_command() - IPC command with input/output data 452 * @cmd: IPC command code. 453 * @sub: IPC command sub type. 454 * @in: input data of this IPC command. 455 * @inlen: input data length in bytes. 456 * @out: output data of this IPC command. 457 * @outlen: output data length in dwords. 458 * 459 * Send an IPC command to PMC with input/output data. 460 * 461 * Return: an IPC error code or 0 on success. 462 */ 463int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen, 464 u32 *out, u32 outlen) 465{ 466 return intel_pmc_ipc_raw_cmd(cmd, sub, in, inlen, out, outlen, 0, 0); 467} 468EXPORT_SYMBOL_GPL(intel_pmc_ipc_command); 469 470static irqreturn_t ioc(int irq, void *dev_id) 471{ 472 int status; 473 474 if (ipcdev.irq_mode) { 475 status = ipc_read_status(); 476 writel(status | IPC_STATUS_IRQ, ipcdev.ipc_base + IPC_STATUS); 477 } 478 complete(&ipcdev.cmd_complete); 479 480 return IRQ_HANDLED; 481} 482 483static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 484{ 485 struct intel_pmc_ipc_dev *pmc = &ipcdev; 486 int ret; 487 488 /* Only one PMC is supported */ 489 if (pmc->dev) 490 return -EBUSY; 491 492 pmc->irq_mode = IPC_TRIGGER_MODE_IRQ; 493 494 spin_lock_init(&ipcdev.gcr_lock); 495 496 ret = pcim_enable_device(pdev); 497 if (ret) 498 return ret; 499 500 ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev)); 501 if (ret) 502 return ret; 503 504 init_completion(&pmc->cmd_complete); 505 506 pmc->ipc_base = pcim_iomap_table(pdev)[0]; 507 508 ret = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_pmc_ipc", 509 pmc); 510 if (ret) { 511 dev_err(&pdev->dev, "Failed to request irq\n"); 512 return ret; 513 } 514 515 pmc->dev = &pdev->dev; 516 517 pci_set_drvdata(pdev, pmc); 518 519 return 0; 520} 521 522static const struct pci_device_id ipc_pci_ids[] = { 523 {PCI_VDEVICE(INTEL, 0x0a94), 0}, 524 {PCI_VDEVICE(INTEL, 0x1a94), 0}, 525 {PCI_VDEVICE(INTEL, 0x5a94), 0}, 526 { 0,} 527}; 528MODULE_DEVICE_TABLE(pci, ipc_pci_ids); 529 530static struct pci_driver ipc_pci_driver = { 531 .name = "intel_pmc_ipc", 532 .id_table = ipc_pci_ids, 533 .probe = ipc_pci_probe, 534}; 535 536static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev, 537 struct device_attribute *attr, 538 const char *buf, size_t count) 539{ 540 int subcmd; 541 int cmd; 542 int ret; 543 544 ret = sscanf(buf, "%d %d", &cmd, &subcmd); 545 if (ret != 2) { 546 dev_err(dev, "Error args\n"); 547 return -EINVAL; 548 } 549 550 ret = intel_pmc_ipc_simple_command(cmd, subcmd); 551 if (ret) { 552 dev_err(dev, "command %d error with %d\n", cmd, ret); 553 return ret; 554 } 555 return (ssize_t)count; 556} 557 558static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev, 559 struct device_attribute *attr, 560 const char *buf, size_t count) 561{ 562 unsigned long val; 563 int subcmd; 564 int ret; 565 566 if (kstrtoul(buf, 0, &val)) 567 return -EINVAL; 568 569 if (val) 570 subcmd = 1; 571 else 572 subcmd = 0; 573 ret = intel_pmc_ipc_simple_command(PMC_IPC_NORTHPEAK_CTRL, subcmd); 574 if (ret) { 575 dev_err(dev, "command north %d error with %d\n", subcmd, ret); 576 return ret; 577 } 578 return (ssize_t)count; 579} 580 581static DEVICE_ATTR(simplecmd, S_IWUSR, 582 NULL, intel_pmc_ipc_simple_cmd_store); 583static DEVICE_ATTR(northpeak, S_IWUSR, 584 NULL, intel_pmc_ipc_northpeak_store); 585 586static struct attribute *intel_ipc_attrs[] = { 587 &dev_attr_northpeak.attr, 588 &dev_attr_simplecmd.attr, 589 NULL 590}; 591 592static const struct attribute_group intel_ipc_group = { 593 .attrs = intel_ipc_attrs, 594}; 595 596static struct resource punit_res_array[] = { 597 /* Punit BIOS */ 598 { 599 .flags = IORESOURCE_MEM, 600 }, 601 { 602 .flags = IORESOURCE_MEM, 603 }, 604 /* Punit ISP */ 605 { 606 .flags = IORESOURCE_MEM, 607 }, 608 { 609 .flags = IORESOURCE_MEM, 610 }, 611 /* Punit GTD */ 612 { 613 .flags = IORESOURCE_MEM, 614 }, 615 { 616 .flags = IORESOURCE_MEM, 617 }, 618}; 619 620#define TCO_RESOURCE_ACPI_IO 0 621#define TCO_RESOURCE_SMI_EN_IO 1 622#define TCO_RESOURCE_GCR_MEM 2 623static struct resource tco_res[] = { 624 /* ACPI - TCO */ 625 { 626 .flags = IORESOURCE_IO, 627 }, 628 /* ACPI - SMI */ 629 { 630 .flags = IORESOURCE_IO, 631 }, 632}; 633 634static struct itco_wdt_platform_data tco_info = { 635 .name = "Apollo Lake SoC", 636 .version = 5, 637 .no_reboot_priv = &ipcdev, 638 .update_no_reboot_bit = update_no_reboot_bit, 639}; 640 641#define TELEMETRY_RESOURCE_PUNIT_SSRAM 0 642#define TELEMETRY_RESOURCE_PMC_SSRAM 1 643static struct resource telemetry_res[] = { 644 /*Telemetry*/ 645 { 646 .flags = IORESOURCE_MEM, 647 }, 648 { 649 .flags = IORESOURCE_MEM, 650 }, 651}; 652 653static int ipc_create_punit_device(void) 654{ 655 struct platform_device *pdev; 656 const struct platform_device_info pdevinfo = { 657 .parent = ipcdev.dev, 658 .name = PUNIT_DEVICE_NAME, 659 .id = -1, 660 .res = punit_res_array, 661 .num_res = ARRAY_SIZE(punit_res_array), 662 }; 663 664 pdev = platform_device_register_full(&pdevinfo); 665 if (IS_ERR(pdev)) 666 return PTR_ERR(pdev); 667 668 ipcdev.punit_dev = pdev; 669 670 return 0; 671} 672 673static int ipc_create_tco_device(void) 674{ 675 struct platform_device *pdev; 676 struct resource *res; 677 const struct platform_device_info pdevinfo = { 678 .parent = ipcdev.dev, 679 .name = TCO_DEVICE_NAME, 680 .id = -1, 681 .res = tco_res, 682 .num_res = ARRAY_SIZE(tco_res), 683 .data = &tco_info, 684 .size_data = sizeof(tco_info), 685 }; 686 687 res = tco_res + TCO_RESOURCE_ACPI_IO; 688 res->start = ipcdev.acpi_io_base + TCO_BASE_OFFSET; 689 res->end = res->start + TCO_REGS_SIZE - 1; 690 691 res = tco_res + TCO_RESOURCE_SMI_EN_IO; 692 res->start = ipcdev.acpi_io_base + SMI_EN_OFFSET; 693 res->end = res->start + SMI_EN_SIZE - 1; 694 695 pdev = platform_device_register_full(&pdevinfo); 696 if (IS_ERR(pdev)) 697 return PTR_ERR(pdev); 698 699 ipcdev.tco_dev = pdev; 700 701 return 0; 702} 703 704static int ipc_create_telemetry_device(void) 705{ 706 struct platform_device *pdev; 707 struct resource *res; 708 const struct platform_device_info pdevinfo = { 709 .parent = ipcdev.dev, 710 .name = TELEMETRY_DEVICE_NAME, 711 .id = -1, 712 .res = telemetry_res, 713 .num_res = ARRAY_SIZE(telemetry_res), 714 }; 715 716 res = telemetry_res + TELEMETRY_RESOURCE_PUNIT_SSRAM; 717 res->start = ipcdev.telem_punit_ssram_base; 718 res->end = res->start + ipcdev.telem_punit_ssram_size - 1; 719 720 res = telemetry_res + TELEMETRY_RESOURCE_PMC_SSRAM; 721 res->start = ipcdev.telem_pmc_ssram_base; 722 res->end = res->start + ipcdev.telem_pmc_ssram_size - 1; 723 724 pdev = platform_device_register_full(&pdevinfo); 725 if (IS_ERR(pdev)) 726 return PTR_ERR(pdev); 727 728 ipcdev.telemetry_dev = pdev; 729 730 return 0; 731} 732 733static int ipc_create_pmc_devices(void) 734{ 735 int ret; 736 737 /* If we have ACPI based watchdog use that instead */ 738 if (!acpi_has_watchdog()) { 739 ret = ipc_create_tco_device(); 740 if (ret) { 741 dev_err(ipcdev.dev, "Failed to add tco platform device\n"); 742 return ret; 743 } 744 } 745 746 ret = ipc_create_punit_device(); 747 if (ret) { 748 dev_err(ipcdev.dev, "Failed to add punit platform device\n"); 749 platform_device_unregister(ipcdev.tco_dev); 750 } 751 752 if (!ipcdev.telem_res_inval) { 753 ret = ipc_create_telemetry_device(); 754 if (ret) 755 dev_warn(ipcdev.dev, 756 "Failed to add telemetry platform device\n"); 757 } 758 759 return ret; 760} 761 762static int ipc_plat_get_res(struct platform_device *pdev) 763{ 764 struct resource *res, *punit_res; 765 void __iomem *addr; 766 int size; 767 768 res = platform_get_resource(pdev, IORESOURCE_IO, 769 PLAT_RESOURCE_ACPI_IO_INDEX); 770 if (!res) { 771 dev_err(&pdev->dev, "Failed to get io resource\n"); 772 return -ENXIO; 773 } 774 size = resource_size(res); 775 ipcdev.acpi_io_base = res->start; 776 ipcdev.acpi_io_size = size; 777 dev_info(&pdev->dev, "io res: %pR\n", res); 778 779 punit_res = punit_res_array; 780 /* This is index 0 to cover BIOS data register */ 781 res = platform_get_resource(pdev, IORESOURCE_MEM, 782 PLAT_RESOURCE_BIOS_DATA_INDEX); 783 if (!res) { 784 dev_err(&pdev->dev, "Failed to get res of punit BIOS data\n"); 785 return -ENXIO; 786 } 787 *punit_res = *res; 788 dev_info(&pdev->dev, "punit BIOS data res: %pR\n", res); 789 790 /* This is index 1 to cover BIOS interface register */ 791 res = platform_get_resource(pdev, IORESOURCE_MEM, 792 PLAT_RESOURCE_BIOS_IFACE_INDEX); 793 if (!res) { 794 dev_err(&pdev->dev, "Failed to get res of punit BIOS iface\n"); 795 return -ENXIO; 796 } 797 *++punit_res = *res; 798 dev_info(&pdev->dev, "punit BIOS interface res: %pR\n", res); 799 800 /* This is index 2 to cover ISP data register, optional */ 801 res = platform_get_resource(pdev, IORESOURCE_MEM, 802 PLAT_RESOURCE_ISP_DATA_INDEX); 803 ++punit_res; 804 if (res) { 805 *punit_res = *res; 806 dev_info(&pdev->dev, "punit ISP data res: %pR\n", res); 807 } 808 809 /* This is index 3 to cover ISP interface register, optional */ 810 res = platform_get_resource(pdev, IORESOURCE_MEM, 811 PLAT_RESOURCE_ISP_IFACE_INDEX); 812 ++punit_res; 813 if (res) { 814 *punit_res = *res; 815 dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res); 816 } 817 818 /* This is index 4 to cover GTD data register, optional */ 819 res = platform_get_resource(pdev, IORESOURCE_MEM, 820 PLAT_RESOURCE_GTD_DATA_INDEX); 821 ++punit_res; 822 if (res) { 823 *punit_res = *res; 824 dev_info(&pdev->dev, "punit GTD data res: %pR\n", res); 825 } 826 827 /* This is index 5 to cover GTD interface register, optional */ 828 res = platform_get_resource(pdev, IORESOURCE_MEM, 829 PLAT_RESOURCE_GTD_IFACE_INDEX); 830 ++punit_res; 831 if (res) { 832 *punit_res = *res; 833 dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res); 834 } 835 836 res = platform_get_resource(pdev, IORESOURCE_MEM, 837 PLAT_RESOURCE_IPC_INDEX); 838 if (!res) { 839 dev_err(&pdev->dev, "Failed to get ipc resource\n"); 840 return -ENXIO; 841 } 842 size = PLAT_RESOURCE_IPC_SIZE + PLAT_RESOURCE_GCR_SIZE; 843 res->end = res->start + size - 1; 844 845 addr = devm_ioremap_resource(&pdev->dev, res); 846 if (IS_ERR(addr)) 847 return PTR_ERR(addr); 848 849 ipcdev.ipc_base = addr; 850 851 ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET; 852 dev_info(&pdev->dev, "ipc res: %pR\n", res); 853 854 ipcdev.telem_res_inval = 0; 855 res = platform_get_resource(pdev, IORESOURCE_MEM, 856 PLAT_RESOURCE_TELEM_SSRAM_INDEX); 857 if (!res) { 858 dev_err(&pdev->dev, "Failed to get telemetry ssram resource\n"); 859 ipcdev.telem_res_inval = 1; 860 } else { 861 ipcdev.telem_punit_ssram_base = res->start + 862 TELEM_PUNIT_SSRAM_OFFSET; 863 ipcdev.telem_punit_ssram_size = TELEM_SSRAM_SIZE; 864 ipcdev.telem_pmc_ssram_base = res->start + 865 TELEM_PMC_SSRAM_OFFSET; 866 ipcdev.telem_pmc_ssram_size = TELEM_SSRAM_SIZE; 867 dev_info(&pdev->dev, "telemetry ssram res: %pR\n", res); 868 } 869 870 return 0; 871} 872 873/** 874 * intel_pmc_s0ix_counter_read() - Read S0ix residency. 875 * @data: Out param that contains current S0ix residency count. 876 * 877 * Return: an error code or 0 on success. 878 */ 879int intel_pmc_s0ix_counter_read(u64 *data) 880{ 881 u64 deep, shlw; 882 883 if (!ipcdev.has_gcr_regs) 884 return -EACCES; 885 886 deep = gcr_data_readq(PMC_GCR_TELEM_DEEP_S0IX_REG); 887 shlw = gcr_data_readq(PMC_GCR_TELEM_SHLW_S0IX_REG); 888 889 *data = S0IX_RESIDENCY_IN_USECS(deep, shlw); 890 891 return 0; 892} 893EXPORT_SYMBOL_GPL(intel_pmc_s0ix_counter_read); 894 895#ifdef CONFIG_ACPI 896static const struct acpi_device_id ipc_acpi_ids[] = { 897 { "INT34D2", 0}, 898 { } 899}; 900MODULE_DEVICE_TABLE(acpi, ipc_acpi_ids); 901#endif 902 903static int ipc_plat_probe(struct platform_device *pdev) 904{ 905 int ret; 906 907 ipcdev.dev = &pdev->dev; 908 ipcdev.irq_mode = IPC_TRIGGER_MODE_IRQ; 909 init_completion(&ipcdev.cmd_complete); 910 spin_lock_init(&ipcdev.gcr_lock); 911 912 ipcdev.irq = platform_get_irq(pdev, 0); 913 if (ipcdev.irq < 0) { 914 dev_err(&pdev->dev, "Failed to get irq\n"); 915 return -EINVAL; 916 } 917 918 ret = ipc_plat_get_res(pdev); 919 if (ret) { 920 dev_err(&pdev->dev, "Failed to request resource\n"); 921 return ret; 922 } 923 924 ret = ipc_create_pmc_devices(); 925 if (ret) { 926 dev_err(&pdev->dev, "Failed to create pmc devices\n"); 927 return ret; 928 } 929 930 if (devm_request_irq(&pdev->dev, ipcdev.irq, ioc, IRQF_NO_SUSPEND, 931 "intel_pmc_ipc", &ipcdev)) { 932 dev_err(&pdev->dev, "Failed to request irq\n"); 933 ret = -EBUSY; 934 goto err_irq; 935 } 936 937 ret = sysfs_create_group(&pdev->dev.kobj, &intel_ipc_group); 938 if (ret) { 939 dev_err(&pdev->dev, "Failed to create sysfs group %d\n", 940 ret); 941 goto err_sys; 942 } 943 944 ipcdev.has_gcr_regs = true; 945 946 return 0; 947err_sys: 948 devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev); 949err_irq: 950 platform_device_unregister(ipcdev.tco_dev); 951 platform_device_unregister(ipcdev.punit_dev); 952 platform_device_unregister(ipcdev.telemetry_dev); 953 954 return ret; 955} 956 957static int ipc_plat_remove(struct platform_device *pdev) 958{ 959 sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group); 960 devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev); 961 platform_device_unregister(ipcdev.tco_dev); 962 platform_device_unregister(ipcdev.punit_dev); 963 platform_device_unregister(ipcdev.telemetry_dev); 964 ipcdev.dev = NULL; 965 return 0; 966} 967 968static struct platform_driver ipc_plat_driver = { 969 .remove = ipc_plat_remove, 970 .probe = ipc_plat_probe, 971 .driver = { 972 .name = "pmc-ipc-plat", 973 .acpi_match_table = ACPI_PTR(ipc_acpi_ids), 974 }, 975}; 976 977static int __init intel_pmc_ipc_init(void) 978{ 979 int ret; 980 981 ret = platform_driver_register(&ipc_plat_driver); 982 if (ret) { 983 pr_err("Failed to register PMC ipc platform driver\n"); 984 return ret; 985 } 986 ret = pci_register_driver(&ipc_pci_driver); 987 if (ret) { 988 pr_err("Failed to register PMC ipc pci driver\n"); 989 platform_driver_unregister(&ipc_plat_driver); 990 return ret; 991 } 992 return ret; 993} 994 995static void __exit intel_pmc_ipc_exit(void) 996{ 997 pci_unregister_driver(&ipc_pci_driver); 998 platform_driver_unregister(&ipc_plat_driver); 999} 1000 1001MODULE_AUTHOR("Zha Qipeng <qipeng.zha@intel.com>"); 1002MODULE_DESCRIPTION("Intel PMC IPC driver"); 1003MODULE_LICENSE("GPL"); 1004 1005/* Some modules are dependent on this, so init earlier */ 1006fs_initcall(intel_pmc_ipc_init); 1007module_exit(intel_pmc_ipc_exit);