From: Kate Hsuan Date: Fri, 20 Aug 2021 11:04:43 +0000 (+0300) Subject: platform/x86: intel_punit_ipc: Move to intel sub-directory X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=386d17b22e422da3285e33fe8dcc282f02d98178;p=linux.git platform/x86: intel_punit_ipc: Move to intel sub-directory Move Intel P-Unit IPC driver to intel sub-directory to improve readability. Signed-off-by: Kate Hsuan Reviewed-by: Hans de Goede Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20210820110458.73018-6-andriy.shevchenko@linux.intel.com Signed-off-by: Hans de Goede --- diff --git a/MAINTAINERS b/MAINTAINERS index b731988a4452a..21813a0e00eb8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9475,7 +9475,7 @@ M: Zha Qipeng L: platform-driver-x86@vger.kernel.org S: Maintained F: arch/x86/include/asm/intel_punit_ipc.h -F: drivers/platform/x86/intel_punit_ipc.c +F: drivers/platform/x86/intel/punit_ipc.c INTEL PMC CORE DRIVER M: Rajneesh Bhardwaj diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 2d6723bb64593..9cadce7908eaa 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1180,12 +1180,6 @@ config INTEL_PMC_CORE - Low Power Mode registers (Tigerlake and beyond) - PMC quirks as needed to enable SLPS0/S0ix -config INTEL_PUNIT_IPC - tristate "Intel P-Unit IPC Driver" - help - This driver provides support for Intel P-Unit Mailbox IPC mechanism, - which is used to bridge the communications between kernel and P-Unit. - config INTEL_SCU_IPC bool diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index f70c0aa30cdd0..776370ce8fbbb 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -128,7 +128,6 @@ obj-$(CONFIG_INTEL_UNCORE_FREQ_CONTROL) += intel-uncore-frequency.o # Intel PMIC / PMC / P-Unit devices obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o intel_pmc_core_pltdrv.o -obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o obj-$(CONFIG_INTEL_SCU_PCI) += intel_scu_pcidrv.o obj-$(CONFIG_INTEL_SCU_PLATFORM) += intel_scu_pltdrv.o diff --git a/drivers/platform/x86/intel/Kconfig b/drivers/platform/x86/intel/Kconfig index 9e719db8450c1..c4ceb5ee83f33 100644 --- a/drivers/platform/x86/intel/Kconfig +++ b/drivers/platform/x86/intel/Kconfig @@ -53,4 +53,10 @@ config INTEL_MRFLD_PWRBTN To compile this driver as a module, choose M here: the module will be called intel_mrfld_pwrbtn. +config INTEL_PUNIT_IPC + tristate "Intel P-Unit IPC Driver" + help + This driver provides support for Intel P-Unit Mailbox IPC mechanism, + which is used to bridge the communications between kernel and P-Unit. + endif # X86_PLATFORM_DRIVERS_INTEL diff --git a/drivers/platform/x86/intel/Makefile b/drivers/platform/x86/intel/Makefile index 4ff755a117704..58fc8e7a3b629 100644 --- a/drivers/platform/x86/intel/Makefile +++ b/drivers/platform/x86/intel/Makefile @@ -16,3 +16,5 @@ intel_chtdc_ti_pwrbtn-y := chtdc_ti_pwrbtn.o obj-$(CONFIG_INTEL_CHTDC_TI_PWRBTN) += intel_chtdc_ti_pwrbtn.o intel_mrfld_pwrbtn-y := mrfld_pwrbtn.o obj-$(CONFIG_INTEL_MRFLD_PWRBTN) += intel_mrfld_pwrbtn.o +intel_punit_ipc-y := punit_ipc.o +obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o diff --git a/drivers/platform/x86/intel/punit_ipc.c b/drivers/platform/x86/intel/punit_ipc.c new file mode 100644 index 0000000000000..f58b8543f6ac5 --- /dev/null +++ b/drivers/platform/x86/intel/punit_ipc.c @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for the Intel P-Unit Mailbox IPC mechanism + * + * (C) Copyright 2015 Intel Corporation + * + * The heart of the P-Unit is the Foxton microcontroller and its firmware, + * which provide mailbox interface for power management usage. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* IPC Mailbox registers */ +#define OFFSET_DATA_LOW 0x0 +#define OFFSET_DATA_HIGH 0x4 +/* bit field of interface register */ +#define CMD_RUN BIT(31) +#define CMD_ERRCODE_MASK GENMASK(7, 0) +#define CMD_PARA1_SHIFT 8 +#define CMD_PARA2_SHIFT 16 + +#define CMD_TIMEOUT_SECONDS 1 + +enum { + BASE_DATA = 0, + BASE_IFACE, + BASE_MAX, +}; + +typedef struct { + struct device *dev; + struct mutex lock; + int irq; + struct completion cmd_complete; + /* base of interface and data registers */ + void __iomem *base[RESERVED_IPC][BASE_MAX]; + IPC_TYPE type; +} IPC_DEV; + +static IPC_DEV *punit_ipcdev; + +static inline u32 ipc_read_status(IPC_DEV *ipcdev, IPC_TYPE type) +{ + return readl(ipcdev->base[type][BASE_IFACE]); +} + +static inline void ipc_write_cmd(IPC_DEV *ipcdev, IPC_TYPE type, u32 cmd) +{ + writel(cmd, ipcdev->base[type][BASE_IFACE]); +} + +static inline u32 ipc_read_data_low(IPC_DEV *ipcdev, IPC_TYPE type) +{ + return readl(ipcdev->base[type][BASE_DATA] + OFFSET_DATA_LOW); +} + +static inline u32 ipc_read_data_high(IPC_DEV *ipcdev, IPC_TYPE type) +{ + return readl(ipcdev->base[type][BASE_DATA] + OFFSET_DATA_HIGH); +} + +static inline void ipc_write_data_low(IPC_DEV *ipcdev, IPC_TYPE type, u32 data) +{ + writel(data, ipcdev->base[type][BASE_DATA] + OFFSET_DATA_LOW); +} + +static inline void ipc_write_data_high(IPC_DEV *ipcdev, IPC_TYPE type, u32 data) +{ + writel(data, ipcdev->base[type][BASE_DATA] + OFFSET_DATA_HIGH); +} + +static const char *ipc_err_string(int error) +{ + if (error == IPC_PUNIT_ERR_SUCCESS) + return "no error"; + else if (error == IPC_PUNIT_ERR_INVALID_CMD) + return "invalid command"; + else if (error == IPC_PUNIT_ERR_INVALID_PARAMETER) + return "invalid parameter"; + else if (error == IPC_PUNIT_ERR_CMD_TIMEOUT) + return "command timeout"; + else if (error == IPC_PUNIT_ERR_CMD_LOCKED) + return "command locked"; + else if (error == IPC_PUNIT_ERR_INVALID_VR_ID) + return "invalid vr id"; + else if (error == IPC_PUNIT_ERR_VR_ERR) + return "vr error"; + else + return "unknown error"; +} + +static int intel_punit_ipc_check_status(IPC_DEV *ipcdev, IPC_TYPE type) +{ + int loops = CMD_TIMEOUT_SECONDS * USEC_PER_SEC; + int errcode; + int status; + + if (ipcdev->irq) { + if (!wait_for_completion_timeout(&ipcdev->cmd_complete, + CMD_TIMEOUT_SECONDS * HZ)) { + dev_err(ipcdev->dev, "IPC timed out\n"); + return -ETIMEDOUT; + } + } else { + while ((ipc_read_status(ipcdev, type) & CMD_RUN) && --loops) + udelay(1); + if (!loops) { + dev_err(ipcdev->dev, "IPC timed out\n"); + return -ETIMEDOUT; + } + } + + status = ipc_read_status(ipcdev, type); + errcode = status & CMD_ERRCODE_MASK; + if (errcode) { + dev_err(ipcdev->dev, "IPC failed: %s, IPC_STS=0x%x\n", + ipc_err_string(errcode), status); + return -EIO; + } + + return 0; +} + +/** + * intel_punit_ipc_simple_command() - Simple IPC command + * @cmd: IPC command code. + * @para1: First 8bit parameter, set 0 if not used. + * @para2: Second 8bit parameter, set 0 if not used. + * + * Send a IPC command to P-Unit when there is no data transaction + * + * Return: IPC error code or 0 on success. + */ +int intel_punit_ipc_simple_command(int cmd, int para1, int para2) +{ + IPC_DEV *ipcdev = punit_ipcdev; + IPC_TYPE type; + u32 val; + int ret; + + mutex_lock(&ipcdev->lock); + + reinit_completion(&ipcdev->cmd_complete); + type = (cmd & IPC_PUNIT_CMD_TYPE_MASK) >> IPC_TYPE_OFFSET; + + val = cmd & ~IPC_PUNIT_CMD_TYPE_MASK; + val |= CMD_RUN | para2 << CMD_PARA2_SHIFT | para1 << CMD_PARA1_SHIFT; + ipc_write_cmd(ipcdev, type, val); + ret = intel_punit_ipc_check_status(ipcdev, type); + + mutex_unlock(&ipcdev->lock); + + return ret; +} +EXPORT_SYMBOL(intel_punit_ipc_simple_command); + +/** + * intel_punit_ipc_command() - IPC command with data and pointers + * @cmd: IPC command code. + * @para1: First 8bit parameter, set 0 if not used. + * @para2: Second 8bit parameter, set 0 if not used. + * @in: Input data, 32bit for BIOS cmd, two 32bit for GTD and ISPD. + * @out: Output data. + * + * Send a IPC command to P-Unit with data transaction + * + * Return: IPC error code or 0 on success. + */ +int intel_punit_ipc_command(u32 cmd, u32 para1, u32 para2, u32 *in, u32 *out) +{ + IPC_DEV *ipcdev = punit_ipcdev; + IPC_TYPE type; + u32 val; + int ret; + + mutex_lock(&ipcdev->lock); + + reinit_completion(&ipcdev->cmd_complete); + type = (cmd & IPC_PUNIT_CMD_TYPE_MASK) >> IPC_TYPE_OFFSET; + + if (in) { + ipc_write_data_low(ipcdev, type, *in); + if (type == GTDRIVER_IPC || type == ISPDRIVER_IPC) + ipc_write_data_high(ipcdev, type, *++in); + } + + val = cmd & ~IPC_PUNIT_CMD_TYPE_MASK; + val |= CMD_RUN | para2 << CMD_PARA2_SHIFT | para1 << CMD_PARA1_SHIFT; + ipc_write_cmd(ipcdev, type, val); + + ret = intel_punit_ipc_check_status(ipcdev, type); + if (ret) + goto out; + + if (out) { + *out = ipc_read_data_low(ipcdev, type); + if (type == GTDRIVER_IPC || type == ISPDRIVER_IPC) + *++out = ipc_read_data_high(ipcdev, type); + } + +out: + mutex_unlock(&ipcdev->lock); + return ret; +} +EXPORT_SYMBOL_GPL(intel_punit_ipc_command); + +static irqreturn_t intel_punit_ioc(int irq, void *dev_id) +{ + IPC_DEV *ipcdev = dev_id; + + complete(&ipcdev->cmd_complete); + return IRQ_HANDLED; +} + +static int intel_punit_get_bars(struct platform_device *pdev) +{ + void __iomem *addr; + + /* + * The following resources are required + * - BIOS_IPC BASE_DATA + * - BIOS_IPC BASE_IFACE + */ + addr = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(addr)) + return PTR_ERR(addr); + punit_ipcdev->base[BIOS_IPC][BASE_DATA] = addr; + + addr = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(addr)) + return PTR_ERR(addr); + punit_ipcdev->base[BIOS_IPC][BASE_IFACE] = addr; + + /* + * The following resources are optional + * - ISPDRIVER_IPC BASE_DATA + * - ISPDRIVER_IPC BASE_IFACE + * - GTDRIVER_IPC BASE_DATA + * - GTDRIVER_IPC BASE_IFACE + */ + addr = devm_platform_ioremap_resource(pdev, 2); + if (!IS_ERR(addr)) + punit_ipcdev->base[ISPDRIVER_IPC][BASE_DATA] = addr; + + addr = devm_platform_ioremap_resource(pdev, 3); + if (!IS_ERR(addr)) + punit_ipcdev->base[ISPDRIVER_IPC][BASE_IFACE] = addr; + + addr = devm_platform_ioremap_resource(pdev, 4); + if (!IS_ERR(addr)) + punit_ipcdev->base[GTDRIVER_IPC][BASE_DATA] = addr; + + addr = devm_platform_ioremap_resource(pdev, 5); + if (!IS_ERR(addr)) + punit_ipcdev->base[GTDRIVER_IPC][BASE_IFACE] = addr; + + return 0; +} + +static int intel_punit_ipc_probe(struct platform_device *pdev) +{ + int irq, ret; + + punit_ipcdev = devm_kzalloc(&pdev->dev, + sizeof(*punit_ipcdev), GFP_KERNEL); + if (!punit_ipcdev) + return -ENOMEM; + + platform_set_drvdata(pdev, punit_ipcdev); + + irq = platform_get_irq_optional(pdev, 0); + if (irq < 0) { + dev_warn(&pdev->dev, "Invalid IRQ, using polling mode\n"); + } else { + ret = devm_request_irq(&pdev->dev, irq, intel_punit_ioc, + IRQF_NO_SUSPEND, "intel_punit_ipc", + &punit_ipcdev); + if (ret) { + dev_err(&pdev->dev, "Failed to request irq: %d\n", irq); + return ret; + } + punit_ipcdev->irq = irq; + } + + ret = intel_punit_get_bars(pdev); + if (ret) + return ret; + + punit_ipcdev->dev = &pdev->dev; + mutex_init(&punit_ipcdev->lock); + init_completion(&punit_ipcdev->cmd_complete); + + return 0; +} + +static int intel_punit_ipc_remove(struct platform_device *pdev) +{ + return 0; +} + +static const struct acpi_device_id punit_ipc_acpi_ids[] = { + { "INT34D4", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, punit_ipc_acpi_ids); + +static struct platform_driver intel_punit_ipc_driver = { + .probe = intel_punit_ipc_probe, + .remove = intel_punit_ipc_remove, + .driver = { + .name = "intel_punit_ipc", + .acpi_match_table = ACPI_PTR(punit_ipc_acpi_ids), + }, +}; + +static int __init intel_punit_ipc_init(void) +{ + return platform_driver_register(&intel_punit_ipc_driver); +} + +static void __exit intel_punit_ipc_exit(void) +{ + platform_driver_unregister(&intel_punit_ipc_driver); +} + +MODULE_AUTHOR("Zha Qipeng "); +MODULE_DESCRIPTION("Intel P-Unit IPC driver"); +MODULE_LICENSE("GPL v2"); + +/* Some modules are dependent on this, so init earlier */ +fs_initcall(intel_punit_ipc_init); +module_exit(intel_punit_ipc_exit); diff --git a/drivers/platform/x86/intel_punit_ipc.c b/drivers/platform/x86/intel_punit_ipc.c deleted file mode 100644 index f58b8543f6ac5..0000000000000 --- a/drivers/platform/x86/intel_punit_ipc.c +++ /dev/null @@ -1,342 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Driver for the Intel P-Unit Mailbox IPC mechanism - * - * (C) Copyright 2015 Intel Corporation - * - * The heart of the P-Unit is the Foxton microcontroller and its firmware, - * which provide mailbox interface for power management usage. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* IPC Mailbox registers */ -#define OFFSET_DATA_LOW 0x0 -#define OFFSET_DATA_HIGH 0x4 -/* bit field of interface register */ -#define CMD_RUN BIT(31) -#define CMD_ERRCODE_MASK GENMASK(7, 0) -#define CMD_PARA1_SHIFT 8 -#define CMD_PARA2_SHIFT 16 - -#define CMD_TIMEOUT_SECONDS 1 - -enum { - BASE_DATA = 0, - BASE_IFACE, - BASE_MAX, -}; - -typedef struct { - struct device *dev; - struct mutex lock; - int irq; - struct completion cmd_complete; - /* base of interface and data registers */ - void __iomem *base[RESERVED_IPC][BASE_MAX]; - IPC_TYPE type; -} IPC_DEV; - -static IPC_DEV *punit_ipcdev; - -static inline u32 ipc_read_status(IPC_DEV *ipcdev, IPC_TYPE type) -{ - return readl(ipcdev->base[type][BASE_IFACE]); -} - -static inline void ipc_write_cmd(IPC_DEV *ipcdev, IPC_TYPE type, u32 cmd) -{ - writel(cmd, ipcdev->base[type][BASE_IFACE]); -} - -static inline u32 ipc_read_data_low(IPC_DEV *ipcdev, IPC_TYPE type) -{ - return readl(ipcdev->base[type][BASE_DATA] + OFFSET_DATA_LOW); -} - -static inline u32 ipc_read_data_high(IPC_DEV *ipcdev, IPC_TYPE type) -{ - return readl(ipcdev->base[type][BASE_DATA] + OFFSET_DATA_HIGH); -} - -static inline void ipc_write_data_low(IPC_DEV *ipcdev, IPC_TYPE type, u32 data) -{ - writel(data, ipcdev->base[type][BASE_DATA] + OFFSET_DATA_LOW); -} - -static inline void ipc_write_data_high(IPC_DEV *ipcdev, IPC_TYPE type, u32 data) -{ - writel(data, ipcdev->base[type][BASE_DATA] + OFFSET_DATA_HIGH); -} - -static const char *ipc_err_string(int error) -{ - if (error == IPC_PUNIT_ERR_SUCCESS) - return "no error"; - else if (error == IPC_PUNIT_ERR_INVALID_CMD) - return "invalid command"; - else if (error == IPC_PUNIT_ERR_INVALID_PARAMETER) - return "invalid parameter"; - else if (error == IPC_PUNIT_ERR_CMD_TIMEOUT) - return "command timeout"; - else if (error == IPC_PUNIT_ERR_CMD_LOCKED) - return "command locked"; - else if (error == IPC_PUNIT_ERR_INVALID_VR_ID) - return "invalid vr id"; - else if (error == IPC_PUNIT_ERR_VR_ERR) - return "vr error"; - else - return "unknown error"; -} - -static int intel_punit_ipc_check_status(IPC_DEV *ipcdev, IPC_TYPE type) -{ - int loops = CMD_TIMEOUT_SECONDS * USEC_PER_SEC; - int errcode; - int status; - - if (ipcdev->irq) { - if (!wait_for_completion_timeout(&ipcdev->cmd_complete, - CMD_TIMEOUT_SECONDS * HZ)) { - dev_err(ipcdev->dev, "IPC timed out\n"); - return -ETIMEDOUT; - } - } else { - while ((ipc_read_status(ipcdev, type) & CMD_RUN) && --loops) - udelay(1); - if (!loops) { - dev_err(ipcdev->dev, "IPC timed out\n"); - return -ETIMEDOUT; - } - } - - status = ipc_read_status(ipcdev, type); - errcode = status & CMD_ERRCODE_MASK; - if (errcode) { - dev_err(ipcdev->dev, "IPC failed: %s, IPC_STS=0x%x\n", - ipc_err_string(errcode), status); - return -EIO; - } - - return 0; -} - -/** - * intel_punit_ipc_simple_command() - Simple IPC command - * @cmd: IPC command code. - * @para1: First 8bit parameter, set 0 if not used. - * @para2: Second 8bit parameter, set 0 if not used. - * - * Send a IPC command to P-Unit when there is no data transaction - * - * Return: IPC error code or 0 on success. - */ -int intel_punit_ipc_simple_command(int cmd, int para1, int para2) -{ - IPC_DEV *ipcdev = punit_ipcdev; - IPC_TYPE type; - u32 val; - int ret; - - mutex_lock(&ipcdev->lock); - - reinit_completion(&ipcdev->cmd_complete); - type = (cmd & IPC_PUNIT_CMD_TYPE_MASK) >> IPC_TYPE_OFFSET; - - val = cmd & ~IPC_PUNIT_CMD_TYPE_MASK; - val |= CMD_RUN | para2 << CMD_PARA2_SHIFT | para1 << CMD_PARA1_SHIFT; - ipc_write_cmd(ipcdev, type, val); - ret = intel_punit_ipc_check_status(ipcdev, type); - - mutex_unlock(&ipcdev->lock); - - return ret; -} -EXPORT_SYMBOL(intel_punit_ipc_simple_command); - -/** - * intel_punit_ipc_command() - IPC command with data and pointers - * @cmd: IPC command code. - * @para1: First 8bit parameter, set 0 if not used. - * @para2: Second 8bit parameter, set 0 if not used. - * @in: Input data, 32bit for BIOS cmd, two 32bit for GTD and ISPD. - * @out: Output data. - * - * Send a IPC command to P-Unit with data transaction - * - * Return: IPC error code or 0 on success. - */ -int intel_punit_ipc_command(u32 cmd, u32 para1, u32 para2, u32 *in, u32 *out) -{ - IPC_DEV *ipcdev = punit_ipcdev; - IPC_TYPE type; - u32 val; - int ret; - - mutex_lock(&ipcdev->lock); - - reinit_completion(&ipcdev->cmd_complete); - type = (cmd & IPC_PUNIT_CMD_TYPE_MASK) >> IPC_TYPE_OFFSET; - - if (in) { - ipc_write_data_low(ipcdev, type, *in); - if (type == GTDRIVER_IPC || type == ISPDRIVER_IPC) - ipc_write_data_high(ipcdev, type, *++in); - } - - val = cmd & ~IPC_PUNIT_CMD_TYPE_MASK; - val |= CMD_RUN | para2 << CMD_PARA2_SHIFT | para1 << CMD_PARA1_SHIFT; - ipc_write_cmd(ipcdev, type, val); - - ret = intel_punit_ipc_check_status(ipcdev, type); - if (ret) - goto out; - - if (out) { - *out = ipc_read_data_low(ipcdev, type); - if (type == GTDRIVER_IPC || type == ISPDRIVER_IPC) - *++out = ipc_read_data_high(ipcdev, type); - } - -out: - mutex_unlock(&ipcdev->lock); - return ret; -} -EXPORT_SYMBOL_GPL(intel_punit_ipc_command); - -static irqreturn_t intel_punit_ioc(int irq, void *dev_id) -{ - IPC_DEV *ipcdev = dev_id; - - complete(&ipcdev->cmd_complete); - return IRQ_HANDLED; -} - -static int intel_punit_get_bars(struct platform_device *pdev) -{ - void __iomem *addr; - - /* - * The following resources are required - * - BIOS_IPC BASE_DATA - * - BIOS_IPC BASE_IFACE - */ - addr = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(addr)) - return PTR_ERR(addr); - punit_ipcdev->base[BIOS_IPC][BASE_DATA] = addr; - - addr = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(addr)) - return PTR_ERR(addr); - punit_ipcdev->base[BIOS_IPC][BASE_IFACE] = addr; - - /* - * The following resources are optional - * - ISPDRIVER_IPC BASE_DATA - * - ISPDRIVER_IPC BASE_IFACE - * - GTDRIVER_IPC BASE_DATA - * - GTDRIVER_IPC BASE_IFACE - */ - addr = devm_platform_ioremap_resource(pdev, 2); - if (!IS_ERR(addr)) - punit_ipcdev->base[ISPDRIVER_IPC][BASE_DATA] = addr; - - addr = devm_platform_ioremap_resource(pdev, 3); - if (!IS_ERR(addr)) - punit_ipcdev->base[ISPDRIVER_IPC][BASE_IFACE] = addr; - - addr = devm_platform_ioremap_resource(pdev, 4); - if (!IS_ERR(addr)) - punit_ipcdev->base[GTDRIVER_IPC][BASE_DATA] = addr; - - addr = devm_platform_ioremap_resource(pdev, 5); - if (!IS_ERR(addr)) - punit_ipcdev->base[GTDRIVER_IPC][BASE_IFACE] = addr; - - return 0; -} - -static int intel_punit_ipc_probe(struct platform_device *pdev) -{ - int irq, ret; - - punit_ipcdev = devm_kzalloc(&pdev->dev, - sizeof(*punit_ipcdev), GFP_KERNEL); - if (!punit_ipcdev) - return -ENOMEM; - - platform_set_drvdata(pdev, punit_ipcdev); - - irq = platform_get_irq_optional(pdev, 0); - if (irq < 0) { - dev_warn(&pdev->dev, "Invalid IRQ, using polling mode\n"); - } else { - ret = devm_request_irq(&pdev->dev, irq, intel_punit_ioc, - IRQF_NO_SUSPEND, "intel_punit_ipc", - &punit_ipcdev); - if (ret) { - dev_err(&pdev->dev, "Failed to request irq: %d\n", irq); - return ret; - } - punit_ipcdev->irq = irq; - } - - ret = intel_punit_get_bars(pdev); - if (ret) - return ret; - - punit_ipcdev->dev = &pdev->dev; - mutex_init(&punit_ipcdev->lock); - init_completion(&punit_ipcdev->cmd_complete); - - return 0; -} - -static int intel_punit_ipc_remove(struct platform_device *pdev) -{ - return 0; -} - -static const struct acpi_device_id punit_ipc_acpi_ids[] = { - { "INT34D4", 0 }, - { } -}; -MODULE_DEVICE_TABLE(acpi, punit_ipc_acpi_ids); - -static struct platform_driver intel_punit_ipc_driver = { - .probe = intel_punit_ipc_probe, - .remove = intel_punit_ipc_remove, - .driver = { - .name = "intel_punit_ipc", - .acpi_match_table = ACPI_PTR(punit_ipc_acpi_ids), - }, -}; - -static int __init intel_punit_ipc_init(void) -{ - return platform_driver_register(&intel_punit_ipc_driver); -} - -static void __exit intel_punit_ipc_exit(void) -{ - platform_driver_unregister(&intel_punit_ipc_driver); -} - -MODULE_AUTHOR("Zha Qipeng "); -MODULE_DESCRIPTION("Intel P-Unit IPC driver"); -MODULE_LICENSE("GPL v2"); - -/* Some modules are dependent on this, so init earlier */ -fs_initcall(intel_punit_ipc_init); -module_exit(intel_punit_ipc_exit);