/*
 * intel_pmc_ipc.c: Driver for the Intel PMC IPC mechanism
 *
 * (C) Copyright 2014-2015 Intel Corporation
 *
 * This driver is based on Intel SCU IPC driver(intel_scu_opc.c) by
 *     Sreedhara DS <sreedhara.ds@intel.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; version 2
 * of the License.
 *
 * PMC running in ARC processor communicates with other entity running in IA
 * core through IPC mechanism which in turn messaging between IA core ad PMC.
 */

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/pm.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/pm_qos.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/sched.h>
#include <linux/atomic.h>
#include <linux/notifier.h>
#include <linux/suspend.h>
#include <linux/acpi.h>
#include <asm/intel_pmc_ipc.h>
#include <linux/platform_data/itco_wdt.h>

/*
 * IPC registers
 * The IA write to IPC_CMD command register triggers an interrupt to the ARC,
 * The ARC handles the interrupt and services it, writing optional data to
 * the IPC1 registers, updates the IPC_STS response register with the status.
 */
#define IPC_CMD			0x0
#define		IPC_CMD_MSI		0x100
#define		IPC_CMD_SIZE		16
#define		IPC_CMD_SUBCMD		12
#define IPC_STATUS		0x04
#define		IPC_STATUS_IRQ		0x4
#define		IPC_STATUS_ERR		0x2
#define		IPC_STATUS_BUSY		0x1
#define IPC_SPTR		0x08
#define IPC_DPTR		0x0C
#define IPC_WRITE_BUFFER	0x80
#define IPC_READ_BUFFER		0x90

/*
 * 16-byte buffer for sending data associated with IPC command.
 */
#define IPC_DATA_BUFFER_SIZE	16

#define IPC_LOOP_CNT		3000000
#define IPC_MAX_SEC		3

#define IPC_TRIGGER_MODE_IRQ		true

/* exported resources from IFWI */
#define PLAT_RESOURCE_IPC_INDEX		0
#define PLAT_RESOURCE_IPC_SIZE		0x1000
#define PLAT_RESOURCE_GCR_OFFSET	0x1008
#define PLAT_RESOURCE_GCR_SIZE		0x4
#define PLAT_RESOURCE_BIOS_DATA_INDEX	1
#define PLAT_RESOURCE_BIOS_IFACE_INDEX	2
#define PLAT_RESOURCE_TELEM_SSRAM_INDEX	3
#define PLAT_RESOURCE_ISP_DATA_INDEX	4
#define PLAT_RESOURCE_ISP_IFACE_INDEX	5
#define PLAT_RESOURCE_GTD_DATA_INDEX	6
#define PLAT_RESOURCE_GTD_IFACE_INDEX	7
#define PLAT_RESOURCE_ACPI_IO_INDEX	0

/*
 * BIOS does not create an ACPI device for each PMC function,
 * but exports multiple resources from one ACPI device(IPC) for
 * multiple functions. This driver is responsible to create a
 * platform device and to export resources for those functions.
 */
#define TCO_DEVICE_NAME			"iTCO_wdt"
#define SMI_EN_OFFSET			0x40
#define SMI_EN_SIZE			4
#define TCO_BASE_OFFSET			0x60
#define TCO_REGS_SIZE			16
#define PUNIT_DEVICE_NAME		"intel_punit_ipc"
#define TELEMETRY_DEVICE_NAME		"intel_telemetry"
#define TELEM_SSRAM_SIZE		240
#define TELEM_PMC_SSRAM_OFFSET		0x1B00
#define TELEM_PUNIT_SSRAM_OFFSET	0x1A00
#define TCO_PMC_OFFSET			0x8
#define TCO_PMC_SIZE			0x4

static const int iTCO_version = 3;

static struct intel_pmc_ipc_dev {
	struct device *dev;
	void __iomem *ipc_base;
	bool irq_mode;
	int irq;
	int cmd;
	struct completion cmd_complete;

	/* The following PMC BARs share the same ACPI device with the IPC */
	resource_size_t acpi_io_base;
	int acpi_io_size;
	struct platform_device *tco_dev;

	/* gcr */
	resource_size_t gcr_base;
	int gcr_size;

	/* punit */
	struct platform_device *punit_dev;

	/* Telemetry */
	resource_size_t telem_pmc_ssram_base;
	resource_size_t telem_punit_ssram_base;
	int telem_pmc_ssram_size;
	int telem_punit_ssram_size;
	u8 telem_res_inval;
	struct platform_device *telemetry_dev;
} ipcdev;

static char *ipc_err_sources[] = {
	[IPC_ERR_NONE] =
		"no error",
	[IPC_ERR_CMD_NOT_SUPPORTED] =
		"command not supported",
	[IPC_ERR_CMD_NOT_SERVICED] =
		"command not serviced",
	[IPC_ERR_UNABLE_TO_SERVICE] =
		"unable to service",
	[IPC_ERR_CMD_INVALID] =
		"command invalid",
	[IPC_ERR_CMD_FAILED] =
		"command failed",
	[IPC_ERR_EMSECURITY] =
		"Invalid Battery",
	[IPC_ERR_UNSIGNEDKERNEL] =
		"Unsigned kernel",
};

/* Prevent concurrent calls to the PMC */
static DEFINE_MUTEX(ipclock);

static inline void ipc_send_command(u32 cmd)
{
	ipcdev.cmd = cmd;
	if (ipcdev.irq_mode) {
		reinit_completion(&ipcdev.cmd_complete);
		cmd |= IPC_CMD_MSI;
	}
	writel(cmd, ipcdev.ipc_base + IPC_CMD);
}

static inline u32 ipc_read_status(void)
{
	return readl(ipcdev.ipc_base + IPC_STATUS);
}

static inline void ipc_data_writel(u32 data, u32 offset)
{
	writel(data, ipcdev.ipc_base + IPC_WRITE_BUFFER + offset);
}

static inline u8 ipc_data_readb(u32 offset)
{
	return readb(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
}

static inline u32 ipc_data_readl(u32 offset)
{
	return readl(ipcdev.ipc_base + IPC_READ_BUFFER + offset);
}

static int intel_pmc_ipc_check_status(void)
{
	int status;
	int ret = 0;

	if (ipcdev.irq_mode) {
		if (0 == wait_for_completion_timeout(
				&ipcdev.cmd_complete, IPC_MAX_SEC * HZ))
			ret = -ETIMEDOUT;
	} else {
		int loop_count = IPC_LOOP_CNT;

		while ((ipc_read_status() & IPC_STATUS_BUSY) && --loop_count)
			udelay(1);
		if (loop_count == 0)
			ret = -ETIMEDOUT;
	}

	status = ipc_read_status();
	if (ret == -ETIMEDOUT) {
		dev_err(ipcdev.dev,
			"IPC timed out, TS=0x%x, CMD=0x%x\n",
			status, ipcdev.cmd);
		return ret;
	}

	if (status & IPC_STATUS_ERR) {
		int i;

		ret = -EIO;
		i = (status >> IPC_CMD_SIZE) & 0xFF;
		if (i < ARRAY_SIZE(ipc_err_sources))
			dev_err(ipcdev.dev,
				"IPC failed: %s, STS=0x%x, CMD=0x%x\n",
				ipc_err_sources[i], status, ipcdev.cmd);
		else
			dev_err(ipcdev.dev,
				"IPC failed: unknown, STS=0x%x, CMD=0x%x\n",
				status, ipcdev.cmd);
		if ((i == IPC_ERR_UNSIGNEDKERNEL) || (i == IPC_ERR_EMSECURITY))
			ret = -EACCES;
	}

	return ret;
}

/**
 * intel_pmc_ipc_simple_command() - Simple IPC command
 * @cmd:	IPC command code.
 * @sub:	IPC command sub type.
 *
 * Send a simple IPC command to PMC when don't need to specify
 * input/output data and source/dest pointers.
 *
 * Return:	an IPC error code or 0 on success.
 */
int intel_pmc_ipc_simple_command(int cmd, int sub)
{
	int ret;

	mutex_lock(&ipclock);
	if (ipcdev.dev == NULL) {
		mutex_unlock(&ipclock);
		return -ENODEV;
	}
	ipc_send_command(sub << IPC_CMD_SUBCMD | cmd);
	ret = intel_pmc_ipc_check_status();
	mutex_unlock(&ipclock);

	return ret;
}
EXPORT_SYMBOL_GPL(intel_pmc_ipc_simple_command);

/**
 * intel_pmc_ipc_raw_cmd() - IPC command with data and pointers
 * @cmd:	IPC command code.
 * @sub:	IPC command sub type.
 * @in:		input data of this IPC command.
 * @inlen:	input data length in bytes.
 * @out:	output data of this IPC command.
 * @outlen:	output data length in dwords.
 * @sptr:	data writing to SPTR register.
 * @dptr:	data writing to DPTR register.
 *
 * Send an IPC command to PMC with input/output data and source/dest pointers.
 *
 * Return:	an IPC error code or 0 on success.
 */
int intel_pmc_ipc_raw_cmd(u32 cmd, u32 sub, u8 *in, u32 inlen, u32 *out,
			  u32 outlen, u32 dptr, u32 sptr)
{
	u32 wbuf[4] = { 0 };
	int ret;
	int i;

	if (inlen > IPC_DATA_BUFFER_SIZE || outlen > IPC_DATA_BUFFER_SIZE / 4)
		return -EINVAL;

	mutex_lock(&ipclock);
	if (ipcdev.dev == NULL) {
		mutex_unlock(&ipclock);
		return -ENODEV;
	}
	memcpy(wbuf, in, inlen);
	writel(dptr, ipcdev.ipc_base + IPC_DPTR);
	writel(sptr, ipcdev.ipc_base + IPC_SPTR);
	/* The input data register is 32bit register and inlen is in Byte */
	for (i = 0; i < ((inlen + 3) / 4); i++)
		ipc_data_writel(wbuf[i], 4 * i);
	ipc_send_command((inlen << IPC_CMD_SIZE) |
			(sub << IPC_CMD_SUBCMD) | cmd);
	ret = intel_pmc_ipc_check_status();
	if (!ret) {
		/* out is read from 32bit register and outlen is in 32bit */
		for (i = 0; i < outlen; i++)
			*out++ = ipc_data_readl(4 * i);
	}
	mutex_unlock(&ipclock);

	return ret;
}
EXPORT_SYMBOL_GPL(intel_pmc_ipc_raw_cmd);

/**
 * intel_pmc_ipc_command() -  IPC command with input/output data
 * @cmd:	IPC command code.
 * @sub:	IPC command sub type.
 * @in:		input data of this IPC command.
 * @inlen:	input data length in bytes.
 * @out:	output data of this IPC command.
 * @outlen:	output data length in dwords.
 *
 * Send an IPC command to PMC with input/output data.
 *
 * Return:	an IPC error code or 0 on success.
 */
int intel_pmc_ipc_command(u32 cmd, u32 sub, u8 *in, u32 inlen,
			  u32 *out, u32 outlen)
{
	return intel_pmc_ipc_raw_cmd(cmd, sub, in, inlen, out, outlen, 0, 0);
}
EXPORT_SYMBOL_GPL(intel_pmc_ipc_command);

static irqreturn_t ioc(int irq, void *dev_id)
{
	int status;

	if (ipcdev.irq_mode) {
		status = ipc_read_status();
		writel(status | IPC_STATUS_IRQ, ipcdev.ipc_base + IPC_STATUS);
	}
	complete(&ipcdev.cmd_complete);

	return IRQ_HANDLED;
}

static int ipc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	resource_size_t pci_resource;
	int ret;
	int len;

	ipcdev.dev = &pci_dev_get(pdev)->dev;
	ipcdev.irq_mode = IPC_TRIGGER_MODE_IRQ;

	ret = pci_enable_device(pdev);
	if (ret)
		return ret;

	ret = pci_request_regions(pdev, "intel_pmc_ipc");
	if (ret)
		return ret;

	pci_resource = pci_resource_start(pdev, 0);
	len = pci_resource_len(pdev, 0);
	if (!pci_resource || !len) {
		dev_err(&pdev->dev, "Failed to get resource\n");
		return -ENOMEM;
	}

	init_completion(&ipcdev.cmd_complete);

	if (request_irq(pdev->irq, ioc, 0, "intel_pmc_ipc", &ipcdev)) {
		dev_err(&pdev->dev, "Failed to request irq\n");
		return -EBUSY;
	}

	ipcdev.ipc_base = ioremap_nocache(pci_resource, len);
	if (!ipcdev.ipc_base) {
		dev_err(&pdev->dev, "Failed to ioremap ipc base\n");
		free_irq(pdev->irq, &ipcdev);
		ret = -ENOMEM;
	}

	return ret;
}

static void ipc_pci_remove(struct pci_dev *pdev)
{
	free_irq(pdev->irq, &ipcdev);
	pci_release_regions(pdev);
	pci_dev_put(pdev);
	iounmap(ipcdev.ipc_base);
	ipcdev.dev = NULL;
}

static const struct pci_device_id ipc_pci_ids[] = {
	{PCI_VDEVICE(INTEL, 0x0a94), 0},
	{PCI_VDEVICE(INTEL, 0x1a94), 0},
	{ 0,}
};
MODULE_DEVICE_TABLE(pci, ipc_pci_ids);

static struct pci_driver ipc_pci_driver = {
	.name = "intel_pmc_ipc",
	.id_table = ipc_pci_ids,
	.probe = ipc_pci_probe,
	.remove = ipc_pci_remove,
};

static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev,
					      struct device_attribute *attr,
					      const char *buf, size_t count)
{
	int subcmd;
	int cmd;
	int ret;

	ret = sscanf(buf, "%d %d", &cmd, &subcmd);
	if (ret != 2) {
		dev_err(dev, "Error args\n");
		return -EINVAL;
	}

	ret = intel_pmc_ipc_simple_command(cmd, subcmd);
	if (ret) {
		dev_err(dev, "command %d error with %d\n", cmd, ret);
		return ret;
	}
	return (ssize_t)count;
}

static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev,
					     struct device_attribute *attr,
					     const char *buf, size_t count)
{
	unsigned long val;
	int subcmd;
	int ret;

	if (kstrtoul(buf, 0, &val))
		return -EINVAL;

	if (val)
		subcmd = 1;
	else
		subcmd = 0;
	ret = intel_pmc_ipc_simple_command(PMC_IPC_NORTHPEAK_CTRL, subcmd);
	if (ret) {
		dev_err(dev, "command north %d error with %d\n", subcmd, ret);
		return ret;
	}
	return (ssize_t)count;
}

static DEVICE_ATTR(simplecmd, S_IWUSR,
		   NULL, intel_pmc_ipc_simple_cmd_store);
static DEVICE_ATTR(northpeak, S_IWUSR,
		   NULL, intel_pmc_ipc_northpeak_store);

static struct attribute *intel_ipc_attrs[] = {
	&dev_attr_northpeak.attr,
	&dev_attr_simplecmd.attr,
	NULL
};

static const struct attribute_group intel_ipc_group = {
	.attrs = intel_ipc_attrs,
};

static struct resource punit_res_array[] = {
	/* Punit BIOS */
	{
		.flags = IORESOURCE_MEM,
	},
	{
		.flags = IORESOURCE_MEM,
	},
	/* Punit ISP */
	{
		.flags = IORESOURCE_MEM,
	},
	{
		.flags = IORESOURCE_MEM,
	},
	/* Punit GTD */
	{
		.flags = IORESOURCE_MEM,
	},
	{
		.flags = IORESOURCE_MEM,
	},
};

#define TCO_RESOURCE_ACPI_IO		0
#define TCO_RESOURCE_SMI_EN_IO		1
#define TCO_RESOURCE_GCR_MEM		2
static struct resource tco_res[] = {
	/* ACPI - TCO */
	{
		.flags = IORESOURCE_IO,
	},
	/* ACPI - SMI */
	{
		.flags = IORESOURCE_IO,
	},
	/* GCS */
	{
		.flags = IORESOURCE_MEM,
	},
};

static struct itco_wdt_platform_data tco_info = {
	.name = "Apollo Lake SoC",
	.version = 5,
};

#define TELEMETRY_RESOURCE_PUNIT_SSRAM	0
#define TELEMETRY_RESOURCE_PMC_SSRAM	1
static struct resource telemetry_res[] = {
	/*Telemetry*/
	{
		.flags = IORESOURCE_MEM,
	},
	{
		.flags = IORESOURCE_MEM,
	},
};

static int ipc_create_punit_device(void)
{
	struct platform_device *pdev;
	const struct platform_device_info pdevinfo = {
		.parent = ipcdev.dev,
		.name = PUNIT_DEVICE_NAME,
		.id = -1,
		.res = punit_res_array,
		.num_res = ARRAY_SIZE(punit_res_array),
		};

	pdev = platform_device_register_full(&pdevinfo);
	if (IS_ERR(pdev))
		return PTR_ERR(pdev);

	ipcdev.punit_dev = pdev;

	return 0;
}

static int ipc_create_tco_device(void)
{
	struct platform_device *pdev;
	struct resource *res;
	const struct platform_device_info pdevinfo = {
		.parent = ipcdev.dev,
		.name = TCO_DEVICE_NAME,
		.id = -1,
		.res = tco_res,
		.num_res = ARRAY_SIZE(tco_res),
		.data = &tco_info,
		.size_data = sizeof(tco_info),
		};

	res = tco_res + TCO_RESOURCE_ACPI_IO;
	res->start = ipcdev.acpi_io_base + TCO_BASE_OFFSET;
	res->end = res->start + TCO_REGS_SIZE - 1;

	res = tco_res + TCO_RESOURCE_SMI_EN_IO;
	res->start = ipcdev.acpi_io_base + SMI_EN_OFFSET;
	res->end = res->start + SMI_EN_SIZE - 1;

	res = tco_res + TCO_RESOURCE_GCR_MEM;
	res->start = ipcdev.gcr_base + TCO_PMC_OFFSET;
	res->end = res->start + TCO_PMC_SIZE - 1;

	pdev = platform_device_register_full(&pdevinfo);
	if (IS_ERR(pdev))
		return PTR_ERR(pdev);

	ipcdev.tco_dev = pdev;

	return 0;
}

static int ipc_create_telemetry_device(void)
{
	struct platform_device *pdev;
	struct resource *res;
	const struct platform_device_info pdevinfo = {
		.parent = ipcdev.dev,
		.name = TELEMETRY_DEVICE_NAME,
		.id = -1,
		.res = telemetry_res,
		.num_res = ARRAY_SIZE(telemetry_res),
		};

	res = telemetry_res + TELEMETRY_RESOURCE_PUNIT_SSRAM;
	res->start = ipcdev.telem_punit_ssram_base;
	res->end = res->start + ipcdev.telem_punit_ssram_size - 1;

	res = telemetry_res + TELEMETRY_RESOURCE_PMC_SSRAM;
	res->start = ipcdev.telem_pmc_ssram_base;
	res->end = res->start + ipcdev.telem_pmc_ssram_size - 1;

	pdev = platform_device_register_full(&pdevinfo);
	if (IS_ERR(pdev))
		return PTR_ERR(pdev);

	ipcdev.telemetry_dev = pdev;

	return 0;
}

static int ipc_create_pmc_devices(void)
{
	int ret;

	/* If we have ACPI based watchdog use that instead */
	if (!acpi_has_watchdog()) {
		ret = ipc_create_tco_device();
		if (ret) {
			dev_err(ipcdev.dev, "Failed to add tco platform device\n");
			return ret;
		}
	}

	ret = ipc_create_punit_device();
	if (ret) {
		dev_err(ipcdev.dev, "Failed to add punit platform device\n");
		platform_device_unregister(ipcdev.tco_dev);
	}

	if (!ipcdev.telem_res_inval) {
		ret = ipc_create_telemetry_device();
		if (ret)
			dev_warn(ipcdev.dev,
				"Failed to add telemetry platform device\n");
	}

	return ret;
}

static int ipc_plat_get_res(struct platform_device *pdev)
{
	struct resource *res, *punit_res;
	void __iomem *addr;
	int size;

	res = platform_get_resource(pdev, IORESOURCE_IO,
				    PLAT_RESOURCE_ACPI_IO_INDEX);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get io resource\n");
		return -ENXIO;
	}
	size = resource_size(res);
	ipcdev.acpi_io_base = res->start;
	ipcdev.acpi_io_size = size;
	dev_info(&pdev->dev, "io res: %pR\n", res);

	punit_res = punit_res_array;
	/* This is index 0 to cover BIOS data register */
	res = platform_get_resource(pdev, IORESOURCE_MEM,
				    PLAT_RESOURCE_BIOS_DATA_INDEX);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get res of punit BIOS data\n");
		return -ENXIO;
	}
	*punit_res = *res;
	dev_info(&pdev->dev, "punit BIOS data res: %pR\n", res);

	/* This is index 1 to cover BIOS interface register */
	res = platform_get_resource(pdev, IORESOURCE_MEM,
				    PLAT_RESOURCE_BIOS_IFACE_INDEX);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get res of punit BIOS iface\n");
		return -ENXIO;
	}
	*++punit_res = *res;
	dev_info(&pdev->dev, "punit BIOS interface res: %pR\n", res);

	/* This is index 2 to cover ISP data register, optional */
	res = platform_get_resource(pdev, IORESOURCE_MEM,
				    PLAT_RESOURCE_ISP_DATA_INDEX);
	++punit_res;
	if (res) {
		*punit_res = *res;
		dev_info(&pdev->dev, "punit ISP data res: %pR\n", res);
	}

	/* This is index 3 to cover ISP interface register, optional */
	res = platform_get_resource(pdev, IORESOURCE_MEM,
				    PLAT_RESOURCE_ISP_IFACE_INDEX);
	++punit_res;
	if (res) {
		*punit_res = *res;
		dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res);
	}

	/* This is index 4 to cover GTD data register, optional */
	res = platform_get_resource(pdev, IORESOURCE_MEM,
				    PLAT_RESOURCE_GTD_DATA_INDEX);
	++punit_res;
	if (res) {
		*punit_res = *res;
		dev_info(&pdev->dev, "punit GTD data res: %pR\n", res);
	}

	/* This is index 5 to cover GTD interface register, optional */
	res = platform_get_resource(pdev, IORESOURCE_MEM,
				    PLAT_RESOURCE_GTD_IFACE_INDEX);
	++punit_res;
	if (res) {
		*punit_res = *res;
		dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res);
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM,
				    PLAT_RESOURCE_IPC_INDEX);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get ipc resource\n");
		return -ENXIO;
	}
	size = PLAT_RESOURCE_IPC_SIZE;
	if (!request_mem_region(res->start, size, pdev->name)) {
		dev_err(&pdev->dev, "Failed to request ipc resource\n");
		return -EBUSY;
	}
	addr = ioremap_nocache(res->start, size);
	if (!addr) {
		dev_err(&pdev->dev, "I/O memory remapping failed\n");
		release_mem_region(res->start, size);
		return -ENOMEM;
	}
	ipcdev.ipc_base = addr;

	ipcdev.gcr_base = res->start + PLAT_RESOURCE_GCR_OFFSET;
	ipcdev.gcr_size = PLAT_RESOURCE_GCR_SIZE;
	dev_info(&pdev->dev, "ipc res: %pR\n", res);

	ipcdev.telem_res_inval = 0;
	res = platform_get_resource(pdev, IORESOURCE_MEM,
				    PLAT_RESOURCE_TELEM_SSRAM_INDEX);
	if (!res) {
		dev_err(&pdev->dev, "Failed to get telemetry ssram resource\n");
		ipcdev.telem_res_inval = 1;
	} else {
		ipcdev.telem_punit_ssram_base = res->start +
						TELEM_PUNIT_SSRAM_OFFSET;
		ipcdev.telem_punit_ssram_size = TELEM_SSRAM_SIZE;
		ipcdev.telem_pmc_ssram_base = res->start +
						TELEM_PMC_SSRAM_OFFSET;
		ipcdev.telem_pmc_ssram_size = TELEM_SSRAM_SIZE;
		dev_info(&pdev->dev, "telemetry ssram res: %pR\n", res);
	}

	return 0;
}

#ifdef CONFIG_ACPI
static const struct acpi_device_id ipc_acpi_ids[] = {
	{ "INT34D2", 0},
	{ }
};
MODULE_DEVICE_TABLE(acpi, ipc_acpi_ids);
#endif

static int ipc_plat_probe(struct platform_device *pdev)
{
	struct resource *res;
	int ret;

	ipcdev.dev = &pdev->dev;
	ipcdev.irq_mode = IPC_TRIGGER_MODE_IRQ;
	init_completion(&ipcdev.cmd_complete);

	ipcdev.irq = platform_get_irq(pdev, 0);
	if (ipcdev.irq < 0) {
		dev_err(&pdev->dev, "Failed to get irq\n");
		return -EINVAL;
	}

	ret = ipc_plat_get_res(pdev);
	if (ret) {
		dev_err(&pdev->dev, "Failed to request resource\n");
		return ret;
	}

	ret = ipc_create_pmc_devices();
	if (ret) {
		dev_err(&pdev->dev, "Failed to create pmc devices\n");
		goto err_device;
	}

	if (request_irq(ipcdev.irq, ioc, IRQF_NO_SUSPEND,
			"intel_pmc_ipc", &ipcdev)) {
		dev_err(&pdev->dev, "Failed to request irq\n");
		ret = -EBUSY;
		goto err_irq;
	}

	ret = sysfs_create_group(&pdev->dev.kobj, &intel_ipc_group);
	if (ret) {
		dev_err(&pdev->dev, "Failed to create sysfs group %d\n",
			ret);
		goto err_sys;
	}

	return 0;
err_sys:
	free_irq(ipcdev.irq, &ipcdev);
err_irq:
	platform_device_unregister(ipcdev.tco_dev);
	platform_device_unregister(ipcdev.punit_dev);
	platform_device_unregister(ipcdev.telemetry_dev);
err_device:
	iounmap(ipcdev.ipc_base);
	res = platform_get_resource(pdev, IORESOURCE_MEM,
				    PLAT_RESOURCE_IPC_INDEX);
	if (res)
		release_mem_region(res->start, PLAT_RESOURCE_IPC_SIZE);
	return ret;
}

static int ipc_plat_remove(struct platform_device *pdev)
{
	struct resource *res;

	sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group);
	free_irq(ipcdev.irq, &ipcdev);
	platform_device_unregister(ipcdev.tco_dev);
	platform_device_unregister(ipcdev.punit_dev);
	platform_device_unregister(ipcdev.telemetry_dev);
	iounmap(ipcdev.ipc_base);
	res = platform_get_resource(pdev, IORESOURCE_MEM,
				    PLAT_RESOURCE_IPC_INDEX);
	if (res)
		release_mem_region(res->start, PLAT_RESOURCE_IPC_SIZE);
	ipcdev.dev = NULL;
	return 0;
}

static struct platform_driver ipc_plat_driver = {
	.remove = ipc_plat_remove,
	.probe = ipc_plat_probe,
	.driver = {
		.name = "pmc-ipc-plat",
		.acpi_match_table = ACPI_PTR(ipc_acpi_ids),
	},
};

static int __init intel_pmc_ipc_init(void)
{
	int ret;

	ret = platform_driver_register(&ipc_plat_driver);
	if (ret) {
		pr_err("Failed to register PMC ipc platform driver\n");
		return ret;
	}
	ret = pci_register_driver(&ipc_pci_driver);
	if (ret) {
		pr_err("Failed to register PMC ipc pci driver\n");
		platform_driver_unregister(&ipc_plat_driver);
		return ret;
	}
	return ret;
}

static void __exit intel_pmc_ipc_exit(void)
{
	pci_unregister_driver(&ipc_pci_driver);
	platform_driver_unregister(&ipc_plat_driver);
}

MODULE_AUTHOR("Zha Qipeng <qipeng.zha@intel.com>");
MODULE_DESCRIPTION("Intel PMC IPC driver");
MODULE_LICENSE("GPL");

/* Some modules are dependent on this, so init earlier */
fs_initcall(intel_pmc_ipc_init);
module_exit(intel_pmc_ipc_exit);
