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

platform/x86: intel_pmc_ipc: Start using SCU IPC

SCU IPC is pretty much the same IPC implemented in the intel_pmc_ipc
driver so drop the duplicate implementation and call directly the SCU
IPC.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Mika Westerberg and committed by
Lee Jones
ddcce057 7e18c89d

+42 -266
+1
drivers/platform/x86/Kconfig
··· 1330 1330 config INTEL_PMC_IPC 1331 1331 tristate "Intel PMC IPC Driver" 1332 1332 depends on ACPI && PCI 1333 + select INTEL_SCU_IPC 1333 1334 ---help--- 1334 1335 This driver provides support for PMC control on some Intel platforms. 1335 1336 The PMC is an ARC processor which defines IPC commands for communication
+41 -266
drivers/platform/x86/intel_pmc_ipc.c
··· 21 21 #include <linux/platform_device.h> 22 22 23 23 #include <asm/intel_pmc_ipc.h> 24 + #include <asm/intel_scu_ipc.h> 24 25 25 26 #include <linux/platform_data/itco_wdt.h> 26 - 27 - /* 28 - * IPC registers 29 - * The IA write to IPC_CMD command register triggers an interrupt to the ARC, 30 - * The ARC handles the interrupt and services it, writing optional data to 31 - * the IPC1 registers, updates the IPC_STS response register with the status. 32 - */ 33 - #define IPC_CMD 0x00 34 - #define IPC_CMD_MSI BIT(8) 35 - #define IPC_CMD_SIZE 16 36 - #define IPC_CMD_SUBCMD 12 37 - #define IPC_STATUS 0x04 38 - #define IPC_STATUS_IRQ BIT(2) 39 - #define IPC_STATUS_ERR BIT(1) 40 - #define IPC_STATUS_BUSY BIT(0) 41 - #define IPC_SPTR 0x08 42 - #define IPC_DPTR 0x0C 43 - #define IPC_WRITE_BUFFER 0x80 44 - #define IPC_READ_BUFFER 0x90 45 27 46 28 /* Residency with clock rate at 19.2MHz to usecs */ 47 29 #define S0IX_RESIDENCY_IN_USECS(d, s) \ ··· 32 50 do_div(result, 192); \ 33 51 result; \ 34 52 }) 35 - 36 - /* 37 - * 16-byte buffer for sending data associated with IPC command. 38 - */ 39 - #define IPC_DATA_BUFFER_SIZE 16 40 - 41 - #define IPC_LOOP_CNT 3000000 42 - #define IPC_MAX_SEC 3 43 - 44 - #define IPC_TRIGGER_MODE_IRQ true 45 53 46 54 /* exported resources from IFWI */ 47 55 #define PLAT_RESOURCE_IPC_INDEX 0 ··· 75 103 76 104 static struct intel_pmc_ipc_dev { 77 105 struct device *dev; 78 - void __iomem *ipc_base; 79 - bool irq_mode; 80 - int irq; 81 - int cmd; 82 - struct completion cmd_complete; 83 106 84 107 /* The following PMC BARs share the same ACPI device with the IPC */ 85 108 resource_size_t acpi_io_base; ··· 98 131 u8 telem_res_inval; 99 132 struct platform_device *telemetry_dev; 100 133 } ipcdev; 101 - 102 - static char *ipc_err_sources[] = { 103 - [IPC_ERR_NONE] = 104 - "no error", 105 - [IPC_ERR_CMD_NOT_SUPPORTED] = 106 - "command not supported", 107 - [IPC_ERR_CMD_NOT_SERVICED] = 108 - "command not serviced", 109 - [IPC_ERR_UNABLE_TO_SERVICE] = 110 - "unable to service", 111 - [IPC_ERR_CMD_INVALID] = 112 - "command invalid", 113 - [IPC_ERR_CMD_FAILED] = 114 - "command failed", 115 - [IPC_ERR_EMSECURITY] = 116 - "Invalid Battery", 117 - [IPC_ERR_UNSIGNEDKERNEL] = 118 - "Unsigned kernel", 119 - }; 120 - 121 - /* Prevent concurrent calls to the PMC */ 122 - static DEFINE_MUTEX(ipclock); 123 - 124 - static inline void ipc_send_command(u32 cmd) 125 - { 126 - ipcdev.cmd = cmd; 127 - if (ipcdev.irq_mode) { 128 - reinit_completion(&ipcdev.cmd_complete); 129 - cmd |= IPC_CMD_MSI; 130 - } 131 - writel(cmd, ipcdev.ipc_base + IPC_CMD); 132 - } 133 - 134 - static inline u32 ipc_read_status(void) 135 - { 136 - return readl(ipcdev.ipc_base + IPC_STATUS); 137 - } 138 - 139 - static inline void ipc_data_writel(u32 data, u32 offset) 140 - { 141 - writel(data, ipcdev.ipc_base + IPC_WRITE_BUFFER + offset); 142 - } 143 - 144 - static inline u32 ipc_data_readl(u32 offset) 145 - { 146 - return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset); 147 - } 148 134 149 135 static inline u64 gcr_data_readq(u32 offset) 150 136 { ··· 194 274 PMC_CFG_NO_REBOOT_MASK, value); 195 275 } 196 276 197 - static int intel_pmc_ipc_check_status(void) 198 - { 199 - int status; 200 - int ret = 0; 201 - 202 - if (ipcdev.irq_mode) { 203 - if (0 == wait_for_completion_timeout( 204 - &ipcdev.cmd_complete, IPC_MAX_SEC * HZ)) 205 - ret = -ETIMEDOUT; 206 - } else { 207 - int loop_count = IPC_LOOP_CNT; 208 - 209 - while ((ipc_read_status() & IPC_STATUS_BUSY) && --loop_count) 210 - udelay(1); 211 - if (loop_count == 0) 212 - ret = -ETIMEDOUT; 213 - } 214 - 215 - status = ipc_read_status(); 216 - if (ret == -ETIMEDOUT) { 217 - dev_err(ipcdev.dev, 218 - "IPC timed out, TS=0x%x, CMD=0x%x\n", 219 - status, ipcdev.cmd); 220 - return ret; 221 - } 222 - 223 - if (status & IPC_STATUS_ERR) { 224 - int i; 225 - 226 - ret = -EIO; 227 - i = (status >> IPC_CMD_SIZE) & 0xFF; 228 - if (i < ARRAY_SIZE(ipc_err_sources)) 229 - dev_err(ipcdev.dev, 230 - "IPC failed: %s, STS=0x%x, CMD=0x%x\n", 231 - ipc_err_sources[i], status, ipcdev.cmd); 232 - else 233 - dev_err(ipcdev.dev, 234 - "IPC failed: unknown, STS=0x%x, CMD=0x%x\n", 235 - status, ipcdev.cmd); 236 - if ((i == IPC_ERR_UNSIGNEDKERNEL) || (i == IPC_ERR_EMSECURITY)) 237 - ret = -EACCES; 238 - } 239 - 240 - return ret; 241 - } 242 - 243 - /** 244 - * intel_pmc_ipc_simple_command() - Simple IPC command 245 - * @cmd: IPC command code. 246 - * @sub: IPC command sub type. 247 - * 248 - * Send a simple IPC command to PMC when don't need to specify 249 - * input/output data and source/dest pointers. 250 - * 251 - * Return: an IPC error code or 0 on success. 252 - */ 253 - static int intel_pmc_ipc_simple_command(int cmd, int sub) 254 - { 255 - int ret; 256 - 257 - mutex_lock(&ipclock); 258 - if (ipcdev.dev == NULL) { 259 - mutex_unlock(&ipclock); 260 - return -ENODEV; 261 - } 262 - ipc_send_command(sub << IPC_CMD_SUBCMD | cmd); 263 - ret = intel_pmc_ipc_check_status(); 264 - mutex_unlock(&ipclock); 265 - 266 - return ret; 267 - } 268 - 269 - /** 270 - * intel_pmc_ipc_raw_cmd() - IPC command with data and pointers 271 - * @cmd: IPC command code. 272 - * @sub: IPC command sub type. 273 - * @in: input data of this IPC command. 274 - * @inlen: input data length in bytes. 275 - * @out: output data of this IPC command. 276 - * @outlen: output data length in dwords. 277 - * @sptr: data writing to SPTR register. 278 - * @dptr: data writing to DPTR register. 279 - * 280 - * Send an IPC command to PMC with input/output data and source/dest pointers. 281 - * 282 - * Return: an IPC error code or 0 on success. 283 - */ 284 - static int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out, 285 - u32 outlen, u32 dptr, u32 sptr) 286 - { 287 - u32 wbuf[4] = { 0 }; 288 - int ret; 289 - int i; 290 - 291 - if (inlen > IPC_DATA_BUFFER_SIZE || outlen > IPC_DATA_BUFFER_SIZE / 4) 292 - return -EINVAL; 293 - 294 - mutex_lock(&ipclock); 295 - if (ipcdev.dev == NULL) { 296 - mutex_unlock(&ipclock); 297 - return -ENODEV; 298 - } 299 - memcpy(wbuf, in, inlen); 300 - writel(dptr, ipcdev.ipc_base + IPC_DPTR); 301 - writel(sptr, ipcdev.ipc_base + IPC_SPTR); 302 - /* The input data register is 32bit register and inlen is in Byte */ 303 - for (i = 0; i < ((inlen + 3) / 4); i++) 304 - ipc_data_writel(wbuf[i], 4 * i); 305 - ipc_send_command((inlen << IPC_CMD_SIZE) | 306 - (sub << IPC_CMD_SUBCMD) | cmd); 307 - ret = intel_pmc_ipc_check_status(); 308 - if (!ret) { 309 - /* out is read from 32bit register and outlen is in 32bit */ 310 - for (i = 0; i < outlen; i++) 311 - *out++ = ipc_data_readl(4 * i); 312 - } 313 - mutex_unlock(&ipclock); 314 - 315 - return ret; 316 - } 317 - 318 277 /** 319 278 * intel_pmc_ipc_command() - IPC command with input/output data 320 279 * @cmd: IPC command code. ··· 210 411 int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen, 211 412 u32 *out, u32 outlen) 212 413 { 213 - return intel_pmc_ipc_raw_cmd(cmd, sub, in, inlen, out, outlen, 0, 0); 414 + return intel_scu_ipc_dev_command(NULL, cmd, sub, in, inlen, out, outlen); 214 415 } 215 416 EXPORT_SYMBOL_GPL(intel_pmc_ipc_command); 216 - 217 - static irqreturn_t ioc(int irq, void *dev_id) 218 - { 219 - int status; 220 - 221 - if (ipcdev.irq_mode) { 222 - status = ipc_read_status(); 223 - writel(status | IPC_STATUS_IRQ, ipcdev.ipc_base + IPC_STATUS); 224 - } 225 - complete(&ipcdev.cmd_complete); 226 - 227 - return IRQ_HANDLED; 228 - } 229 417 230 418 static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 231 419 { 232 420 struct intel_pmc_ipc_dev *pmc = &ipcdev; 421 + struct intel_scu_ipc_data scu_data = {}; 422 + struct intel_scu_ipc_dev *scu; 233 423 int ret; 234 424 235 425 /* Only one PMC is supported */ 236 426 if (pmc->dev) 237 427 return -EBUSY; 238 - 239 - pmc->irq_mode = IPC_TRIGGER_MODE_IRQ; 240 428 241 429 spin_lock_init(&ipcdev.gcr_lock); 242 430 ··· 231 445 if (ret) 232 446 return ret; 233 447 234 - ret = pcim_iomap_regions(pdev, 1 << 0, pci_name(pdev)); 235 - if (ret) 236 - return ret; 448 + scu_data.mem = pdev->resource[0]; 237 449 238 - init_completion(&pmc->cmd_complete); 239 - 240 - pmc->ipc_base = pcim_iomap_table(pdev)[0]; 241 - 242 - ret = devm_request_irq(&pdev->dev, pdev->irq, ioc, 0, "intel_pmc_ipc", 243 - pmc); 244 - if (ret) { 245 - dev_err(&pdev->dev, "Failed to request irq\n"); 246 - return ret; 247 - } 450 + scu = devm_intel_scu_ipc_register(&pdev->dev, &scu_data); 451 + if (IS_ERR(scu)) 452 + return PTR_ERR(scu); 248 453 249 454 pmc->dev = &pdev->dev; 250 455 ··· 262 485 struct device_attribute *attr, 263 486 const char *buf, size_t count) 264 487 { 488 + struct intel_scu_ipc_dev *scu = dev_get_drvdata(dev); 265 489 int subcmd; 266 490 int cmd; 267 491 int ret; ··· 273 495 return -EINVAL; 274 496 } 275 497 276 - ret = intel_pmc_ipc_simple_command(cmd, subcmd); 498 + ret = intel_scu_ipc_dev_simple_command(scu, cmd, subcmd); 277 499 if (ret) { 278 500 dev_err(dev, "command %d error with %d\n", cmd, ret); 279 501 return ret; ··· 286 508 struct device_attribute *attr, 287 509 const char *buf, size_t count) 288 510 { 511 + struct intel_scu_ipc_dev *scu = dev_get_drvdata(dev); 289 512 unsigned long val; 290 513 int subcmd; 291 514 int ret; ··· 299 520 subcmd = 1; 300 521 else 301 522 subcmd = 0; 302 - ret = intel_pmc_ipc_simple_command(PMC_IPC_NORTHPEAK_CTRL, subcmd); 523 + ret = intel_scu_ipc_dev_simple_command(scu, PMC_IPC_NORTHPEAK_CTRL, subcmd); 303 524 if (ret) { 304 525 dev_err(dev, "command north %d error with %d\n", subcmd, ret); 305 526 return ret; ··· 493 714 return ret; 494 715 } 495 716 496 - static int ipc_plat_get_res(struct platform_device *pdev) 717 + static int ipc_plat_get_res(struct platform_device *pdev, 718 + struct intel_scu_ipc_data *scu_data) 497 719 { 498 720 struct resource *res, *punit_res = punit_res_array; 721 + resource_size_t start; 499 722 void __iomem *addr; 500 723 int size; 501 724 ··· 566 785 dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res); 567 786 } 568 787 788 + scu_data->irq = platform_get_irq(pdev, 0); 789 + 569 790 res = platform_get_resource(pdev, IORESOURCE_MEM, 570 791 PLAT_RESOURCE_IPC_INDEX); 571 792 if (!res) { 572 793 dev_err(&pdev->dev, "Failed to get ipc resource\n"); 573 794 return -ENXIO; 574 795 } 575 - size = PLAT_RESOURCE_IPC_SIZE + PLAT_RESOURCE_GCR_SIZE; 576 - res->end = res->start + size - 1; 577 - 578 - addr = devm_ioremap_resource(&pdev->dev, res); 579 - if (IS_ERR(addr)) 580 - return PTR_ERR(addr); 581 - 582 - ipcdev.ipc_base = addr; 583 - 584 - ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET; 585 796 dev_info(&pdev->dev, "ipc res: %pR\n", res); 797 + 798 + scu_data->mem.flags = res->flags; 799 + scu_data->mem.start = res->start; 800 + scu_data->mem.end = res->start + PLAT_RESOURCE_IPC_SIZE - 1; 801 + 802 + start = res->start + PLAT_RESOURCE_GCR_OFFSET; 803 + if (!devm_request_mem_region(&pdev->dev, start, PLAT_RESOURCE_GCR_SIZE, 804 + "pmc_ipc_plat")) 805 + return -EBUSY; 806 + 807 + addr = devm_ioremap(&pdev->dev, start, PLAT_RESOURCE_GCR_SIZE); 808 + if (!addr) 809 + return -ENOMEM; 810 + 811 + ipcdev.gcr_mem_base = addr; 586 812 587 813 ipcdev.telem_res_inval = 0; 588 814 res = platform_get_resource(pdev, IORESOURCE_MEM, ··· 642 854 643 855 static int ipc_plat_probe(struct platform_device *pdev) 644 856 { 857 + struct intel_scu_ipc_data scu_data = {}; 858 + struct intel_scu_ipc_dev *scu; 645 859 int ret; 646 860 647 861 ipcdev.dev = &pdev->dev; 648 - ipcdev.irq_mode = IPC_TRIGGER_MODE_IRQ; 649 - init_completion(&ipcdev.cmd_complete); 650 862 spin_lock_init(&ipcdev.gcr_lock); 651 863 652 - ipcdev.irq = platform_get_irq(pdev, 0); 653 - if (ipcdev.irq < 0) 654 - return -EINVAL; 655 - 656 - ret = ipc_plat_get_res(pdev); 864 + ret = ipc_plat_get_res(pdev, &scu_data); 657 865 if (ret) { 658 866 dev_err(&pdev->dev, "Failed to request resource\n"); 659 867 return ret; 660 868 } 869 + 870 + scu = devm_intel_scu_ipc_register(&pdev->dev, &scu_data); 871 + if (IS_ERR(scu)) 872 + return PTR_ERR(scu); 873 + 874 + platform_set_drvdata(pdev, scu); 661 875 662 876 ret = ipc_create_pmc_devices(); 663 877 if (ret) { ··· 667 877 return ret; 668 878 } 669 879 670 - if (devm_request_irq(&pdev->dev, ipcdev.irq, ioc, IRQF_NO_SUSPEND, 671 - "intel_pmc_ipc", &ipcdev)) { 672 - dev_err(&pdev->dev, "Failed to request irq\n"); 673 - ret = -EBUSY; 674 - goto err_irq; 675 - } 676 - 677 880 ipcdev.has_gcr_regs = true; 678 881 679 882 return 0; 680 - 681 - err_irq: 682 - platform_device_unregister(ipcdev.tco_dev); 683 - platform_device_unregister(ipcdev.punit_dev); 684 - platform_device_unregister(ipcdev.telemetry_dev); 685 - 686 - return ret; 687 883 } 688 884 689 885 static int ipc_plat_remove(struct platform_device *pdev) 690 886 { 691 - devm_free_irq(&pdev->dev, ipcdev.irq, &ipcdev); 692 887 platform_device_unregister(ipcdev.tco_dev); 693 888 platform_device_unregister(ipcdev.punit_dev); 694 889 platform_device_unregister(ipcdev.telemetry_dev);