On Wed, Jan 08, 2020 at 02:41:59PM +0300, Mika Westerberg wrote: > This driver only creates a bunch of platform devices sharing resources > belonging to the PMC device. This is pretty much what MFD subsystem is > for so move the driver there, renaming it to intel_pmc_bxt.c which > should be more clear what it is. > > MFD subsystem provides nice helper APIs for subdevice creation so > convert the driver to use those. Unfortunately the ACPI device includes > separate resources for most of the subdevices so we cannot simply call > mfd_add_devices() to create all of them but instead we need to call it > separately for each device. Comments below, after addressing, Reviewed-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> > > Signed-off-by: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx> > --- > drivers/mfd/Kconfig | 14 +- > drivers/mfd/Makefile | 1 + > .../intel_pmc_ipc.c => mfd/intel_pmc_bxt.c} | 394 +++++++----------- > drivers/platform/x86/Kconfig | 16 +- > drivers/platform/x86/Makefile | 1 - > .../platform/x86/intel_telemetry_debugfs.c | 2 +- > drivers/usb/typec/tcpm/Kconfig | 2 +- > .../linux/mfd/intel_pmc_bxt.h | 11 +- > 8 files changed, 171 insertions(+), 270 deletions(-) > rename drivers/{platform/x86/intel_pmc_ipc.c => mfd/intel_pmc_bxt.c} (50%) > rename arch/x86/include/asm/intel_pmc_ipc.h => include/linux/mfd/intel_pmc_bxt.h (83%) > > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig > index 59515142438e..04542feffe25 100644 > --- a/drivers/mfd/Kconfig > +++ b/drivers/mfd/Kconfig > @@ -551,7 +551,7 @@ config INTEL_SOC_PMIC > > config INTEL_SOC_PMIC_BXTWC > tristate "Support for Intel Broxton Whiskey Cove PMIC" > - depends on INTEL_PMC_IPC > + depends on MFD_INTEL_PMC_BXT > select MFD_CORE > select REGMAP_IRQ > help > @@ -632,6 +632,18 @@ config MFD_INTEL_MSIC > Passage) chip. This chip embeds audio, battery, GPIO, etc. > devices used in Intel Medfield platforms. > > +config MFD_INTEL_PMC_BXT > + tristate "Intel PMC Driver for Broxton" > + depends on X86 && X86_PLATFORM_DEVICES && ACPI Is the X86_PLATFORM_DEVICES dependency compulsory? Quick grep shows that none of drivers (except nouveau) relies on it. For the rest two I think we might split one per line to be consistent with existing example(s) in drivers/mfd/Kconfig. > + select INTEL_SCU_IPC > + select MFD_CORE > + help > + This driver provides support for PMC (Power Management > + Controller) on Intel Broxton and Apollo Lake. PMC is a > + multi-function device that exposes IPC, General Control > + Register and P-unit access. In addition this creates devices > + for iTCO watchdog and telemetry that are part of the PMC. > + > config MFD_IPAQ_MICRO > bool "Atmel Micro ASIC (iPAQ h3100/h3600/h3700) Support" > depends on SA1100_H3100 || SA1100_H3600 > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile > index aed99f08739f..34563a6a047b 100644 > --- a/drivers/mfd/Makefile > +++ b/drivers/mfd/Makefile > @@ -211,6 +211,7 @@ obj-$(CONFIG_MFD_INTEL_LPSS) += intel-lpss.o > obj-$(CONFIG_MFD_INTEL_LPSS_PCI) += intel-lpss-pci.o > obj-$(CONFIG_MFD_INTEL_LPSS_ACPI) += intel-lpss-acpi.o > obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o > +obj-$(CONFIG_MFD_INTEL_PMC_BXT) += intel_pmc_bxt.o > obj-$(CONFIG_MFD_PALMAS) += palmas.o > obj-$(CONFIG_MFD_VIPERBOARD) += viperboard.o > obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o > diff --git a/drivers/platform/x86/intel_pmc_ipc.c b/drivers/mfd/intel_pmc_bxt.c > similarity index 50% > rename from drivers/platform/x86/intel_pmc_ipc.c > rename to drivers/mfd/intel_pmc_bxt.c > index 20a4bb72aeac..76f166c1455b 100644 > --- a/drivers/platform/x86/intel_pmc_ipc.c > +++ b/drivers/mfd/intel_pmc_bxt.c > @@ -1,8 +1,8 @@ > // SPDX-License-Identifier: GPL-2.0 > /* > - * Driver for the Intel PMC IPC mechanism > + * Driver for the Intel Broxton PMC > * > - * (C) Copyright 2014-2015 Intel Corporation > + * (C) Copyright 2014-2015, 2020 Intel Corporation > * > * This driver is based on Intel SCU IPC driver(intel_scu_ipc.c) by > * Sreedhara DS <sreedhara.ds@xxxxxxxxx> > @@ -16,10 +16,11 @@ > #include <linux/errno.h> > #include <linux/interrupt.h> > #include <linux/io-64-nonatomic-lo-hi.h> > +#include <linux/mfd/core.h> > +#include <linux/mfd/intel_pmc_bxt.h> > #include <linux/module.h> > #include <linux/platform_device.h> > > -#include <asm/intel_pmc_ipc.h> > #include <asm/intel_scu_ipc.h> > > #include <linux/platform_data/itco_wdt.h> > @@ -62,8 +63,6 @@ > #define TELEM_SSRAM_SIZE 240 > #define TELEM_PMC_SSRAM_OFFSET 0x1B00 > #define TELEM_PUNIT_SSRAM_OFFSET 0x1A00 > -#define TCO_PMC_OFFSET 0x08 > -#define TCO_PMC_SIZE 0x04 > > /* PMC register bit definitions */ > > @@ -72,40 +71,32 @@ > #define PMC_CFG_NO_REBOOT_EN (1 << 4) > #define PMC_CFG_NO_REBOOT_DIS (0 << 4) > > -static struct intel_pmc_ipc_dev { > +static struct intel_pmc_dev { > struct device *dev; > > - /* 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; > + /* iTCO */ > + struct resource tco_res[2]; > > /* gcr */ > void __iomem *gcr_mem_base; > - bool has_gcr_regs; > spinlock_t gcr_lock; > > /* punit */ > - struct platform_device *punit_dev; > + struct resource punit_res[6]; > unsigned int punit_res_count; > > /* 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; > + struct resource *telem_base; > +} pmcdev; > > static inline u64 gcr_data_readq(u32 offset) > { > - return readq(ipcdev.gcr_mem_base + offset); > + return readq(pmcdev.gcr_mem_base + offset); > } > > static inline int is_gcr_valid(u32 offset) > { > - if (!ipcdev.has_gcr_regs) > + if (!pmcdev.gcr_mem_base) > return -EACCES; > > if (offset > PLAT_RESOURCE_GCR_SIZE) > @@ -127,17 +118,17 @@ int intel_pmc_gcr_read64(u32 offset, u64 *data) > { > int ret; > > - spin_lock(&ipcdev.gcr_lock); > + spin_lock(&pmcdev.gcr_lock); > > ret = is_gcr_valid(offset); > if (ret < 0) { > - spin_unlock(&ipcdev.gcr_lock); > + spin_unlock(&pmcdev.gcr_lock); > return ret; > } > > - *data = readq(ipcdev.gcr_mem_base + offset); > + *data = readq(pmcdev.gcr_mem_base + offset); > > - spin_unlock(&ipcdev.gcr_lock); > + spin_unlock(&pmcdev.gcr_lock); > > return 0; > } > @@ -159,29 +150,29 @@ static int intel_pmc_gcr_update(u32 offset, u32 mask, u32 val) > u32 new_val; > int ret = 0; > > - spin_lock(&ipcdev.gcr_lock); > + spin_lock(&pmcdev.gcr_lock); > > ret = is_gcr_valid(offset); > if (ret < 0) > - goto gcr_ipc_unlock; > + goto gcr_unlock; > > - new_val = readl(ipcdev.gcr_mem_base + offset); > + new_val = readl(pmcdev.gcr_mem_base + offset); > > new_val &= ~mask; > new_val |= val & mask; > > - writel(new_val, ipcdev.gcr_mem_base + offset); > + writel(new_val, pmcdev.gcr_mem_base + offset); > > - new_val = readl(ipcdev.gcr_mem_base + offset); > + new_val = readl(pmcdev.gcr_mem_base + offset); > > /* check whether the bit update is successful */ > if ((new_val & mask) != (val & mask)) { > ret = -EIO; > - goto gcr_ipc_unlock; > + goto gcr_unlock; > } > > -gcr_ipc_unlock: > - spin_unlock(&ipcdev.gcr_lock); > +gcr_unlock: > + spin_unlock(&pmcdev.gcr_lock); > return ret; > } > > @@ -193,9 +184,9 @@ static int update_no_reboot_bit(void *priv, bool set) > PMC_CFG_NO_REBOOT_MASK, value); > } > > -static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev, > - struct device_attribute *attr, > - const char *buf, size_t count) > +static ssize_t intel_pmc_simple_cmd_store(struct device *dev, > + struct device_attribute *attr, > + const char *buf, size_t count) > { > struct intel_scu_ipc_dev *scu = dev_get_drvdata(dev); > int subcmd; > @@ -215,11 +206,11 @@ static ssize_t intel_pmc_ipc_simple_cmd_store(struct device *dev, > } > return (ssize_t)count; > } > -static DEVICE_ATTR(simplecmd, 0200, NULL, intel_pmc_ipc_simple_cmd_store); > +static DEVICE_ATTR(simplecmd, 0200, NULL, intel_pmc_simple_cmd_store); > > -static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev, > - struct device_attribute *attr, > - const char *buf, size_t count) > +static ssize_t intel_pmc_northpeak_store(struct device *dev, > + struct device_attribute *attr, > + const char *buf, size_t count) > { > struct intel_scu_ipc_dev *scu = dev_get_drvdata(dev); > unsigned long val; > @@ -241,264 +232,183 @@ static ssize_t intel_pmc_ipc_northpeak_store(struct device *dev, > } > return (ssize_t)count; > } > -static DEVICE_ATTR(northpeak, 0200, NULL, intel_pmc_ipc_northpeak_store); > +static DEVICE_ATTR(northpeak, 0200, NULL, intel_pmc_northpeak_store); > > -static struct attribute *intel_ipc_attrs[] = { > +static struct attribute *intel_pmc_attrs[] = { > &dev_attr_northpeak.attr, > &dev_attr_simplecmd.attr, > NULL > }; > > -static const struct attribute_group intel_ipc_group = { > - .attrs = intel_ipc_attrs, > +static const struct attribute_group intel_pmc_group = { > + .attrs = intel_pmc_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, > - }, > -}; > - > -static struct itco_wdt_platform_data tco_info = { > - .name = "Apollo Lake SoC", > - .version = 5, > - .no_reboot_priv = &ipcdev, > - .update_no_reboot_bit = update_no_reboot_bit, > -}; > - > -#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) > +static int pmc_create_punit_device(void) > { > - struct platform_device *pdev; > - const struct platform_device_info pdevinfo = { > - .parent = ipcdev.dev, > + struct mfd_cell punit = { > .name = PUNIT_DEVICE_NAME, > - .id = -1, > - .res = punit_res_array, > - .num_res = ipcdev.punit_res_count, > - }; > + .resources = pmcdev.punit_res, > + .num_resources = pmcdev.punit_res_count, > + }; > > - pdev = platform_device_register_full(&pdevinfo); > - if (IS_ERR(pdev)) > - return PTR_ERR(pdev); > + if (!pmcdev.punit_res_count) > + return 0; > > - ipcdev.punit_dev = pdev; > - > - return 0; > + return devm_mfd_add_devices(pmcdev.dev, PLATFORM_DEVID_AUTO, &punit, 1, > + NULL, 0, NULL); > } > > -static int ipc_create_tco_device(void) > +static int pmc_create_tco_device(void) > { > - struct platform_device *pdev; > - struct resource *res; > - const struct platform_device_info pdevinfo = { > - .parent = ipcdev.dev, > + struct itco_wdt_platform_data tco_info = { > + .name = "Apollo Lake SoC", > + .version = 5, > + .no_reboot_priv = &pmcdev, > + .update_no_reboot_bit = update_no_reboot_bit, > + }; > + struct mfd_cell tco = { > .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; > - > - pdev = platform_device_register_full(&pdevinfo); > - if (IS_ERR(pdev)) > - return PTR_ERR(pdev); > - > - ipcdev.tco_dev = pdev; > - > - return 0; > + .ignore_resource_conflicts = true, > + .platform_data = &tco_info, > + .pdata_size = sizeof(tco_info), > + .resources = pmcdev.tco_res, > + .num_resources = ARRAY_SIZE(pmcdev.tco_res), > + }; > + > + if (!pmcdev.tco_res[0].start) > + return 0; > + > + return devm_mfd_add_devices(pmcdev.dev, PLATFORM_DEVID_AUTO, &tco, 1, > + NULL, 0, NULL); > } > > -static int ipc_create_telemetry_device(void) > +static int pmc_create_telemetry_device(void) > { > - struct platform_device *pdev; > - struct resource *res; > - const struct platform_device_info pdevinfo = { > - .parent = ipcdev.dev, > + struct resource telem_res[] = { > + DEFINE_RES_MEM(TELEM_PUNIT_SSRAM_OFFSET, TELEM_SSRAM_SIZE), > + DEFINE_RES_MEM(TELEM_PMC_SSRAM_OFFSET, TELEM_SSRAM_SIZE), > + }; > + struct mfd_cell telem = { > .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; > + .resources = telem_res, > + .num_resources = ARRAY_SIZE(telem_res), > + }; > > - res = telemetry_res + TELEMETRY_RESOURCE_PMC_SSRAM; > - res->start = ipcdev.telem_pmc_ssram_base; > - res->end = res->start + ipcdev.telem_pmc_ssram_size - 1; > + if (!pmcdev.telem_base) > + return 0; > > - pdev = platform_device_register_full(&pdevinfo); > - if (IS_ERR(pdev)) > - return PTR_ERR(pdev); > - > - ipcdev.telemetry_dev = pdev; > - > - return 0; > + return devm_mfd_add_devices(pmcdev.dev, PLATFORM_DEVID_AUTO, &telem, 1, > + pmcdev.telem_base, 0, NULL); > } > > -static int ipc_create_pmc_devices(void) > +static int pmc_create_devices(void) > { > int ret; > > /* If we have ACPI based watchdog use that instead */ > if (!acpi_has_watchdog()) { > - ret = ipc_create_tco_device(); > + ret = pmc_create_tco_device(); > if (ret) { > - dev_err(ipcdev.dev, "Failed to add tco platform device\n"); > + dev_err(pmcdev.dev, "Failed to add tco platform device\n"); > return ret; > } > } > > - ret = ipc_create_punit_device(); > + ret = pmc_create_punit_device(); > if (ret) { > - dev_err(ipcdev.dev, "Failed to add punit platform device\n"); > - platform_device_unregister(ipcdev.tco_dev); > + dev_err(pmcdev.dev, "Failed to add punit platform device\n"); > return ret; > } > > - if (!ipcdev.telem_res_inval) { > - ret = ipc_create_telemetry_device(); > - if (ret) { > - dev_warn(ipcdev.dev, > - "Failed to add telemetry platform device\n"); > - platform_device_unregister(ipcdev.punit_dev); > - platform_device_unregister(ipcdev.tco_dev); > - } > - } > + ret = pmc_create_telemetry_device(); > + if (ret) > + dev_warn(pmcdev.dev, "Failed to add telemetry platform device\n"); > > return ret; > } > > -static int ipc_plat_get_res(struct platform_device *pdev, > +static int pmc_plat_get_res(struct platform_device *pdev, > struct intel_scu_ipc_pdata *pdata) > { > - struct resource *res, *punit_res = punit_res_array; > + struct resource *res, *punit_res = pmcdev.punit_res; > + struct resource *tco_res = pmcdev.tco_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"); > + 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); > + tco_res[0].flags = IORESOURCE_IO; > + tco_res[0].start = res->start + TCO_BASE_OFFSET; > + tco_res[0].end = tco_res[0].start + TCO_REGS_SIZE - 1; > + tco_res[1].flags = IORESOURCE_IO; > + tco_res[1].start = res->start + SMI_EN_OFFSET; > + tco_res[1].end = tco_res[1].start + SMI_EN_SIZE - 1; > + dev_dbg(&pdev->dev, "IO: %pR\n", res); > > - ipcdev.punit_res_count = 0; > + pmcdev.punit_res_count = 0; > > /* 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"); > + dev_err(&pdev->dev, "Failed to get res of P-unit BIOS data\n"); > return -ENXIO; > } > - punit_res[ipcdev.punit_res_count++] = *res; > - dev_info(&pdev->dev, "punit BIOS data res: %pR\n", res); > + punit_res[pmcdev.punit_res_count++] = *res; > + dev_dbg(&pdev->dev, "P-unit BIOS data: %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"); > + dev_err(&pdev->dev, "Failed to get res of P-unit BIOS iface\n"); > return -ENXIO; > } > - punit_res[ipcdev.punit_res_count++] = *res; > - dev_info(&pdev->dev, "punit BIOS interface res: %pR\n", res); > + punit_res[pmcdev.punit_res_count++] = *res; > + dev_dbg(&pdev->dev, "P-unit BIOS interface: %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); > if (res) { > - punit_res[ipcdev.punit_res_count++] = *res; > - dev_info(&pdev->dev, "punit ISP data res: %pR\n", res); > + punit_res[pmcdev.punit_res_count++] = *res; > + dev_dbg(&pdev->dev, "P-unit ISP data: %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); > if (res) { > - punit_res[ipcdev.punit_res_count++] = *res; > - dev_info(&pdev->dev, "punit ISP interface res: %pR\n", res); > + punit_res[pmcdev.punit_res_count++] = *res; > + dev_dbg(&pdev->dev, "P-unit ISP interface: %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); > if (res) { > - punit_res[ipcdev.punit_res_count++] = *res; > - dev_info(&pdev->dev, "punit GTD data res: %pR\n", res); > + punit_res[pmcdev.punit_res_count++] = *res; > + dev_dbg(&pdev->dev, "P-unit GTD data: %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); > if (res) { > - punit_res[ipcdev.punit_res_count++] = *res; > - dev_info(&pdev->dev, "punit GTD interface res: %pR\n", res); > + punit_res[pmcdev.punit_res_count++] = *res; > + dev_dbg(&pdev->dev, "P-unit GTD interface: %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"); > + dev_err(&pdev->dev, "Failed to get IPC resource\n"); > return -ENXIO; > } > size = PLAT_RESOURCE_IPC_SIZE + PLAT_RESOURCE_GCR_SIZE; > @@ -510,23 +420,16 @@ static int ipc_plat_get_res(struct platform_device *pdev, > > pdata->ipc_regs = addr; > > - ipcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET; > - dev_info(&pdev->dev, "ipc res: %pR\n", res); > + pmcdev.gcr_mem_base = addr + PLAT_RESOURCE_GCR_OFFSET; > + dev_dbg(&pdev->dev, "IPC: %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; > + dev_err(&pdev->dev, "Failed to get telemetry SSRAM resource\n"); > } 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); > + dev_dbg(&pdev->dev, "Telemetry SSRAM: %pR\n", res); > + pmcdev.telem_base = res; > } > > return 0; > @@ -542,7 +445,7 @@ int intel_pmc_s0ix_counter_read(u64 *data) > { > u64 deep, shlw; > > - if (!ipcdev.has_gcr_regs) > + if (!pmcdev.gcr_mem_base) > return -EACCES; > > deep = gcr_data_readq(PMC_GCR_TELEM_DEEP_S0IX_REG); > @@ -554,15 +457,13 @@ int intel_pmc_s0ix_counter_read(u64 *data) > } > EXPORT_SYMBOL_GPL(intel_pmc_s0ix_counter_read); > > -#ifdef CONFIG_ACPI > -static const struct acpi_device_id ipc_acpi_ids[] = { > +static const struct acpi_device_id intel_pmc_acpi_ids[] = { > { "INT34D2", 0}, > { } > }; > -MODULE_DEVICE_TABLE(acpi, ipc_acpi_ids); > -#endif > +MODULE_DEVICE_TABLE(acpi, intel_pmc_acpi_ids); > > -static int ipc_plat_probe(struct platform_device *pdev) > +static int intel_pmc_probe(struct platform_device *pdev) > { > struct intel_scu_ipc_pdata pdata; > struct intel_scu_ipc_dev *scu; > @@ -573,10 +474,10 @@ static int ipc_plat_probe(struct platform_device *pdev) > if (pdata.irq < 0) > return -EINVAL; > > - ipcdev.dev = &pdev->dev; > - spin_lock_init(&ipcdev.gcr_lock); > + pmcdev.dev = &pdev->dev; > + spin_lock_init(&pmcdev.gcr_lock); > > - ret = ipc_plat_get_res(pdev, &pdata); > + ret = pmc_plat_get_res(pdev, &pdata); > if (ret) { > dev_err(&pdev->dev, "Failed to request resource\n"); > return ret; > @@ -588,67 +489,58 @@ static int ipc_plat_probe(struct platform_device *pdev) > > platform_set_drvdata(pdev, scu); > > - ret = ipc_create_pmc_devices(); > + ret = pmc_create_devices(); > if (ret) { > dev_err(&pdev->dev, "Failed to create pmc devices\n"); > goto err_ipc; > } > > - ret = sysfs_create_group(&pdev->dev.kobj, &intel_ipc_group); > + ret = sysfs_create_group(&pdev->dev.kobj, &intel_pmc_group); > if (ret) { > dev_err(&pdev->dev, "Failed to create sysfs group %d\n", > ret); > - goto err_devs; > + goto err_ipc; > } > > - ipcdev.has_gcr_regs = true; > - > return 0; > > err_ipc: > intel_scu_ipc_remove(scu); > -err_devs: > - platform_device_unregister(ipcdev.tco_dev); > - platform_device_unregister(ipcdev.punit_dev); > - platform_device_unregister(ipcdev.telemetry_dev); > > return ret; > } > > -static int ipc_plat_remove(struct platform_device *pdev) > +static int intel_pmc_remove(struct platform_device *pdev) > { > - sysfs_remove_group(&pdev->dev.kobj, &intel_ipc_group); > - platform_device_unregister(ipcdev.tco_dev); > - platform_device_unregister(ipcdev.punit_dev); > - platform_device_unregister(ipcdev.telemetry_dev); > + sysfs_remove_group(&pdev->dev.kobj, &intel_pmc_group); > intel_scu_ipc_remove(platform_get_drvdata(pdev)); > - ipcdev.dev = NULL; > + pmcdev.dev = NULL; > return 0; > } > > -static struct platform_driver ipc_plat_driver = { > - .remove = ipc_plat_remove, > - .probe = ipc_plat_probe, > +static struct platform_driver intel_pmc_driver = { > + .remove = intel_pmc_remove, > + .probe = intel_pmc_probe, > .driver = { > - .name = "pmc-ipc-plat", > - .acpi_match_table = ACPI_PTR(ipc_acpi_ids), > + .name = "intel_pmc_bxt", > + .acpi_match_table = ACPI_PTR(intel_pmc_acpi_ids), > }, > }; > > -static int __init intel_pmc_ipc_init(void) > +static int __init intel_pmc_init(void) > { > - return platform_driver_register(&ipc_plat_driver); > + return platform_driver_register(&intel_pmc_driver); > } > > -static void __exit intel_pmc_ipc_exit(void) > +static void __exit intel_pmc_exit(void) > { > - platform_driver_unregister(&ipc_plat_driver); > + platform_driver_unregister(&intel_pmc_driver); > } > > MODULE_AUTHOR("Zha Qipeng <qipeng.zha@xxxxxxxxx>"); > -MODULE_DESCRIPTION("Intel PMC IPC driver"); > +MODULE_DESCRIPTION("Intel Broxton PMC driver"); > MODULE_LICENSE("GPL v2"); > > /* Some modules are dependent on this, so init earlier */ > -fs_initcall(intel_pmc_ipc_init); > -module_exit(intel_pmc_ipc_exit); > +fs_initcall(intel_pmc_init); > +module_exit(intel_pmc_exit); > diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig > index 1c5afb9e4965..e01aba797656 100644 > --- a/drivers/platform/x86/Kconfig > +++ b/drivers/platform/x86/Kconfig > @@ -1195,19 +1195,11 @@ config INTEL_SMARTCONNECT > This driver checks to determine whether the device has Intel Smart > Connect enabled, and if so disables it. > > -config INTEL_PMC_IPC > - tristate "Intel PMC IPC Driver" > - depends on ACPI > - select INTEL_SCU_IPC > - ---help--- > - This driver provides support for PMC control on some Intel platforms. > - The PMC is an ARC processor which defines IPC commands for communication > - with other entities in the CPU. > - > config INTEL_BXTWC_PMIC_TMU > tristate "Intel BXT Whiskey Cove TMU Driver" > depends on REGMAP > - depends on INTEL_SOC_PMIC_BXTWC && INTEL_PMC_IPC > + depends on MFD_INTEL_PMC_BXT > + depends on INTEL_SOC_PMIC_BXTWC > ---help--- > Select this driver to use Intel BXT Whiskey Cove PMIC TMU feature. > This driver enables the alarm wakeup functionality in the TMU unit > @@ -1233,7 +1225,9 @@ config INTEL_PUNIT_IPC > > config INTEL_TELEMETRY > tristate "Intel SoC Telemetry Driver" > - depends on INTEL_PMC_IPC && INTEL_PUNIT_IPC && X86_64 > + depends on X86_64 > + depends on MFD_INTEL_PMC_BXT > + depends on INTEL_PUNIT_IPC > ---help--- > This driver provides interfaces to configure and use > telemetry for INTEL SoC from APL onwards. It is also > diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile > index c7a42feaa521..f1abce3e1720 100644 > --- a/drivers/platform/x86/Makefile > +++ b/drivers/platform/x86/Makefile > @@ -86,7 +86,6 @@ obj-$(CONFIG_INTEL_RST) += intel-rst.o > obj-$(CONFIG_INTEL_SMARTCONNECT) += intel-smartconnect.o > > obj-$(CONFIG_ALIENWARE_WMI) += alienware-wmi.o > -obj-$(CONFIG_INTEL_PMC_IPC) += intel_pmc_ipc.o > obj-$(CONFIG_TOUCHSCREEN_DMI) += touchscreen_dmi.o > obj-$(CONFIG_SURFACE_PRO3_BUTTON) += surfacepro3_button.o > obj-$(CONFIG_SURFACE_3_BUTTON) += surface3_button.o > diff --git a/drivers/platform/x86/intel_telemetry_debugfs.c b/drivers/platform/x86/intel_telemetry_debugfs.c > index e84d3e983e0c..7b7a766a6cb8 100644 > --- a/drivers/platform/x86/intel_telemetry_debugfs.c > +++ b/drivers/platform/x86/intel_telemetry_debugfs.c > @@ -16,13 +16,13 @@ > #include <linux/debugfs.h> > #include <linux/device.h> > #include <linux/module.h> > +#include <linux/mfd/intel_pmc_bxt.h> > #include <linux/pci.h> > #include <linux/seq_file.h> > #include <linux/suspend.h> > > #include <asm/cpu_device_id.h> > #include <asm/intel-family.h> > -#include <asm/intel_pmc_ipc.h> > #include <asm/intel_telemetry.h> > > #define DRIVER_NAME "telemetry_soc_debugfs" > diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig > index 5b986d6c801d..fa3f39336246 100644 > --- a/drivers/usb/typec/tcpm/Kconfig > +++ b/drivers/usb/typec/tcpm/Kconfig > @@ -41,8 +41,8 @@ config TYPEC_FUSB302 > config TYPEC_WCOVE > tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver" > depends on ACPI > + depends on MFD_INTEL_PMC_BXT > depends on INTEL_SOC_PMIC > - depends on INTEL_PMC_IPC > depends on BXT_WC_PMIC_OPREGION > help > This driver adds support for USB Type-C on Intel Broxton platforms > diff --git a/arch/x86/include/asm/intel_pmc_ipc.h b/include/linux/mfd/intel_pmc_bxt.h > similarity index 83% > rename from arch/x86/include/asm/intel_pmc_ipc.h > rename to include/linux/mfd/intel_pmc_bxt.h > index 22848df5faaf..f03a80df0728 100644 > --- a/arch/x86/include/asm/intel_pmc_ipc.h > +++ b/include/linux/mfd/intel_pmc_bxt.h > @@ -1,6 +1,9 @@ > /* SPDX-License-Identifier: GPL-2.0 */ > -#ifndef _ASM_X86_INTEL_PMC_IPC_H_ > -#define _ASM_X86_INTEL_PMC_IPC_H_ > +#ifndef MFD_INTEL_PMC_BXT_H > +#define MFD_INTEL_PMC_BXT_H > + > +#include <linux/errno.h> > +#include <linux/types.h> > > /* Commands */ > #define PMC_IPC_USB_PWR_CTRL 0xF0 > @@ -25,7 +28,7 @@ > #define PMC_GCR_TELEM_DEEP_S0IX_REG 0x78 > #define PMC_GCR_TELEM_SHLW_S0IX_REG 0x80 > > -#if IS_ENABLED(CONFIG_INTEL_PMC_IPC) > +#if IS_ENABLED(CONFIG_MFD_INTEL_PMC_BXT) > > int intel_pmc_s0ix_counter_read(u64 *data); > int intel_pmc_gcr_read64(u32 offset, u64 *data); > @@ -42,6 +45,6 @@ static inline int intel_pmc_gcr_read64(u32 offset, u64 *data) > return -EINVAL; > } > > -#endif /*CONFIG_INTEL_PMC_IPC*/ > +#endif /* CONFIG_MFD_INTEL_PMC_BXT */ > > #endif > -- > 2.24.1 > -- With Best Regards, Andy Shevchenko