linux/drivers/platform/x86/intel_pmc_ipc.c
<<
>>
Prefs
   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);
1008