Commit 25f1ca31 authored by Mika Westerberg's avatar Mika Westerberg Committed by Lee Jones

platform/x86: intel_pmc_ipc: Convert to MFD

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.

The new MFD driver continues to expose two sysfs attributes that allow
userspace to send IPC commands to the PMC/SCU to avoid breaking any
existing applications that may use these. Generally this is bad idea so
document this in the ABI documentation.
Signed-off-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
parent 0759a873
These files allow sending arbitrary IPC commands to the PMC/SCU which
may be dangerous. These will be removed eventually and should not be
used in any new applications.
What: /sys/bus/platform/devices/INT34D2:00/simplecmd
Date: Jun 2015
KernelVersion: 4.1
Contact: Mika Westerberg <mika.westerberg@linux.intel.com>
Description: This interface allows userspace to send an arbitrary
IPC command to the PMC/SCU.
Format: %d %d where first number is command and
second number is subcommand.
What: /sys/bus/platform/devices/INT34D2:00/northpeak
Date: Jun 2015
KernelVersion: 4.1
Contact: Mika Westerberg <mika.westerberg@linux.intel.com>
Description: This interface allows userspace to enable and disable
Northpeak through the PMC/SCU.
Format: %u.
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_X86_INTEL_PMC_IPC_H_
#define _ASM_X86_INTEL_PMC_IPC_H_
/* Commands */
#define PMC_IPC_USB_PWR_CTRL 0xF0
#define PMC_IPC_PMIC_BLACKLIST_SEL 0xEF
#define PMC_IPC_PHY_CONFIG 0xEE
#define PMC_IPC_NORTHPEAK_CTRL 0xED
#define PMC_IPC_PM_DEBUG 0xEC
#define PMC_IPC_PMC_FW_MSG_CTRL 0xEA
/* IPC return code */
#define IPC_ERR_NONE 0
#define IPC_ERR_CMD_NOT_SUPPORTED 1
#define IPC_ERR_CMD_NOT_SERVICED 2
#define IPC_ERR_UNABLE_TO_SERVICE 3
#define IPC_ERR_CMD_INVALID 4
#define IPC_ERR_CMD_FAILED 5
#define IPC_ERR_EMSECURITY 6
#define IPC_ERR_UNSIGNEDKERNEL 7
/* GCR reg offsets from gcr base*/
#define PMC_GCR_PMC_CFG_REG 0x08
#define PMC_GCR_TELEM_DEEP_S0IX_REG 0x78
#define PMC_GCR_TELEM_SHLW_S0IX_REG 0x80
#if IS_ENABLED(CONFIG_INTEL_PMC_IPC)
int intel_pmc_s0ix_counter_read(u64 *data);
int intel_pmc_gcr_read64(u32 offset, u64 *data);
#else
static inline int intel_pmc_s0ix_counter_read(u64 *data)
{
return -EINVAL;
}
static inline int intel_pmc_gcr_read64(u32 offset, u64 *data)
{
return -EINVAL;
}
#endif /*CONFIG_INTEL_PMC_IPC*/
#endif
......@@ -53,6 +53,7 @@ struct telemetry_plt_config {
struct telemetry_unit_config ioss_config;
struct mutex telem_trace_lock;
struct mutex telem_lock;
struct intel_pmc_dev *pmc;
struct intel_scu_ipc_dev *scu;
bool telem_in_use;
};
......
......@@ -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,20 @@ 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
depends on X86_PLATFORM_DEVICES
depends on ACPI
select INTEL_SCU_IPC
select MFD_CORE
help
This driver provides support for the PMC (Power Management
Controller) on Intel Broxton and Apollo Lake. The 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
......
......@@ -212,6 +212,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
......
This diff is collapsed.
......@@ -1269,7 +1269,8 @@ config INTEL_UNCORE_FREQ_CONTROL
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
......@@ -1327,15 +1328,6 @@ config INTEL_PMC_CORE
- LTR Ignore
- MPHY/PLL gating status (Sunrisepoint PCH only)
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_PUNIT_IPC
tristate "Intel P-Unit IPC Driver"
---help---
......@@ -1374,7 +1366,9 @@ config INTEL_SCU_IPC_UTIL
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
......
......@@ -138,7 +138,6 @@ obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o
obj-$(CONFIG_INTEL_MID_POWER_BUTTON) += intel_mid_powerbtn.o
obj-$(CONFIG_INTEL_MRFLD_PWRBTN) += intel_mrfld_pwrbtn.o
obj-$(CONFIG_INTEL_PMC_CORE) += intel_pmc_core.o intel_pmc_core_pltdrv.o
obj-$(CONFIG_INTEL_PMC_IPC) += intel_pmc_ipc.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
......
This diff is collapsed.
......@@ -15,6 +15,7 @@
*/
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/mfd/intel_pmc_bxt.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/seq_file.h>
......@@ -22,7 +23,6 @@
#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"
......@@ -647,10 +647,11 @@ DEFINE_SHOW_ATTRIBUTE(telem_soc_states);
static int telem_s0ix_res_get(void *data, u64 *val)
{
struct telemetry_plt_config *plt_config = telemetry_get_pltdata();
u64 s0ix_total_res;
int ret;
ret = intel_pmc_s0ix_counter_read(&s0ix_total_res);
ret = intel_pmc_s0ix_counter_read(plt_config->pmc, &s0ix_total_res);
if (ret) {
pr_err("Failed to read S0ix residency");
return ret;
......@@ -837,12 +838,15 @@ static int pm_suspend_exit_cb(void)
*/
if (suspend_shlw_ctr_exit == suspend_shlw_ctr_temp &&
suspend_deep_ctr_exit == suspend_deep_ctr_temp) {
ret = intel_pmc_gcr_read64(PMC_GCR_TELEM_SHLW_S0IX_REG,
struct telemetry_plt_config *plt_config = telemetry_get_pltdata();
struct intel_pmc_dev *pmc = plt_config->pmc;
ret = intel_pmc_gcr_read64(pmc, PMC_GCR_TELEM_SHLW_S0IX_REG,
&suspend_shlw_res_exit);
if (ret < 0)
goto out;
ret = intel_pmc_gcr_read64(PMC_GCR_TELEM_DEEP_S0IX_REG,
ret = intel_pmc_gcr_read64(pmc, PMC_GCR_TELEM_DEEP_S0IX_REG,
&suspend_deep_res_exit);
if (ret < 0)
goto out;
......
......@@ -1115,6 +1115,8 @@ static int telemetry_pltdrv_probe(struct platform_device *pdev)
telm_conf = (struct telemetry_plt_config *)id->driver_data;
telm_conf->pmc = dev_get_drvdata(pdev->dev.parent);
mem = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(mem))
return PTR_ERR(mem);
......
......@@ -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
......
......@@ -64,6 +64,7 @@
#include <linux/uaccess.h> /* For copy_to_user/put_user/... */
#include <linux/io.h> /* For inb/outb/... */
#include <linux/platform_data/itco_wdt.h>
#include <linux/mfd/intel_pmc_bxt.h>
#include "iTCO_vendor.h"
......@@ -233,12 +234,24 @@ static int update_no_reboot_bit_cnt(void *priv, bool set)
return val != newval ? -EIO : 0;
}
static int update_no_reboot_bit_pmc(void *priv, bool set)
{
struct intel_pmc_dev *pmc = priv;
u32 bits = PMC_CFG_NO_REBOOT_EN;
u32 value = set ? bits : 0;
return intel_pmc_gcr_update(pmc, PMC_GCR_PMC_CFG_REG, bits, value);
}
static void iTCO_wdt_no_reboot_bit_setup(struct iTCO_wdt_private *p,
struct itco_wdt_platform_data *pdata)
struct platform_device *pdev,
struct itco_wdt_platform_data *pdata)
{
if (pdata->update_no_reboot_bit) {
p->update_no_reboot_bit = pdata->update_no_reboot_bit;
p->no_reboot_priv = pdata->no_reboot_priv;
if (pdata->no_reboot_use_pmc) {
struct intel_pmc_dev *pmc = dev_get_drvdata(pdev->dev.parent);
p->update_no_reboot_bit = update_no_reboot_bit_pmc;
p->no_reboot_priv = pmc;
return;
}
......@@ -478,14 +491,14 @@ static int iTCO_wdt_probe(struct platform_device *pdev)
return -ENODEV;
}
iTCO_wdt_no_reboot_bit_setup(p, pdata);
iTCO_wdt_no_reboot_bit_setup(p, pdev, pdata);
/*
* Get the Memory-Mapped GCS or PMC register, we need it for the
* NO_REBOOT flag (TCO v2 and v3).
*/
if (p->iTCO_version >= 2 && p->iTCO_version < 6 &&
!pdata->update_no_reboot_bit) {
!pdata->no_reboot_use_pmc) {
p->gcs_pmc_res = platform_get_resource(pdev,
IORESOURCE_MEM,
ICH_RES_MEM_GCS_PMC);
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef MFD_INTEL_PMC_BXT_H
#define MFD_INTEL_PMC_BXT_H
/* GCR reg offsets from GCR base */
#define PMC_GCR_PMC_CFG_REG 0x08
#define PMC_GCR_TELEM_DEEP_S0IX_REG 0x78
#define PMC_GCR_TELEM_SHLW_S0IX_REG 0x80
/* PMC_CFG_REG bit masks */
#define PMC_CFG_NO_REBOOT_EN BIT(4)
/**
* struct intel_pmc_dev - Intel PMC device structure
* @dev: Pointer to the parent PMC device
* @scu: Pointer to the SCU IPC device data structure
* @gcr_mem_base: Virtual base address of GCR (Global Configuration Registers)
* @gcr_lock: Lock used to serialize access to GCR registers
* @telem_base: Pointer to telemetry SSRAM base resource or %NULL if not
* available
*/
struct intel_pmc_dev {
struct device *dev;
struct intel_scu_ipc_dev *scu;
void __iomem *gcr_mem_base;
spinlock_t gcr_lock;
struct resource *telem_base;
};
#if IS_ENABLED(CONFIG_MFD_INTEL_PMC_BXT)
int intel_pmc_gcr_read64(struct intel_pmc_dev *pmc, u32 offset, u64 *data);
int intel_pmc_gcr_update(struct intel_pmc_dev *pmc, u32 offset, u32 mask, u32 val);
int intel_pmc_s0ix_counter_read(struct intel_pmc_dev *pmc, u64 *data);
#else
static inline int intel_pmc_gcr_read64(struct intel_pmc_dev *pmc, u32 offset,
u64 *data)
{
return -ENOTSUPP;
}
static inline int intel_pmc_gcr_update(struct intel_pmc_dev *pmc, u32 offset,
u32 mask, u32 val)
{
return -ENOTSUPP;
}
static inline int intel_pmc_s0ix_counter_read(struct intel_pmc_dev *pmc, u64 *data)
{
return -ENOTSUPP;
}
#endif
#endif /* MFD_INTEL_PMC_BXT_H */
......@@ -12,13 +12,16 @@
#define ICH_RES_MEM_OFF 2
#define ICH_RES_MEM_GCS_PMC 0
/**
* struct itco_wdt_platform_data - iTCO_wdt platform data
* @name: Name of the platform
* @version: iTCO version
* @no_reboot_use_pmc: Use PMC BXT API to set and clear NO_REBOOT bit
*/
struct itco_wdt_platform_data {
char name[32];
unsigned int version;
/* private data to be passed to update_no_reboot_bit API */
void *no_reboot_priv;
/* pointer for platform specific no reboot update function */
int (*update_no_reboot_bit)(void *priv, bool set);
bool no_reboot_use_pmc;
};
#endif /* _ITCO_WDT_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment