summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0010-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0010-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0010-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch1375
1 files changed, 1189 insertions, 186 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0010-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0010-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch
index db21250bb..d2ecdfd72 100644
--- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0010-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0010-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch
@@ -1,4 +1,4 @@
-From 63ccbbe64f7e6560233971b886f6166fc59d20ef Mon Sep 17 00:00:00 2001
+From 9c27803dd432c7a9fc57dd3e16f0fd724919575e Mon Sep 17 00:00:00 2001
From: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
Date: Mon, 7 Jan 2019 09:56:10 -0800
Subject: [PATCH] Update PECI drivers to sync with linux upstreaming version
@@ -10,28 +10,32 @@ Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
---
Documentation/hwmon/peci-cputemp | 34 +-
drivers/hwmon/Kconfig | 4 +-
- drivers/hwmon/peci-cputemp.c | 156 ++++--
+ drivers/hwmon/peci-cputemp.c | 162 ++++--
drivers/hwmon/peci-dimmtemp.c | 69 +--
drivers/hwmon/peci-hwmon.h | 9 +-
drivers/mfd/Kconfig | 5 +-
- drivers/mfd/intel-peci-client.c | 43 +-
- drivers/peci/Kconfig | 35 +-
- drivers/peci/Makefile | 6 +-
- drivers/peci/busses/Kconfig | 19 +
- drivers/peci/busses/Makefile | 6 +
+ drivers/mfd/intel-peci-client.c | 49 +-
+ drivers/peci/Kconfig | 46 +-
+ drivers/peci/Makefile | 7 +-
+ drivers/peci/busses/Kconfig | 32 ++
+ drivers/peci/busses/Makefile | 7 +
drivers/peci/busses/peci-aspeed.c | 494 +++++++++++++++++++
+ drivers/peci/busses/peci-npcm.c | 410 +++++++++++++++
drivers/peci/peci-aspeed.c | 505 -------------------
- drivers/peci/peci-core.c | 889 ++++++++++++++++++----------------
- drivers/peci/peci-dev.c | 340 +++++++++++++
- include/linux/mfd/intel-peci-client.h | 6 +-
+ drivers/peci/peci-core.c | 905 +++++++++++++++++++---------------
+ drivers/peci/peci-dev.c | 346 +++++++++++++
+ drivers/peci/peci-npcm.c | 410 ---------------
+ include/linux/mfd/intel-peci-client.h | 32 +-
include/linux/peci.h | 30 +-
- include/uapi/linux/peci-ioctl.h | 394 ++++++++-------
- 18 files changed, 1805 insertions(+), 1239 deletions(-)
+ include/uapi/linux/peci-ioctl.h | 416 +++++++++-------
+ 20 files changed, 2296 insertions(+), 1676 deletions(-)
create mode 100644 drivers/peci/busses/Kconfig
create mode 100644 drivers/peci/busses/Makefile
create mode 100644 drivers/peci/busses/peci-aspeed.c
+ create mode 100644 drivers/peci/busses/peci-npcm.c
delete mode 100644 drivers/peci/peci-aspeed.c
create mode 100644 drivers/peci/peci-dev.c
+ delete mode 100644 drivers/peci/peci-npcm.c
diff --git a/Documentation/hwmon/peci-cputemp b/Documentation/hwmon/peci-cputemp
index 821a9258f2e6..a3a3e465c888 100644
@@ -89,7 +93,7 @@ index 821a9258f2e6..a3a3e465c888 100644
+temp[6-*]_crit_hyst Provides the hysteresis value from Tcontrol to Tjmax of
the core.
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
-index 996e80590b5b..93945eb19261 100644
+index 18cd3b17f660..0bd06a938526 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1321,7 +1321,7 @@ config SENSORS_PECI_CPUTEMP
@@ -111,7 +115,7 @@ index 996e80590b5b..93945eb19261 100644
source "drivers/hwmon/pmbus/Kconfig"
diff --git a/drivers/hwmon/peci-cputemp.c b/drivers/hwmon/peci-cputemp.c
-index 11880c86a854..30ba1638e358 100644
+index 11880c86a854..3cb2db2fdf0a 100644
--- a/drivers/hwmon/peci-cputemp.c
+++ b/drivers/hwmon/peci-cputemp.c
@@ -1,5 +1,5 @@
@@ -214,7 +218,7 @@ index 11880c86a854..30ba1638e358 100644
/* Note that the tjmax should be available before calling it */
priv->temp.die.value = priv->temp.tjmax.value +
-@@ -144,24 +151,67 @@ static int get_die_temp(struct peci_cputemp *priv)
+@@ -144,24 +151,70 @@ static int get_die_temp(struct peci_cputemp *priv)
return 0;
}
@@ -237,6 +241,9 @@ index 11880c86a854..30ba1638e358 100644
+ if (ret)
+ return ret;
+
++ if (msg.cc != PECI_DEV_CC_SUCCESS)
++ return -EAGAIN;
++
+ dts_margin = (msg.pkg_config[1] << 8) | msg.pkg_config[0];
+
+ /**
@@ -289,7 +296,7 @@ index 11880c86a854..30ba1638e358 100644
* Processors return a value of the core DTS reading in 10.6 format
* (10 bits signed decimal, 6 bits fractional).
* Error codes:
-@@ -192,6 +242,7 @@ static int cputemp_read_string(struct device *dev,
+@@ -192,6 +245,7 @@ static int cputemp_read_string(struct device *dev,
return -EOPNOTSUPP;
*str = cputemp_label[channel];
@@ -297,7 +304,7 @@ index 11880c86a854..30ba1638e358 100644
return 0;
}
-@@ -200,26 +251,33 @@ static int cputemp_read(struct device *dev,
+@@ -200,26 +254,33 @@ static int cputemp_read(struct device *dev,
u32 attr, int channel, long *val)
{
struct peci_cputemp *priv = dev_get_drvdata(dev);
@@ -337,7 +344,7 @@ index 11880c86a854..30ba1638e358 100644
case channel_tcontrol:
*val = priv->temp.tcontrol.value;
break;
-@@ -231,8 +289,8 @@ static int cputemp_read(struct device *dev,
+@@ -231,8 +292,8 @@ static int cputemp_read(struct device *dev,
break;
default:
core_index = channel - DEFAULT_CHANNEL_NUMS;
@@ -348,7 +355,7 @@ index 11880c86a854..30ba1638e358 100644
break;
*val = priv->temp.core[core_index].value;
-@@ -249,11 +307,11 @@ static int cputemp_read(struct device *dev,
+@@ -249,11 +310,11 @@ static int cputemp_read(struct device *dev,
*val = priv->temp.tjmax.value - priv->temp.tcontrol.value;
break;
default:
@@ -362,7 +369,7 @@ index 11880c86a854..30ba1638e358 100644
}
static umode_t cputemp_is_visible(const void *data,
-@@ -262,11 +320,11 @@ static umode_t cputemp_is_visible(const void *data,
+@@ -262,11 +323,11 @@ static umode_t cputemp_is_visible(const void *data,
{
const struct peci_cputemp *priv = data;
@@ -379,7 +386,7 @@ index 11880c86a854..30ba1638e358 100644
return 0;
}
-@@ -280,7 +338,7 @@ static const struct hwmon_ops cputemp_ops = {
+@@ -280,7 +341,7 @@ static const struct hwmon_ops cputemp_ops = {
static int check_resolved_cores(struct peci_cputemp *priv)
{
struct peci_rd_pci_cfg_local_msg msg;
@@ -388,7 +395,7 @@ index 11880c86a854..30ba1638e358 100644
/* Get the RESOLVED_CORES register value */
msg.addr = priv->mgr->client->addr;
-@@ -290,30 +348,31 @@ static int check_resolved_cores(struct peci_cputemp *priv)
+@@ -290,30 +351,34 @@ static int check_resolved_cores(struct peci_cputemp *priv)
msg.reg = REG_RESOLVED_CORES_OFFSET;
msg.rx_len = 4;
@@ -400,6 +407,9 @@ index 11880c86a854..30ba1638e358 100644
+ PECI_CMD_RD_PCI_CFG_LOCAL, &msg);
+ if (ret)
+ return ret;
++
++ if (msg.cc != PECI_DEV_CC_SUCCESS)
++ return -EAGAIN;
priv->core_mask = le32_to_cpup((__le32 *)msg.pci_config);
if (!priv->core_mask)
@@ -429,7 +439,7 @@ index 11880c86a854..30ba1638e358 100644
priv->temp_config[priv->config_idx++] =
config_table[channel_core];
-@@ -326,7 +385,7 @@ static int peci_cputemp_probe(struct platform_device *pdev)
+@@ -326,7 +391,7 @@ static int peci_cputemp_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct peci_cputemp *priv;
struct device *hwmon_dev;
@@ -438,7 +448,7 @@ index 11880c86a854..30ba1638e358 100644
if ((mgr->client->adapter->cmd_mask &
(BIT(PECI_CMD_GET_TEMP) | BIT(PECI_CMD_RD_PKG_CFG))) !=
-@@ -346,12 +405,13 @@ static int peci_cputemp_probe(struct platform_device *pdev)
+@@ -346,12 +411,13 @@ static int peci_cputemp_probe(struct platform_device *pdev)
mgr->client->addr - PECI_BASE_ADDR);
priv->temp_config[priv->config_idx++] = config_table[channel_die];
@@ -686,7 +696,7 @@ index 9af5730ad7ba..28087e9cd4da 100644
bool "Atmel Micro ASIC (iPAQ h3100/h3600/h3700) Support"
depends on SA1100_H3100 || SA1100_H3600
diff --git a/drivers/mfd/intel-peci-client.c b/drivers/mfd/intel-peci-client.c
-index d53e4f1078ac..d62442438512 100644
+index d53e4f1078ac..466085fd43b9 100644
--- a/drivers/mfd/intel-peci-client.c
+++ b/drivers/mfd/intel-peci-client.c
@@ -1,12 +1,12 @@
@@ -717,7 +727,7 @@ index d53e4f1078ac..d62442438512 100644
static struct mfd_cell peci_functions[] = {
{ .name = "peci-cputemp", },
{ .name = "peci-dimmtemp", },
-@@ -31,19 +25,19 @@ static struct mfd_cell peci_functions[] = {
+@@ -31,19 +25,25 @@ static struct mfd_cell peci_functions[] = {
};
static const struct cpu_gen_info cpu_gen_info_table[] = {
@@ -736,11 +746,17 @@ index d53e4f1078ac..d62442438512 100644
.chan_rank_max = CHAN_RANK_MAX_ON_BDX,
.dimm_idx_max = DIMM_IDX_MAX_ON_BDX },
- [CPU_GEN_SKX] = {
++ { /* Broadwell Xeon D */
++ .family = 6, /* Family code */
++ .model = INTEL_FAM6_BROADWELL_XEON_D,
++ .core_max = CORE_MAX_ON_XD,
++ .chan_rank_max = CHAN_RANK_MAX_ON_XD,
++ .dimm_idx_max = DIMM_IDX_MAX_ON_XD },
+ { /* Skylake Xeon */
.family = 6, /* Family code */
.model = INTEL_FAM6_SKYLAKE_X,
.core_max = CORE_MAX_ON_SKX,
-@@ -53,16 +47,17 @@ static const struct cpu_gen_info cpu_gen_info_table[] = {
+@@ -53,16 +53,17 @@ static const struct cpu_gen_info cpu_gen_info_table[] = {
static int peci_client_get_cpu_gen_info(struct peci_client_manager *priv)
{
@@ -763,7 +779,7 @@ index d53e4f1078ac..d62442438512 100644
family = FIELD_PREP(LOWER_BYTE_MASK,
FIELD_GET(CPU_ID_FAMILY_MASK, cpu_id)) |
-@@ -83,11 +78,11 @@ static int peci_client_get_cpu_gen_info(struct peci_client_manager *priv)
+@@ -83,11 +84,11 @@ static int peci_client_get_cpu_gen_info(struct peci_client_manager *priv)
}
if (!priv->gen_info) {
@@ -778,7 +794,7 @@ index d53e4f1078ac..d62442438512 100644
}
static int peci_client_probe(struct peci_client *client)
-@@ -103,31 +98,29 @@ static int peci_client_probe(struct peci_client *client)
+@@ -103,31 +104,29 @@ static int peci_client_probe(struct peci_client *client)
dev_set_drvdata(dev, priv);
priv->client = client;
@@ -815,7 +831,7 @@ index d53e4f1078ac..d62442438512 100644
static const struct peci_device_id peci_client_ids[] = {
{ .name = "peci-client" },
diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
-index 9e9845ebcff4..9752feee2454 100644
+index 7293108fb543..9752feee2454 100644
--- a/drivers/peci/Kconfig
+++ b/drivers/peci/Kconfig
@@ -2,10 +2,12 @@
@@ -833,7 +849,7 @@ index 9e9845ebcff4..9752feee2454 100644
help
The Platform Environment Control Interface (PECI) is a one-wire bus
interface that provides a communication channel from Intel processors
-@@ -14,26 +16,23 @@ config PECI
+@@ -14,37 +16,23 @@ config PECI
If you want PECI support, you should say Y here and also to the
specific driver for your bus adapter(s) below.
@@ -842,42 +858,53 @@ index 9e9845ebcff4..9752feee2454 100644
-#
-# PECI hardware bus configuration
-#
+-
+-menu "PECI Hardware Bus support"
+-
+-config PECI_ASPEED
+- tristate "ASPEED PECI support"
+- select REGMAP_MMIO
+- depends on OF
+- depends on ARCH_ASPEED || COMPILE_TEST
+- help
+- Say Y here if you want support for the Platform Environment Control
+- Interface (PECI) bus adapter driver on the ASPEED SoCs.
+ This support is also available as a module. If so, the module
+ will be called peci-core.
--menu "PECI Hardware Bus support"
+- This support is also available as a module. If so, the module
+- will be called peci-aspeed.
+if PECI
--config PECI_ASPEED
-- tristate "ASPEED PECI support"
+-config PECI_NPCM
+- tristate "Nuvoton NPCM PECI support"
- select REGMAP_MMIO
- depends on OF
-- depends on ARCH_ASPEED || COMPILE_TEST
+- depends on ARCH_NPCM || COMPILE_TEST
+config PECI_CHARDEV
+ tristate "PECI device interface"
help
- Say Y here if you want support for the Platform Environment Control
-- Interface (PECI) bus adapter driver on the ASPEED SoCs.
+- Interface (PECI) bus adapter driver on the Nuvoton NPCM SoCs.
+ Say Y here to use peci-* device files, usually found in the /dev
+ directory on your system. They make it possible to have user-space
+ programs use the PECI bus.
-- This support is also available as a module. If so, the module
-- will be called peci-aspeed.
-+ This support is also available as a module. If so, the module
-+ will be called peci-dev.
-
+ This support is also available as a module. If so, the module
+- will be called peci-npcm.
-endmenu
++ will be called peci-dev.
++
+source "drivers/peci/busses/Kconfig"
endif # PECI
+
+endmenu
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
-index 886285e69765..da8b0a33fa42 100644
+index 3326da54a21a..da8b0a33fa42 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
-@@ -1,9 +1,11 @@
+@@ -1,10 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
#
-# Makefile for the PECI core and bus drivers.
@@ -890,13 +917,14 @@ index 886285e69765..da8b0a33fa42 100644
# Hardware specific bus drivers
-obj-$(CONFIG_PECI_ASPEED) += peci-aspeed.o
+-obj-$(CONFIG_PECI_NPCM) += peci-npcm.o
+obj-y += busses/
diff --git a/drivers/peci/busses/Kconfig b/drivers/peci/busses/Kconfig
new file mode 100644
-index 000000000000..a20d470b4250
+index 000000000000..bfacafb7a7ba
--- /dev/null
+++ b/drivers/peci/busses/Kconfig
-@@ -0,0 +1,19 @@
+@@ -0,0 +1,32 @@
+#
+# PECI hardware bus configuration
+#
@@ -912,22 +940,36 @@ index 000000000000..a20d470b4250
+ Say Y here if you want support for the Platform Environment Control
+ Interface (PECI) bus adapter driver on the ASPEED SoCs.
+
-+ This support is also available as a module. If so, the module
++ This support is also available as a module. If so, the module
+ will be called peci-aspeed.
+
++config PECI_NPCM
++ tristate "Nuvoton NPCM PECI support"
++ select REGMAP_MMIO
++ depends on OF
++ depends on ARCH_NPCM || COMPILE_TEST
++ depends on PECI
++ help
++ Say Y here if you want support for the Platform Environment Control
++ Interface (PECI) bus adapter driver on the Nuvoton NPCM SoCs.
++
++ This support is also available as a module. If so, the module
++ will be called peci-npcm.
++
+endmenu
diff --git a/drivers/peci/busses/Makefile b/drivers/peci/busses/Makefile
new file mode 100644
-index 000000000000..69e31dfaca19
+index 000000000000..aa8ce3ae5947
--- /dev/null
+++ b/drivers/peci/busses/Makefile
-@@ -0,0 +1,6 @@
+@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the PECI hardware bus drivers.
+#
+
+obj-$(CONFIG_PECI_ASPEED) += peci-aspeed.o
++obj-$(CONFIG_PECI_NPCM) += peci-npcm.o
diff --git a/drivers/peci/busses/peci-aspeed.c b/drivers/peci/busses/peci-aspeed.c
new file mode 100644
index 000000000000..8a0dd40730cc
@@ -1428,6 +1470,422 @@ index 000000000000..8a0dd40730cc
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>");
+MODULE_DESCRIPTION("ASPEED PECI driver");
+MODULE_LICENSE("GPL v2");
+diff --git a/drivers/peci/busses/peci-npcm.c b/drivers/peci/busses/peci-npcm.c
+new file mode 100644
+index 000000000000..f632365b1416
+--- /dev/null
++++ b/drivers/peci/busses/peci-npcm.c
+@@ -0,0 +1,410 @@
++// SPDX-License-Identifier: GPL-2.0
++// Copyright (c) 2019 Nuvoton Technology corporation.
++
++#include <linux/bitfield.h>
++#include <linux/clk.h>
++#include <linux/interrupt.h>
++#include <linux/jiffies.h>
++#include <linux/module.h>
++#include <linux/of.h>
++#include <linux/peci.h>
++#include <linux/platform_device.h>
++#include <linux/regmap.h>
++#include <linux/mfd/syscon.h>
++#include <linux/reset.h>
++
++/* NPCM7xx GCR module */
++#define NPCM7XX_INTCR3_OFFSET 0x9C
++#define NPCM7XX_INTCR3_PECIVSEL BIT(19)
++
++/* NPCM PECI Registers */
++#define NPCM_PECI_CTL_STS 0x00
++#define NPCM_PECI_RD_LENGTH 0x04
++#define NPCM_PECI_ADDR 0x08
++#define NPCM_PECI_CMD 0x0C
++#define NPCM_PECI_CTL2 0x10
++#define NPCM_PECI_WR_LENGTH 0x1C
++#define NPCM_PECI_PDDR 0x2C
++#define NPCM_PECI_DAT_INOUT(n) (0x100 + ((n) * 4))
++
++#define NPCM_PECI_MAX_REG 0x200
++
++/* NPCM_PECI_CTL_STS - 0x00 : Control Register */
++#define NPCM_PECI_CTRL_DONE_INT_EN BIT(6)
++#define NPCM_PECI_CTRL_ABRT_ERR BIT(4)
++#define NPCM_PECI_CTRL_CRC_ERR BIT(3)
++#define NPCM_PECI_CTRL_DONE BIT(1)
++#define NPCM_PECI_CTRL_START_BUSY BIT(0)
++
++/* NPCM_PECI_RD_LENGTH - 0x04 : Command Register */
++#define NPCM_PECI_RD_LEN_MASK GENMASK(6, 0)
++
++/* NPCM_PECI_CMD - 0x10 : Command Register */
++#define NPCM_PECI_CTL2_MASK GENMASK(7, 6)
++
++/* NPCM_PECI_WR_LENGTH - 0x1C : Command Register */
++#define NPCM_PECI_WR_LEN_MASK GENMASK(6, 0)
++
++/* NPCM_PECI_PDDR - 0x2C : Command Register */
++#define NPCM_PECI_PDDR_MASK GENMASK(4, 0)
++
++#define NPCM_PECI_INT_MASK (NPCM_PECI_CTRL_ABRT_ERR | \
++ NPCM_PECI_CTRL_CRC_ERR | \
++ NPCM_PECI_CTRL_DONE)
++
++#define NPCM_PECI_IDLE_CHECK_TIMEOUT_USEC 50000
++#define NPCM_PECI_IDLE_CHECK_INTERVAL_USEC 10000
++#define NPCM_PECI_CMD_TIMEOUT_MS_DEFAULT 1000
++#define NPCM_PECI_CMD_TIMEOUT_MS_MAX 60000
++#define NPCM_PECI_HOST_NEG_BIT_RATE_MAX 31
++#define NPCM_PECI_HOST_NEG_BIT_RATE_MIN 7
++#define NPCM_PECI_HOST_NEG_BIT_RATE_DEFAULT 15
++#define NPCM_PECI_PULL_DOWN_DEFAULT 0
++#define NPCM_PECI_PULL_DOWN_MAX 2
++
++struct npcm_peci {
++ u32 cmd_timeout_ms;
++ u32 host_bit_rate;
++ struct completion xfer_complete;
++ struct regmap *gcr_regmap;
++ struct peci_adapter *adapter;
++ struct regmap *regmap;
++ u32 status;
++ spinlock_t lock; /* to sync completion status handling */
++ struct device *dev;
++ struct clk *clk;
++ int irq;
++};
++
++static int npcm_peci_xfer_native(struct npcm_peci *priv,
++ struct peci_xfer_msg *msg)
++{
++ long err, timeout = msecs_to_jiffies(priv->cmd_timeout_ms);
++ unsigned long flags;
++ unsigned int msg_rd;
++ u32 cmd_sts;
++ int i, rc;
++
++ /* Check command sts and bus idle state */
++ rc = regmap_read_poll_timeout(priv->regmap, NPCM_PECI_CTL_STS, cmd_sts,
++ !(cmd_sts & NPCM_PECI_CTRL_START_BUSY),
++ NPCM_PECI_IDLE_CHECK_INTERVAL_USEC,
++ NPCM_PECI_IDLE_CHECK_TIMEOUT_USEC);
++ if (rc)
++ return rc; /* -ETIMEDOUT */
++
++ spin_lock_irqsave(&priv->lock, flags);
++ reinit_completion(&priv->xfer_complete);
++
++ regmap_write(priv->regmap, NPCM_PECI_ADDR, msg->addr);
++ regmap_write(priv->regmap, NPCM_PECI_RD_LENGTH,
++ NPCM_PECI_WR_LEN_MASK & msg->rx_len);
++ regmap_write(priv->regmap, NPCM_PECI_WR_LENGTH,
++ NPCM_PECI_WR_LEN_MASK & msg->tx_len);
++
++ if (msg->tx_len) {
++ regmap_write(priv->regmap, NPCM_PECI_CMD, msg->tx_buf[0]);
++
++ for (i = 0; i < (msg->tx_len - 1); i++)
++ regmap_write(priv->regmap, NPCM_PECI_DAT_INOUT(i),
++ msg->tx_buf[i + 1]);
++ }
++
++ priv->status = 0;
++ regmap_update_bits(priv->regmap, NPCM_PECI_CTL_STS,
++ NPCM_PECI_CTRL_START_BUSY,
++ NPCM_PECI_CTRL_START_BUSY);
++
++ spin_unlock_irqrestore(&priv->lock, flags);
++
++ err = wait_for_completion_interruptible_timeout(&priv->xfer_complete,
++ timeout);
++
++ spin_lock_irqsave(&priv->lock, flags);
++
++ regmap_write(priv->regmap, NPCM_PECI_CMD, 0);
++
++ if (err <= 0 || priv->status != NPCM_PECI_CTRL_DONE) {
++ if (err < 0) { /* -ERESTARTSYS */
++ rc = (int)err;
++ goto err_irqrestore;
++ } else if (err == 0) {
++ dev_dbg(priv->dev, "Timeout waiting for a response!\n");
++ rc = -ETIMEDOUT;
++ goto err_irqrestore;
++ }
++
++ dev_dbg(priv->dev, "No valid response!\n");
++ rc = -EIO;
++ goto err_irqrestore;
++ }
++
++ for (i = 0; i < msg->rx_len; i++) {
++ regmap_read(priv->regmap, NPCM_PECI_DAT_INOUT(i), &msg_rd);
++ msg->rx_buf[i] = (u8)msg_rd;
++ }
++
++err_irqrestore:
++ spin_unlock_irqrestore(&priv->lock, flags);
++ return rc;
++}
++
++static irqreturn_t npcm_peci_irq_handler(int irq, void *arg)
++{
++ struct npcm_peci *priv = arg;
++ u32 status_ack = 0;
++ u32 status;
++
++ spin_lock(&priv->lock);
++ regmap_read(priv->regmap, NPCM_PECI_CTL_STS, &status);
++ priv->status |= (status & NPCM_PECI_INT_MASK);
++
++ if (status & NPCM_PECI_CTRL_CRC_ERR) {
++ dev_dbg(priv->dev, "PECI_INT_W_FCS_BAD\n");
++ status_ack |= NPCM_PECI_CTRL_CRC_ERR;
++ }
++
++ if (status & NPCM_PECI_CTRL_ABRT_ERR) {
++ dev_dbg(priv->dev, "NPCM_PECI_CTRL_ABRT_ERR\n");
++ status_ack |= NPCM_PECI_CTRL_ABRT_ERR;
++ }
++
++ /*
++ * All commands should be ended up with a NPCM_PECI_CTRL_DONE
++ * bit set even in an error case.
++ */
++ if (status & NPCM_PECI_CTRL_DONE) {
++ dev_dbg(priv->dev, "NPCM_PECI_CTRL_DONE\n");
++ status_ack |= NPCM_PECI_CTRL_DONE;
++ complete(&priv->xfer_complete);
++ }
++
++ regmap_write_bits(priv->regmap, NPCM_PECI_CTL_STS,
++ NPCM_PECI_INT_MASK, status_ack);
++
++ spin_unlock(&priv->lock);
++ return IRQ_HANDLED;
++}
++
++static int npcm_peci_init_ctrl(struct npcm_peci *priv)
++{
++ u32 cmd_sts, host_neg_bit_rate = 0, pull_down = 0;
++ int ret;
++ bool volt;
++
++ priv->clk = devm_clk_get(priv->dev, NULL);
++ if (IS_ERR(priv->clk)) {
++ dev_err(priv->dev, "Failed to get clk source.\n");
++ return PTR_ERR(priv->clk);
++ }
++
++ ret = clk_prepare_enable(priv->clk);
++ if (ret) {
++ dev_err(priv->dev, "Failed to enable clock.\n");
++ return ret;
++ }
++
++ ret = of_property_read_u32(priv->dev->of_node, "cmd-timeout-ms",
++ &priv->cmd_timeout_ms);
++ if (ret || priv->cmd_timeout_ms > NPCM_PECI_CMD_TIMEOUT_MS_MAX ||
++ priv->cmd_timeout_ms == 0) {
++ if (ret)
++ dev_warn(priv->dev,
++ "cmd-timeout-ms not found, use default : %u\n",
++ NPCM_PECI_CMD_TIMEOUT_MS_DEFAULT);
++ else
++ dev_warn(priv->dev,
++ "Invalid cmd-timeout-ms : %u. Use default : %u\n",
++ priv->cmd_timeout_ms,
++ NPCM_PECI_CMD_TIMEOUT_MS_DEFAULT);
++
++ priv->cmd_timeout_ms = NPCM_PECI_CMD_TIMEOUT_MS_DEFAULT;
++ }
++
++ if (of_device_is_compatible(priv->dev->of_node,
++ "nuvoton,npcm750-peci")) {
++ priv->gcr_regmap = syscon_regmap_lookup_by_compatible
++ ("nuvoton,npcm750-gcr");
++ if (!IS_ERR(priv->gcr_regmap)) {
++ volt = of_property_read_bool(priv->dev->of_node,
++ "high-volt-range");
++ if (volt)
++ regmap_update_bits(priv->gcr_regmap,
++ NPCM7XX_INTCR3_OFFSET,
++ NPCM7XX_INTCR3_PECIVSEL,
++ NPCM7XX_INTCR3_PECIVSEL);
++ else
++ regmap_update_bits(priv->gcr_regmap,
++ NPCM7XX_INTCR3_OFFSET,
++ NPCM7XX_INTCR3_PECIVSEL, 0);
++ }
++ }
++
++ ret = of_property_read_u32(priv->dev->of_node, "pull-down",
++ &pull_down);
++ if (ret || pull_down > NPCM_PECI_PULL_DOWN_MAX) {
++ if (ret)
++ dev_warn(priv->dev,
++ "pull-down not found, use default : %u\n",
++ NPCM_PECI_PULL_DOWN_DEFAULT);
++ else
++ dev_warn(priv->dev,
++ "Invalid pull-down : %u. Use default : %u\n",
++ pull_down,
++ NPCM_PECI_PULL_DOWN_DEFAULT);
++ pull_down = NPCM_PECI_PULL_DOWN_DEFAULT;
++ }
++
++ regmap_update_bits(priv->regmap, NPCM_PECI_CTL2, NPCM_PECI_CTL2_MASK,
++ pull_down << 6);
++
++ ret = of_property_read_u32(priv->dev->of_node, "host-neg-bit-rate",
++ &host_neg_bit_rate);
++ if (ret || host_neg_bit_rate > NPCM_PECI_HOST_NEG_BIT_RATE_MAX ||
++ host_neg_bit_rate < NPCM_PECI_HOST_NEG_BIT_RATE_MIN) {
++ if (ret)
++ dev_warn(priv->dev,
++ "host-neg-bit-rate not found, use default : %u\n",
++ NPCM_PECI_HOST_NEG_BIT_RATE_DEFAULT);
++ else
++ dev_warn(priv->dev,
++ "Invalid host-neg-bit-rate : %u. Use default : %u\n",
++ host_neg_bit_rate,
++ NPCM_PECI_HOST_NEG_BIT_RATE_DEFAULT);
++ host_neg_bit_rate = NPCM_PECI_HOST_NEG_BIT_RATE_DEFAULT;
++ }
++
++ regmap_update_bits(priv->regmap, NPCM_PECI_PDDR, NPCM_PECI_PDDR_MASK,
++ host_neg_bit_rate);
++
++ priv->host_bit_rate = clk_get_rate(priv->clk) /
++ (4 * (host_neg_bit_rate + 1));
++
++ ret = regmap_read_poll_timeout(priv->regmap, NPCM_PECI_CTL_STS, cmd_sts,
++ !(cmd_sts & NPCM_PECI_CTRL_START_BUSY),
++ NPCM_PECI_IDLE_CHECK_INTERVAL_USEC,
++ NPCM_PECI_IDLE_CHECK_TIMEOUT_USEC);
++ if (ret)
++ return ret; /* -ETIMEDOUT */
++
++ /* PECI interrupt enable */
++ regmap_update_bits(priv->regmap, NPCM_PECI_CTL_STS,
++ NPCM_PECI_CTRL_DONE_INT_EN,
++ NPCM_PECI_CTRL_DONE_INT_EN);
++
++ return 0;
++}
++
++static const struct regmap_config npcm_peci_regmap_config = {
++ .reg_bits = 8,
++ .val_bits = 8,
++ .max_register = NPCM_PECI_MAX_REG,
++ .fast_io = true,
++};
++
++static int npcm_peci_xfer(struct peci_adapter *adapter,
++ struct peci_xfer_msg *msg)
++{
++ struct npcm_peci *priv = peci_get_adapdata(adapter);
++
++ return npcm_peci_xfer_native(priv, msg);
++}
++
++static int npcm_peci_probe(struct platform_device *pdev)
++{
++ struct peci_adapter *adapter;
++ struct npcm_peci *priv;
++ struct resource *res;
++ void __iomem *base;
++ int ret;
++
++ adapter = peci_alloc_adapter(&pdev->dev, sizeof(*priv));
++ if (!adapter)
++ return -ENOMEM;
++
++ priv = peci_get_adapdata(adapter);
++ priv->adapter = adapter;
++ priv->dev = &pdev->dev;
++ dev_set_drvdata(&pdev->dev, priv);
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ base = devm_ioremap_resource(&pdev->dev, res);
++ if (IS_ERR(base)) {
++ ret = PTR_ERR(base);
++ goto err_put_adapter_dev;
++ }
++
++ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
++ &npcm_peci_regmap_config);
++ if (IS_ERR(priv->regmap)) {
++ ret = PTR_ERR(priv->regmap);
++ goto err_put_adapter_dev;
++ }
++
++ priv->irq = platform_get_irq(pdev, 0);
++ if (!priv->irq) {
++ ret = -ENODEV;
++ goto err_put_adapter_dev;
++ }
++
++ ret = devm_request_irq(&pdev->dev, priv->irq, npcm_peci_irq_handler,
++ 0, "peci-npcm-irq", priv);
++ if (ret)
++ goto err_put_adapter_dev;
++
++ init_completion(&priv->xfer_complete);
++ spin_lock_init(&priv->lock);
++
++ priv->adapter->owner = THIS_MODULE;
++ priv->adapter->dev.of_node = of_node_get(dev_of_node(priv->dev));
++ strlcpy(priv->adapter->name, pdev->name, sizeof(priv->adapter->name));
++ priv->adapter->xfer = npcm_peci_xfer;
++
++ ret = npcm_peci_init_ctrl(priv);
++ if (ret)
++ goto err_put_adapter_dev;
++
++ ret = peci_add_adapter(priv->adapter);
++ if (ret)
++ goto err_put_adapter_dev;
++
++ dev_info(&pdev->dev, "peci bus %d registered, host negotiation bit rate %dHz",
++ priv->adapter->nr, priv->host_bit_rate);
++
++ return 0;
++
++err_put_adapter_dev:
++ put_device(&adapter->dev);
++ return ret;
++}
++
++static int npcm_peci_remove(struct platform_device *pdev)
++{
++ struct npcm_peci *priv = dev_get_drvdata(&pdev->dev);
++
++ clk_disable_unprepare(priv->clk);
++ peci_del_adapter(priv->adapter);
++ of_node_put(priv->adapter->dev.of_node);
++
++ return 0;
++}
++
++static const struct of_device_id npcm_peci_of_table[] = {
++ { .compatible = "nuvoton,npcm750-peci", },
++ { }
++};
++MODULE_DEVICE_TABLE(of, npcm_peci_of_table);
++
++static struct platform_driver npcm_peci_driver = {
++ .probe = npcm_peci_probe,
++ .remove = npcm_peci_remove,
++ .driver = {
++ .name = "peci-npcm",
++ .of_match_table = of_match_ptr(npcm_peci_of_table),
++ },
++};
++module_platform_driver(npcm_peci_driver);
++
++MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
++MODULE_DESCRIPTION("NPCM Platform Environment Control Interface (PECI) driver");
++MODULE_LICENSE("GPL v2");
diff --git a/drivers/peci/peci-aspeed.c b/drivers/peci/peci-aspeed.c
deleted file mode 100644
index 51cb2563ceb6..000000000000
@@ -1940,7 +2398,7 @@ index 51cb2563ceb6..000000000000
-MODULE_DESCRIPTION("ASPEED PECI driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/peci/peci-core.c b/drivers/peci/peci-core.c
-index 6f241469ec7e..e2ef013e5002 100644
+index 6f241469ec7e..d1f0df8b139a 100644
--- a/drivers/peci/peci-core.c
+++ b/drivers/peci/peci-core.c
@@ -1,38 +1,31 @@
@@ -2040,7 +2498,8 @@ index 6f241469ec7e..e2ef013e5002 100644
+ * This function must only be called from process context!
+ */
+struct peci_xfer_msg *peci_get_xfer_msg(u8 tx_len, u8 rx_len)
-+{
+ {
+- return crc8(peci_crc8_table, data, (size_t)len, 0);
+ struct peci_xfer_msg *msg;
+ u8 *tx_buf, *rx_buf;
+
@@ -2097,8 +2556,7 @@ index 6f241469ec7e..e2ef013e5002 100644
+
+/* Calculate an Assured Write Frame Check Sequence byte */
+static int peci_aw_fcs(struct peci_xfer_msg *msg, int len, u8 *aw_fcs)
- {
-- return crc8(peci_crc8_table, data, (size_t)len, 0);
++{
+ u8 *tmp_buf;
+
+ /* Allocate a temporary buffer to use a contiguous byte array */
@@ -2127,8 +2585,7 @@ index 6f241469ec7e..e2ef013e5002 100644
+ ulong timeout = jiffies;
+ u8 aw_fcs;
+ int ret;
-
-- /**
++
+ /*
+ * In case if adapter uses DMA, check at here whether tx and rx buffers
+ * are DMA capable or not.
@@ -2144,12 +2601,13 @@ index 6f241469ec7e..e2ef013e5002 100644
+ return -EAGAIN;
+ }
+ }
-+
+
+- /**
+ /*
* For some commands, the PECI originator may need to retry a command if
* the processor PECI client responds with a 0x8x completion code. In
* each instance, the processor PECI client may have started the
-@@ -125,55 +223,56 @@ static int __peci_xfer(struct peci_adapter *adapter, struct peci_xfer_msg *msg,
+@@ -125,55 +223,51 @@ static int __peci_xfer(struct peci_adapter *adapter, struct peci_xfer_msg *msg,
*/
if (do_retry)
@@ -2162,11 +2620,10 @@ index 6f241469ec7e..e2ef013e5002 100644
+ ret = adapter->xfer(adapter, msg);
- if (!do_retry || rc)
-+ if (!do_retry || ret)
- break;
-
+- break;
+-
- if (msg->rx_buf[0] == DEV_PECI_CC_SUCCESS)
-+ if (msg->rx_buf[0] == PECI_DEV_CC_SUCCESS)
++ if (!do_retry || ret || !msg->rx_buf)
break;
/* Retry is needed when completion code is 0x8x */
@@ -2174,10 +2631,9 @@ index 6f241469ec7e..e2ef013e5002 100644
- DEV_PECI_CC_NEED_RETRY) {
- rc = -EIO;
+ if ((msg->rx_buf[0] & PECI_DEV_CC_RETRY_CHECK_MASK) !=
-+ PECI_DEV_CC_NEED_RETRY) {
-+ ret = -EIO;
++ PECI_DEV_CC_NEED_RETRY)
break;
- }
+- }
/* Set the retry bit to indicate a retry attempt */
- msg->tx_buf[1] |= DEV_PECI_RETRY_BIT;
@@ -2192,11 +2648,11 @@ index 6f241469ec7e..e2ef013e5002 100644
+ ret = peci_aw_fcs(msg, 2 + msg->tx_len, &aw_fcs);
+ if (ret)
+ break;
-
-- /**
++
+ msg->tx_buf[msg->tx_len - 1] = 0x80 ^ aw_fcs;
+ }
-+
+
+- /**
+ /*
* Retry for at least 250ms before returning an error.
* Retry interval guideline:
@@ -2230,7 +2686,7 @@ index 6f241469ec7e..e2ef013e5002 100644
}
static int peci_xfer(struct peci_adapter *adapter, struct peci_xfer_msg *msg)
-@@ -190,34 +289,37 @@ static int peci_xfer_with_retries(struct peci_adapter *adapter,
+@@ -190,34 +284,37 @@ static int peci_xfer_with_retries(struct peci_adapter *adapter,
static int peci_scan_cmd_mask(struct peci_adapter *adapter)
{
@@ -2274,13 +2730,14 @@ index 6f241469ec7e..e2ef013e5002 100644
+ goto out;
}
- /**
+- /**
- * Setting up the supporting commands based on minor revision number.
++ /*
+ * Setting up the supporting commands based on revision number.
* See PECI Spec Table 3-1.
*/
revision = FIELD_GET(REVISION_NUM_MASK, dib);
-@@ -243,10 +345,14 @@ static int peci_scan_cmd_mask(struct peci_adapter *adapter)
+@@ -243,10 +340,14 @@ static int peci_scan_cmd_mask(struct peci_adapter *adapter)
adapter->cmd_mask |= BIT(PECI_CMD_GET_DIB);
adapter->cmd_mask |= BIT(PECI_CMD_PING);
@@ -2297,7 +2754,7 @@ index 6f241469ec7e..e2ef013e5002 100644
{
if (!(adapter->cmd_mask & BIT(PECI_CMD_PING)) &&
peci_scan_cmd_mask(adapter) < 0) {
-@@ -262,70 +368,87 @@ static int peci_cmd_support(struct peci_adapter *adapter, enum peci_cmd cmd)
+@@ -262,70 +363,87 @@ static int peci_cmd_support(struct peci_adapter *adapter, enum peci_cmd cmd)
return 0;
}
@@ -2316,19 +2773,19 @@ index 6f241469ec7e..e2ef013e5002 100644
- struct peci_xfer_msg msg;
+ struct peci_xfer_msg *msg;
+ int ret;
++
++ msg = peci_get_xfer_msg(0, 0);
++ if (!msg)
++ return -ENOMEM;
++
++ msg->addr = umsg->addr;
- msg.addr = umsg->addr;
- msg.tx_len = 0;
- msg.rx_len = 0;
-+ msg = peci_get_xfer_msg(0, 0);
-+ if (!msg)
-+ return -ENOMEM;
++ ret = peci_xfer(adapter, msg);
- return peci_xfer(adapter, &msg);
-+ msg->addr = umsg->addr;
-+
-+ ret = peci_xfer(adapter, msg);
-+
+ peci_put_xfer_msg(msg);
+
+ return ret;
@@ -2419,7 +2876,7 @@ index 6f241469ec7e..e2ef013e5002 100644
/* Per the PECI spec, the read length must be a byte, word, or dword */
if (umsg->rx_len != 1 && umsg->rx_len != 2 && umsg->rx_len != 4) {
-@@ -334,29 +457,34 @@ static int peci_ioctl_rd_pkg_cfg(struct peci_adapter *adapter, void *vmsg)
+@@ -334,29 +452,35 @@ static int peci_ioctl_rd_pkg_cfg(struct peci_adapter *adapter, void *vmsg)
return -EINVAL;
}
@@ -2445,17 +2902,18 @@ index 6f241469ec7e..e2ef013e5002 100644
+ msg->tx_buf[2] = umsg->index; /* RdPkgConfig index */
+ msg->tx_buf[3] = (u8)umsg->param; /* LSB - Config parameter */
+ msg->tx_buf[4] = (u8)(umsg->param >> 8); /* MSB - Config parameter */
-+
-+ ret = peci_xfer_with_retries(adapter, msg, false);
-+ if (!ret)
-+ memcpy(umsg->pkg_config, &msg->rx_buf[1], umsg->rx_len);
- rc = peci_xfer_with_retries(adapter, &msg, false);
- if (!rc)
- memcpy(umsg->pkg_config, &msg.rx_buf[1], umsg->rx_len);
-+ peci_put_xfer_msg(msg);
++ ret = peci_xfer_with_retries(adapter, msg, false);
++ if (!ret)
++ memcpy(umsg->pkg_config, &msg->rx_buf[1], umsg->rx_len);
- return rc;
++ umsg->cc = msg->rx_buf[0];
++ peci_put_xfer_msg(msg);
++
+ return ret;
}
@@ -2471,7 +2929,7 @@ index 6f241469ec7e..e2ef013e5002 100644
/* Per the PECI spec, the write length must be a dword */
if (umsg->tx_len != 4) {
-@@ -365,86 +493,113 @@ static int peci_ioctl_wr_pkg_cfg(struct peci_adapter *adapter, void *vmsg)
+@@ -365,86 +489,116 @@ static int peci_ioctl_wr_pkg_cfg(struct peci_adapter *adapter, void *vmsg)
return -EINVAL;
}
@@ -2504,19 +2962,20 @@ index 6f241469ec7e..e2ef013e5002 100644
+ ret = peci_aw_fcs(msg, 8 + umsg->tx_len, &aw_fcs);
+ if (ret)
+ goto out;
-+
-+ msg->tx_buf[5 + i] = 0x80 ^ aw_fcs;
- /* Add an Assure Write Frame Check Sequence byte */
- msg.tx_buf[5 + i] = 0x80 ^
- peci_aw_fcs((u8 *)&msg, 8 + umsg->tx_len);
-+ ret = peci_xfer_with_retries(adapter, msg, true);
++ msg->tx_buf[5 + i] = 0x80 ^ aw_fcs;
- rc = peci_xfer_with_retries(adapter, &msg, true);
-+out:
-+ peci_put_xfer_msg(msg);
++ ret = peci_xfer_with_retries(adapter, msg, true);
- return rc;
++out:
++ umsg->cc = msg->rx_buf[0];
++ peci_put_xfer_msg(msg);
++
+ return ret;
}
@@ -2559,17 +3018,18 @@ index 6f241469ec7e..e2ef013e5002 100644
+ if (!ret)
+ memcpy(&umsg->value, &msg->rx_buf[1], sizeof(uint64_t));
+
++ umsg->cc = msg->rx_buf[0];
+ peci_put_xfer_msg(msg);
+
+ return ret;
-+}
-+
-+static int peci_cmd_wr_ia_msr(struct peci_adapter *adapter, void *vmsg)
-+{
-+ return -ENOSYS; /* Not implemented yet */
}
-static int peci_ioctl_rd_pci_cfg(struct peci_adapter *adapter, void *vmsg)
++static int peci_cmd_wr_ia_msr(struct peci_adapter *adapter, void *vmsg)
++{
++ return -ENOSYS; /* Not implemented yet */
++}
++
+static int peci_cmd_rd_pci_cfg(struct peci_adapter *adapter, void *vmsg)
{
struct peci_rd_pci_cfg_msg *umsg = vmsg;
@@ -2614,6 +3074,7 @@ index 6f241469ec7e..e2ef013e5002 100644
- rc = peci_xfer_with_retries(adapter, &msg, false);
- if (!rc)
- memcpy(umsg->pci_config, &msg.rx_buf[1], 4);
++ umsg->cc = msg->rx_buf[0];
+ peci_put_xfer_msg(msg);
- return rc;
@@ -2637,7 +3098,7 @@ index 6f241469ec7e..e2ef013e5002 100644
/* Per the PECI spec, the read length must be a byte, word, or dword */
if (umsg->rx_len != 1 && umsg->rx_len != 2 && umsg->rx_len != 4) {
-@@ -453,34 +608,41 @@ static int peci_ioctl_rd_pci_cfg_local(struct peci_adapter *adapter, void *vmsg)
+@@ -453,34 +607,42 @@ static int peci_ioctl_rd_pci_cfg_local(struct peci_adapter *adapter, void *vmsg)
return -EINVAL;
}
@@ -2676,6 +3137,7 @@ index 6f241469ec7e..e2ef013e5002 100644
- rc = peci_xfer_with_retries(adapter, &msg, false);
- if (!rc)
- memcpy(umsg->pci_config, &msg.rx_buf[1], umsg->rx_len);
++ umsg->cc = msg->rx_buf[0];
+ peci_put_xfer_msg(msg);
- return rc;
@@ -2695,7 +3157,7 @@ index 6f241469ec7e..e2ef013e5002 100644
/* Per the PECI spec, the write length must be a byte, word, or dword */
if (umsg->tx_len != 1 && umsg->tx_len != 2 && umsg->tx_len != 4) {
-@@ -489,47 +651,56 @@ static int peci_ioctl_wr_pci_cfg_local(struct peci_adapter *adapter, void *vmsg)
+@@ -489,47 +651,57 @@ static int peci_ioctl_wr_pci_cfg_local(struct peci_adapter *adapter, void *vmsg)
return -EINVAL;
}
@@ -2743,6 +3205,7 @@ index 6f241469ec7e..e2ef013e5002 100644
- rc = peci_xfer_with_retries(adapter, &msg, true);
+out:
++ umsg->cc = msg->rx_buf[0];
+ peci_put_xfer_msg(msg);
- return rc;
@@ -2782,7 +3245,7 @@ index 6f241469ec7e..e2ef013e5002 100644
};
/**
-@@ -545,109 +716,28 @@ static const peci_ioctl_fn_type peci_ioctl_fn[PECI_CMD_MAX] = {
+@@ -545,109 +717,28 @@ static const peci_ioctl_fn_type peci_ioctl_fn[PECI_CMD_MAX] = {
*/
int peci_command(struct peci_adapter *adapter, enum peci_cmd cmd, void *vmsg)
{
@@ -2901,7 +3364,7 @@ index 6f241469ec7e..e2ef013e5002 100644
static int peci_detect(struct peci_adapter *adapter, u8 addr)
{
struct peci_ping_msg msg;
-@@ -666,9 +756,9 @@ peci_of_match_device(const struct of_device_id *matches,
+@@ -666,9 +757,9 @@ peci_of_match_device(const struct of_device_id *matches,
return NULL;
return of_match_device(matches, &client->dev);
@@ -2913,7 +3376,7 @@ index 6f241469ec7e..e2ef013e5002 100644
}
static const struct peci_device_id *
-@@ -737,6 +827,7 @@ static int peci_device_probe(struct device *dev)
+@@ -737,6 +828,7 @@ static int peci_device_probe(struct device *dev)
err_detach_pm_domain:
dev_pm_domain_detach(&client->dev, true);
@@ -2921,7 +3384,7 @@ index 6f241469ec7e..e2ef013e5002 100644
return status;
}
-@@ -775,13 +866,14 @@ static void peci_device_shutdown(struct device *dev)
+@@ -775,13 +867,14 @@ static void peci_device_shutdown(struct device *dev)
driver->shutdown(client);
}
@@ -2937,7 +3400,7 @@ index 6f241469ec7e..e2ef013e5002 100644
static int peci_check_addr_validity(u8 addr)
{
-@@ -814,18 +906,18 @@ static int peci_check_client_busy(struct device *dev, void *client_new_p)
+@@ -814,18 +907,23 @@ static int peci_check_client_busy(struct device *dev, void *client_new_p)
int peci_get_cpu_id(struct peci_adapter *adapter, u8 addr, u32 *cpu_id)
{
struct peci_rd_pkg_cfg_msg msg;
@@ -2953,16 +3416,22 @@ index 6f241469ec7e..e2ef013e5002 100644
- rc = peci_command(adapter, PECI_CMD_RD_PKG_CFG, &msg);
- if (!rc)
+- *cpu_id = le32_to_cpup((__le32 *)msg.pkg_config);
+ ret = peci_command(adapter, PECI_CMD_RD_PKG_CFG, &msg);
-+ if (!ret)
- *cpu_id = le32_to_cpup((__le32 *)msg.pkg_config);
++ if (ret)
++ return ret;
++
++ if (msg.cc != PECI_DEV_CC_SUCCESS)
++ return -EAGAIN;
++
++ *cpu_id = le32_to_cpup((__le32 *)msg.pkg_config);
- return rc;
-+ return ret;
++ return 0;
}
EXPORT_SYMBOL_GPL(peci_get_cpu_id);
-@@ -833,7 +925,7 @@ static struct peci_client *peci_new_device(struct peci_adapter *adapter,
+@@ -833,7 +931,7 @@ static struct peci_client *peci_new_device(struct peci_adapter *adapter,
struct peci_board_info const *info)
{
struct peci_client *client;
@@ -2971,7 +3440,7 @@ index 6f241469ec7e..e2ef013e5002 100644
/* Increase reference count for the adapter assigned */
if (!peci_get_adapter(adapter->nr))
-@@ -847,46 +939,49 @@ static struct peci_client *peci_new_device(struct peci_adapter *adapter,
+@@ -847,46 +945,49 @@ static struct peci_client *peci_new_device(struct peci_adapter *adapter,
client->addr = info->addr;
strlcpy(client->name, info->type, sizeof(client->name));
@@ -3033,7 +3502,7 @@ index 6f241469ec7e..e2ef013e5002 100644
return NULL;
}
-@@ -895,8 +990,10 @@ static void peci_unregister_device(struct peci_client *client)
+@@ -895,8 +996,10 @@ static void peci_unregister_device(struct peci_client *client)
if (!client)
return;
@@ -3045,7 +3514,7 @@ index 6f241469ec7e..e2ef013e5002 100644
device_unregister(&client->dev);
}
-@@ -916,7 +1013,7 @@ static void peci_adapter_dev_release(struct device *dev)
+@@ -916,7 +1019,7 @@ static void peci_adapter_dev_release(struct device *dev)
dev_dbg(dev, "%s: %s\n", __func__, adapter->name);
mutex_destroy(&adapter->userspace_clients_lock);
@@ -3054,7 +3523,7 @@ index 6f241469ec7e..e2ef013e5002 100644
kfree(adapter);
}
-@@ -928,7 +1025,8 @@ static ssize_t peci_sysfs_new_device(struct device *dev,
+@@ -928,7 +1031,8 @@ static ssize_t peci_sysfs_new_device(struct device *dev,
struct peci_board_info info = {};
struct peci_client *client;
char *blank, end;
@@ -3064,7 +3533,7 @@ index 6f241469ec7e..e2ef013e5002 100644
/* Parse device type */
blank = strchr(buf, ' ');
-@@ -943,16 +1041,17 @@ static ssize_t peci_sysfs_new_device(struct device *dev,
+@@ -943,16 +1047,17 @@ static ssize_t peci_sysfs_new_device(struct device *dev,
memcpy(info.type, buf, blank - buf);
/* Parse remaining parameters, reject extra parameters */
@@ -3085,7 +3554,7 @@ index 6f241469ec7e..e2ef013e5002 100644
client = peci_new_device(adapter, &info);
if (!client)
return -EINVAL;
-@@ -961,8 +1060,8 @@ static ssize_t peci_sysfs_new_device(struct device *dev,
+@@ -961,8 +1066,8 @@ static ssize_t peci_sysfs_new_device(struct device *dev,
mutex_lock(&adapter->userspace_clients_lock);
list_add_tail(&client->detected, &adapter->userspace_clients);
mutex_unlock(&adapter->userspace_clients_lock);
@@ -3096,7 +3565,7 @@ index 6f241469ec7e..e2ef013e5002 100644
return count;
}
-@@ -975,9 +1074,9 @@ static ssize_t peci_sysfs_delete_device(struct device *dev,
+@@ -975,9 +1080,9 @@ static ssize_t peci_sysfs_delete_device(struct device *dev,
struct peci_adapter *adapter = to_peci_adapter(dev);
struct peci_client *client, *next;
struct peci_board_info info = {};
@@ -3108,7 +3577,7 @@ index 6f241469ec7e..e2ef013e5002 100644
/* Parse device type */
blank = strchr(buf, ' ');
-@@ -992,41 +1091,41 @@ static ssize_t peci_sysfs_delete_device(struct device *dev,
+@@ -992,41 +1097,41 @@ static ssize_t peci_sysfs_delete_device(struct device *dev,
memcpy(info.type, buf, blank - buf);
/* Parse remaining parameters, reject extra parameters */
@@ -3162,7 +3631,7 @@ index 6f241469ec7e..e2ef013e5002 100644
}
static DEVICE_ATTR_IGNORE_LOCKDEP(delete_device, 0200, NULL,
peci_sysfs_delete_device);
-@@ -1039,10 +1138,11 @@ static struct attribute *peci_adapter_attrs[] = {
+@@ -1039,10 +1144,11 @@ static struct attribute *peci_adapter_attrs[] = {
};
ATTRIBUTE_GROUPS(peci_adapter);
@@ -3175,7 +3644,7 @@ index 6f241469ec7e..e2ef013e5002 100644
/**
* peci_verify_adapter - return parameter as peci_adapter, or NULL
-@@ -1063,32 +1163,26 @@ static struct peci_client *peci_of_register_device(struct peci_adapter *adapter,
+@@ -1063,32 +1169,26 @@ static struct peci_client *peci_of_register_device(struct peci_adapter *adapter,
struct device_node *node)
{
struct peci_board_info info = {};
@@ -3220,7 +3689,7 @@ index 6f241469ec7e..e2ef013e5002 100644
}
static void peci_of_register_devices(struct peci_adapter *adapter)
-@@ -1119,7 +1213,7 @@ static void peci_of_register_devices(struct peci_adapter *adapter)
+@@ -1119,7 +1219,7 @@ static void peci_of_register_devices(struct peci_adapter *adapter)
of_node_put(bus);
}
@@ -3229,7 +3698,7 @@ index 6f241469ec7e..e2ef013e5002 100644
static void peci_of_register_devices(struct peci_adapter *adapter) { }
#endif /* CONFIG_OF */
-@@ -1163,9 +1257,7 @@ static struct peci_adapter *peci_of_find_adapter(struct device_node *node)
+@@ -1163,9 +1263,7 @@ static struct peci_adapter *peci_of_find_adapter(struct device_node *node)
return adapter;
}
@@ -3240,7 +3709,7 @@ index 6f241469ec7e..e2ef013e5002 100644
{
struct of_reconfig_data *rd = arg;
struct peci_adapter *adapter;
-@@ -1216,7 +1308,7 @@ static int peci_of_notify(struct notifier_block *nb,
+@@ -1216,7 +1314,7 @@ static int peci_of_notify(struct notifier_block *nb,
static struct notifier_block peci_of_notifier = {
.notifier_call = peci_of_notify,
};
@@ -3249,7 +3718,7 @@ index 6f241469ec7e..e2ef013e5002 100644
extern struct notifier_block peci_of_notifier;
#endif /* CONFIG_OF_DYNAMIC */
-@@ -1240,7 +1332,7 @@ extern struct notifier_block peci_of_notifier;
+@@ -1240,7 +1338,7 @@ extern struct notifier_block peci_of_notifier;
*
* Return: the peci_adapter structure on success, else NULL.
*/
@@ -3258,7 +3727,7 @@ index 6f241469ec7e..e2ef013e5002 100644
{
struct peci_adapter *adapter;
-@@ -1263,7 +1355,7 @@ EXPORT_SYMBOL_GPL(peci_alloc_adapter);
+@@ -1263,7 +1361,7 @@ EXPORT_SYMBOL_GPL(peci_alloc_adapter);
static int peci_register_adapter(struct peci_adapter *adapter)
{
@@ -3267,7 +3736,7 @@ index 6f241469ec7e..e2ef013e5002 100644
/* Can't register until after driver model init */
if (WARN_ON(!is_registered))
-@@ -1275,27 +1367,17 @@ static int peci_register_adapter(struct peci_adapter *adapter)
+@@ -1275,27 +1373,17 @@ static int peci_register_adapter(struct peci_adapter *adapter)
if (WARN(!adapter->xfer, "peci adapter has no xfer function\n"))
goto err_free_idr;
@@ -3300,7 +3769,7 @@ index 6f241469ec7e..e2ef013e5002 100644
}
dev_dbg(&adapter->dev, "adapter [%s] registered\n", adapter->name);
-@@ -1309,13 +1391,11 @@ static int peci_register_adapter(struct peci_adapter *adapter)
+@@ -1309,13 +1397,11 @@ static int peci_register_adapter(struct peci_adapter *adapter)
return 0;
@@ -3315,7 +3784,7 @@ index 6f241469ec7e..e2ef013e5002 100644
}
static int peci_add_numbered_adapter(struct peci_adapter *adapter)
-@@ -1411,7 +1491,7 @@ void peci_del_adapter(struct peci_adapter *adapter)
+@@ -1411,7 +1497,7 @@ void peci_del_adapter(struct peci_adapter *adapter)
}
mutex_unlock(&adapter->userspace_clients_lock);
@@ -3324,7 +3793,7 @@ index 6f241469ec7e..e2ef013e5002 100644
* Detach any active clients. This can't fail, thus we do not
* check the returned value.
*/
-@@ -1420,13 +1500,8 @@ void peci_del_adapter(struct peci_adapter *adapter)
+@@ -1420,13 +1506,8 @@ void peci_del_adapter(struct peci_adapter *adapter)
/* device name is gone after device_unregister */
dev_dbg(&adapter->dev, "adapter [%s] unregistered\n", adapter->name);
@@ -3338,7 +3807,7 @@ index 6f241469ec7e..e2ef013e5002 100644
device_unregister(&adapter->dev);
/* free bus id */
-@@ -1436,6 +1511,18 @@ void peci_del_adapter(struct peci_adapter *adapter)
+@@ -1436,6 +1517,18 @@ void peci_del_adapter(struct peci_adapter *adapter)
}
EXPORT_SYMBOL_GPL(peci_del_adapter);
@@ -3357,7 +3826,7 @@ index 6f241469ec7e..e2ef013e5002 100644
/**
* peci_register_driver - register a PECI driver
* @owner: owner module of the driver being registered
-@@ -1446,7 +1533,7 @@ EXPORT_SYMBOL_GPL(peci_del_adapter);
+@@ -1446,7 +1539,7 @@ EXPORT_SYMBOL_GPL(peci_del_adapter);
*/
int peci_register_driver(struct module *owner, struct peci_driver *driver)
{
@@ -3366,7 +3835,7 @@ index 6f241469ec7e..e2ef013e5002 100644
/* Can't register until after driver model init */
if (WARN_ON(!is_registered))
-@@ -1456,13 +1543,13 @@ int peci_register_driver(struct module *owner, struct peci_driver *driver)
+@@ -1456,13 +1549,13 @@ int peci_register_driver(struct module *owner, struct peci_driver *driver)
driver->driver.owner = owner;
driver->driver.bus = &peci_bus_type;
@@ -3384,7 +3853,7 @@ index 6f241469ec7e..e2ef013e5002 100644
pr_debug("driver [%s] registered\n", driver->driver.name);
-@@ -1492,13 +1579,6 @@ static int __init peci_init(void)
+@@ -1492,13 +1585,6 @@ static int __init peci_init(void)
return ret;
}
@@ -3398,7 +3867,7 @@ index 6f241469ec7e..e2ef013e5002 100644
crc8_populate_msb(peci_crc8_table, PECI_CRC8_POLYNOMIAL);
if (IS_ENABLED(CONFIG_OF_DYNAMIC))
-@@ -1514,11 +1594,10 @@ static void __exit peci_exit(void)
+@@ -1514,11 +1600,10 @@ static void __exit peci_exit(void)
if (IS_ENABLED(CONFIG_OF_DYNAMIC))
WARN_ON(of_reconfig_notifier_unregister(&peci_of_notifier));
@@ -3413,10 +3882,10 @@ index 6f241469ec7e..e2ef013e5002 100644
MODULE_AUTHOR("Jason M Biils <jason.m.bills@linux.intel.com>");
diff --git a/drivers/peci/peci-dev.c b/drivers/peci/peci-dev.c
new file mode 100644
-index 000000000000..5de0683206bc
+index 000000000000..ac9cba0fb429
--- /dev/null
+++ b/drivers/peci/peci-dev.c
-@@ -0,0 +1,340 @@
+@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018-2019 Intel Corporation
+
@@ -3517,9 +3986,9 @@ index 000000000000..5de0683206bc
+static long peci_dev_ioctl(struct file *file, uint iocmd, ulong arg)
+{
+ struct peci_dev *peci_dev = file->private_data;
-+ struct peci_xfer_msg __user *uxmsg;
++ void __user *umsg = (void __user *)arg;
+ struct peci_xfer_msg *xmsg = NULL;
-+ void __user *umsg;
++ struct peci_xfer_msg uxmsg;
+ enum peci_cmd cmd;
+ u8 *msg = NULL;
+ uint msg_len;
@@ -3535,30 +4004,35 @@ index 000000000000..5de0683206bc
+ break;
+ }
+
-+ uxmsg = (struct peci_xfer_msg __user *)arg;
-+ xmsg = peci_get_xfer_msg(uxmsg->tx_len, uxmsg->rx_len);
++ if (copy_from_user(&uxmsg, umsg, msg_len)) {
++ ret = -EFAULT;
++ break;
++ }
++
++ xmsg = peci_get_xfer_msg(uxmsg.tx_len, uxmsg.rx_len);
+ if (IS_ERR(xmsg)) {
+ ret = PTR_ERR(xmsg);
+ break;
+ }
+
-+ if (uxmsg->tx_len &&
-+ copy_from_user(uxmsg->tx_buf, xmsg->tx_buf,
-+ uxmsg->tx_len)) {
++ if (uxmsg.tx_len &&
++ copy_from_user(xmsg->tx_buf, uxmsg.tx_buf, uxmsg.tx_len)) {
+ ret = -EFAULT;
+ break;
+ }
+
++ xmsg->addr = uxmsg.addr;
++ xmsg->tx_len = uxmsg.tx_len;
++ xmsg->rx_len = uxmsg.rx_len;
++
+ ret = peci_command(peci_dev->adapter, cmd, xmsg);
-+ if (!ret && uxmsg->rx_len &&
-+ copy_to_user(xmsg->rx_buf, uxmsg->rx_buf,
-+ uxmsg->rx_len))
++ if (!ret && xmsg->rx_len &&
++ copy_to_user(uxmsg.rx_buf, xmsg->rx_buf, xmsg->rx_len))
+ ret = -EFAULT;
+
+ break;
+
+ default:
-+ umsg = (void __user *)arg;
+ msg = memdup_user(umsg, msg_len);
+ if (IS_ERR(msg)) {
+ ret = PTR_ERR(msg);
@@ -3566,7 +4040,8 @@ index 000000000000..5de0683206bc
+ }
+
+ ret = peci_command(peci_dev->adapter, cmd, msg);
-+ if (!ret && copy_to_user(umsg, msg, msg_len))
++ if ((!ret || ret == -ETIMEDOUT) &&
++ copy_to_user(umsg, msg, msg_len))
+ ret = -EFAULT;
+
+ break;
@@ -3757,8 +4232,424 @@ index 000000000000..5de0683206bc
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>");
+MODULE_DESCRIPTION("PECI /dev entries driver");
+MODULE_LICENSE("GPL v2");
+diff --git a/drivers/peci/peci-npcm.c b/drivers/peci/peci-npcm.c
+deleted file mode 100644
+index f632365b1416..000000000000
+--- a/drivers/peci/peci-npcm.c
++++ /dev/null
+@@ -1,410 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0
+-// Copyright (c) 2019 Nuvoton Technology corporation.
+-
+-#include <linux/bitfield.h>
+-#include <linux/clk.h>
+-#include <linux/interrupt.h>
+-#include <linux/jiffies.h>
+-#include <linux/module.h>
+-#include <linux/of.h>
+-#include <linux/peci.h>
+-#include <linux/platform_device.h>
+-#include <linux/regmap.h>
+-#include <linux/mfd/syscon.h>
+-#include <linux/reset.h>
+-
+-/* NPCM7xx GCR module */
+-#define NPCM7XX_INTCR3_OFFSET 0x9C
+-#define NPCM7XX_INTCR3_PECIVSEL BIT(19)
+-
+-/* NPCM PECI Registers */
+-#define NPCM_PECI_CTL_STS 0x00
+-#define NPCM_PECI_RD_LENGTH 0x04
+-#define NPCM_PECI_ADDR 0x08
+-#define NPCM_PECI_CMD 0x0C
+-#define NPCM_PECI_CTL2 0x10
+-#define NPCM_PECI_WR_LENGTH 0x1C
+-#define NPCM_PECI_PDDR 0x2C
+-#define NPCM_PECI_DAT_INOUT(n) (0x100 + ((n) * 4))
+-
+-#define NPCM_PECI_MAX_REG 0x200
+-
+-/* NPCM_PECI_CTL_STS - 0x00 : Control Register */
+-#define NPCM_PECI_CTRL_DONE_INT_EN BIT(6)
+-#define NPCM_PECI_CTRL_ABRT_ERR BIT(4)
+-#define NPCM_PECI_CTRL_CRC_ERR BIT(3)
+-#define NPCM_PECI_CTRL_DONE BIT(1)
+-#define NPCM_PECI_CTRL_START_BUSY BIT(0)
+-
+-/* NPCM_PECI_RD_LENGTH - 0x04 : Command Register */
+-#define NPCM_PECI_RD_LEN_MASK GENMASK(6, 0)
+-
+-/* NPCM_PECI_CMD - 0x10 : Command Register */
+-#define NPCM_PECI_CTL2_MASK GENMASK(7, 6)
+-
+-/* NPCM_PECI_WR_LENGTH - 0x1C : Command Register */
+-#define NPCM_PECI_WR_LEN_MASK GENMASK(6, 0)
+-
+-/* NPCM_PECI_PDDR - 0x2C : Command Register */
+-#define NPCM_PECI_PDDR_MASK GENMASK(4, 0)
+-
+-#define NPCM_PECI_INT_MASK (NPCM_PECI_CTRL_ABRT_ERR | \
+- NPCM_PECI_CTRL_CRC_ERR | \
+- NPCM_PECI_CTRL_DONE)
+-
+-#define NPCM_PECI_IDLE_CHECK_TIMEOUT_USEC 50000
+-#define NPCM_PECI_IDLE_CHECK_INTERVAL_USEC 10000
+-#define NPCM_PECI_CMD_TIMEOUT_MS_DEFAULT 1000
+-#define NPCM_PECI_CMD_TIMEOUT_MS_MAX 60000
+-#define NPCM_PECI_HOST_NEG_BIT_RATE_MAX 31
+-#define NPCM_PECI_HOST_NEG_BIT_RATE_MIN 7
+-#define NPCM_PECI_HOST_NEG_BIT_RATE_DEFAULT 15
+-#define NPCM_PECI_PULL_DOWN_DEFAULT 0
+-#define NPCM_PECI_PULL_DOWN_MAX 2
+-
+-struct npcm_peci {
+- u32 cmd_timeout_ms;
+- u32 host_bit_rate;
+- struct completion xfer_complete;
+- struct regmap *gcr_regmap;
+- struct peci_adapter *adapter;
+- struct regmap *regmap;
+- u32 status;
+- spinlock_t lock; /* to sync completion status handling */
+- struct device *dev;
+- struct clk *clk;
+- int irq;
+-};
+-
+-static int npcm_peci_xfer_native(struct npcm_peci *priv,
+- struct peci_xfer_msg *msg)
+-{
+- long err, timeout = msecs_to_jiffies(priv->cmd_timeout_ms);
+- unsigned long flags;
+- unsigned int msg_rd;
+- u32 cmd_sts;
+- int i, rc;
+-
+- /* Check command sts and bus idle state */
+- rc = regmap_read_poll_timeout(priv->regmap, NPCM_PECI_CTL_STS, cmd_sts,
+- !(cmd_sts & NPCM_PECI_CTRL_START_BUSY),
+- NPCM_PECI_IDLE_CHECK_INTERVAL_USEC,
+- NPCM_PECI_IDLE_CHECK_TIMEOUT_USEC);
+- if (rc)
+- return rc; /* -ETIMEDOUT */
+-
+- spin_lock_irqsave(&priv->lock, flags);
+- reinit_completion(&priv->xfer_complete);
+-
+- regmap_write(priv->regmap, NPCM_PECI_ADDR, msg->addr);
+- regmap_write(priv->regmap, NPCM_PECI_RD_LENGTH,
+- NPCM_PECI_WR_LEN_MASK & msg->rx_len);
+- regmap_write(priv->regmap, NPCM_PECI_WR_LENGTH,
+- NPCM_PECI_WR_LEN_MASK & msg->tx_len);
+-
+- if (msg->tx_len) {
+- regmap_write(priv->regmap, NPCM_PECI_CMD, msg->tx_buf[0]);
+-
+- for (i = 0; i < (msg->tx_len - 1); i++)
+- regmap_write(priv->regmap, NPCM_PECI_DAT_INOUT(i),
+- msg->tx_buf[i + 1]);
+- }
+-
+- priv->status = 0;
+- regmap_update_bits(priv->regmap, NPCM_PECI_CTL_STS,
+- NPCM_PECI_CTRL_START_BUSY,
+- NPCM_PECI_CTRL_START_BUSY);
+-
+- spin_unlock_irqrestore(&priv->lock, flags);
+-
+- err = wait_for_completion_interruptible_timeout(&priv->xfer_complete,
+- timeout);
+-
+- spin_lock_irqsave(&priv->lock, flags);
+-
+- regmap_write(priv->regmap, NPCM_PECI_CMD, 0);
+-
+- if (err <= 0 || priv->status != NPCM_PECI_CTRL_DONE) {
+- if (err < 0) { /* -ERESTARTSYS */
+- rc = (int)err;
+- goto err_irqrestore;
+- } else if (err == 0) {
+- dev_dbg(priv->dev, "Timeout waiting for a response!\n");
+- rc = -ETIMEDOUT;
+- goto err_irqrestore;
+- }
+-
+- dev_dbg(priv->dev, "No valid response!\n");
+- rc = -EIO;
+- goto err_irqrestore;
+- }
+-
+- for (i = 0; i < msg->rx_len; i++) {
+- regmap_read(priv->regmap, NPCM_PECI_DAT_INOUT(i), &msg_rd);
+- msg->rx_buf[i] = (u8)msg_rd;
+- }
+-
+-err_irqrestore:
+- spin_unlock_irqrestore(&priv->lock, flags);
+- return rc;
+-}
+-
+-static irqreturn_t npcm_peci_irq_handler(int irq, void *arg)
+-{
+- struct npcm_peci *priv = arg;
+- u32 status_ack = 0;
+- u32 status;
+-
+- spin_lock(&priv->lock);
+- regmap_read(priv->regmap, NPCM_PECI_CTL_STS, &status);
+- priv->status |= (status & NPCM_PECI_INT_MASK);
+-
+- if (status & NPCM_PECI_CTRL_CRC_ERR) {
+- dev_dbg(priv->dev, "PECI_INT_W_FCS_BAD\n");
+- status_ack |= NPCM_PECI_CTRL_CRC_ERR;
+- }
+-
+- if (status & NPCM_PECI_CTRL_ABRT_ERR) {
+- dev_dbg(priv->dev, "NPCM_PECI_CTRL_ABRT_ERR\n");
+- status_ack |= NPCM_PECI_CTRL_ABRT_ERR;
+- }
+-
+- /*
+- * All commands should be ended up with a NPCM_PECI_CTRL_DONE
+- * bit set even in an error case.
+- */
+- if (status & NPCM_PECI_CTRL_DONE) {
+- dev_dbg(priv->dev, "NPCM_PECI_CTRL_DONE\n");
+- status_ack |= NPCM_PECI_CTRL_DONE;
+- complete(&priv->xfer_complete);
+- }
+-
+- regmap_write_bits(priv->regmap, NPCM_PECI_CTL_STS,
+- NPCM_PECI_INT_MASK, status_ack);
+-
+- spin_unlock(&priv->lock);
+- return IRQ_HANDLED;
+-}
+-
+-static int npcm_peci_init_ctrl(struct npcm_peci *priv)
+-{
+- u32 cmd_sts, host_neg_bit_rate = 0, pull_down = 0;
+- int ret;
+- bool volt;
+-
+- priv->clk = devm_clk_get(priv->dev, NULL);
+- if (IS_ERR(priv->clk)) {
+- dev_err(priv->dev, "Failed to get clk source.\n");
+- return PTR_ERR(priv->clk);
+- }
+-
+- ret = clk_prepare_enable(priv->clk);
+- if (ret) {
+- dev_err(priv->dev, "Failed to enable clock.\n");
+- return ret;
+- }
+-
+- ret = of_property_read_u32(priv->dev->of_node, "cmd-timeout-ms",
+- &priv->cmd_timeout_ms);
+- if (ret || priv->cmd_timeout_ms > NPCM_PECI_CMD_TIMEOUT_MS_MAX ||
+- priv->cmd_timeout_ms == 0) {
+- if (ret)
+- dev_warn(priv->dev,
+- "cmd-timeout-ms not found, use default : %u\n",
+- NPCM_PECI_CMD_TIMEOUT_MS_DEFAULT);
+- else
+- dev_warn(priv->dev,
+- "Invalid cmd-timeout-ms : %u. Use default : %u\n",
+- priv->cmd_timeout_ms,
+- NPCM_PECI_CMD_TIMEOUT_MS_DEFAULT);
+-
+- priv->cmd_timeout_ms = NPCM_PECI_CMD_TIMEOUT_MS_DEFAULT;
+- }
+-
+- if (of_device_is_compatible(priv->dev->of_node,
+- "nuvoton,npcm750-peci")) {
+- priv->gcr_regmap = syscon_regmap_lookup_by_compatible
+- ("nuvoton,npcm750-gcr");
+- if (!IS_ERR(priv->gcr_regmap)) {
+- volt = of_property_read_bool(priv->dev->of_node,
+- "high-volt-range");
+- if (volt)
+- regmap_update_bits(priv->gcr_regmap,
+- NPCM7XX_INTCR3_OFFSET,
+- NPCM7XX_INTCR3_PECIVSEL,
+- NPCM7XX_INTCR3_PECIVSEL);
+- else
+- regmap_update_bits(priv->gcr_regmap,
+- NPCM7XX_INTCR3_OFFSET,
+- NPCM7XX_INTCR3_PECIVSEL, 0);
+- }
+- }
+-
+- ret = of_property_read_u32(priv->dev->of_node, "pull-down",
+- &pull_down);
+- if (ret || pull_down > NPCM_PECI_PULL_DOWN_MAX) {
+- if (ret)
+- dev_warn(priv->dev,
+- "pull-down not found, use default : %u\n",
+- NPCM_PECI_PULL_DOWN_DEFAULT);
+- else
+- dev_warn(priv->dev,
+- "Invalid pull-down : %u. Use default : %u\n",
+- pull_down,
+- NPCM_PECI_PULL_DOWN_DEFAULT);
+- pull_down = NPCM_PECI_PULL_DOWN_DEFAULT;
+- }
+-
+- regmap_update_bits(priv->regmap, NPCM_PECI_CTL2, NPCM_PECI_CTL2_MASK,
+- pull_down << 6);
+-
+- ret = of_property_read_u32(priv->dev->of_node, "host-neg-bit-rate",
+- &host_neg_bit_rate);
+- if (ret || host_neg_bit_rate > NPCM_PECI_HOST_NEG_BIT_RATE_MAX ||
+- host_neg_bit_rate < NPCM_PECI_HOST_NEG_BIT_RATE_MIN) {
+- if (ret)
+- dev_warn(priv->dev,
+- "host-neg-bit-rate not found, use default : %u\n",
+- NPCM_PECI_HOST_NEG_BIT_RATE_DEFAULT);
+- else
+- dev_warn(priv->dev,
+- "Invalid host-neg-bit-rate : %u. Use default : %u\n",
+- host_neg_bit_rate,
+- NPCM_PECI_HOST_NEG_BIT_RATE_DEFAULT);
+- host_neg_bit_rate = NPCM_PECI_HOST_NEG_BIT_RATE_DEFAULT;
+- }
+-
+- regmap_update_bits(priv->regmap, NPCM_PECI_PDDR, NPCM_PECI_PDDR_MASK,
+- host_neg_bit_rate);
+-
+- priv->host_bit_rate = clk_get_rate(priv->clk) /
+- (4 * (host_neg_bit_rate + 1));
+-
+- ret = regmap_read_poll_timeout(priv->regmap, NPCM_PECI_CTL_STS, cmd_sts,
+- !(cmd_sts & NPCM_PECI_CTRL_START_BUSY),
+- NPCM_PECI_IDLE_CHECK_INTERVAL_USEC,
+- NPCM_PECI_IDLE_CHECK_TIMEOUT_USEC);
+- if (ret)
+- return ret; /* -ETIMEDOUT */
+-
+- /* PECI interrupt enable */
+- regmap_update_bits(priv->regmap, NPCM_PECI_CTL_STS,
+- NPCM_PECI_CTRL_DONE_INT_EN,
+- NPCM_PECI_CTRL_DONE_INT_EN);
+-
+- return 0;
+-}
+-
+-static const struct regmap_config npcm_peci_regmap_config = {
+- .reg_bits = 8,
+- .val_bits = 8,
+- .max_register = NPCM_PECI_MAX_REG,
+- .fast_io = true,
+-};
+-
+-static int npcm_peci_xfer(struct peci_adapter *adapter,
+- struct peci_xfer_msg *msg)
+-{
+- struct npcm_peci *priv = peci_get_adapdata(adapter);
+-
+- return npcm_peci_xfer_native(priv, msg);
+-}
+-
+-static int npcm_peci_probe(struct platform_device *pdev)
+-{
+- struct peci_adapter *adapter;
+- struct npcm_peci *priv;
+- struct resource *res;
+- void __iomem *base;
+- int ret;
+-
+- adapter = peci_alloc_adapter(&pdev->dev, sizeof(*priv));
+- if (!adapter)
+- return -ENOMEM;
+-
+- priv = peci_get_adapdata(adapter);
+- priv->adapter = adapter;
+- priv->dev = &pdev->dev;
+- dev_set_drvdata(&pdev->dev, priv);
+-
+- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- base = devm_ioremap_resource(&pdev->dev, res);
+- if (IS_ERR(base)) {
+- ret = PTR_ERR(base);
+- goto err_put_adapter_dev;
+- }
+-
+- priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+- &npcm_peci_regmap_config);
+- if (IS_ERR(priv->regmap)) {
+- ret = PTR_ERR(priv->regmap);
+- goto err_put_adapter_dev;
+- }
+-
+- priv->irq = platform_get_irq(pdev, 0);
+- if (!priv->irq) {
+- ret = -ENODEV;
+- goto err_put_adapter_dev;
+- }
+-
+- ret = devm_request_irq(&pdev->dev, priv->irq, npcm_peci_irq_handler,
+- 0, "peci-npcm-irq", priv);
+- if (ret)
+- goto err_put_adapter_dev;
+-
+- init_completion(&priv->xfer_complete);
+- spin_lock_init(&priv->lock);
+-
+- priv->adapter->owner = THIS_MODULE;
+- priv->adapter->dev.of_node = of_node_get(dev_of_node(priv->dev));
+- strlcpy(priv->adapter->name, pdev->name, sizeof(priv->adapter->name));
+- priv->adapter->xfer = npcm_peci_xfer;
+-
+- ret = npcm_peci_init_ctrl(priv);
+- if (ret)
+- goto err_put_adapter_dev;
+-
+- ret = peci_add_adapter(priv->adapter);
+- if (ret)
+- goto err_put_adapter_dev;
+-
+- dev_info(&pdev->dev, "peci bus %d registered, host negotiation bit rate %dHz",
+- priv->adapter->nr, priv->host_bit_rate);
+-
+- return 0;
+-
+-err_put_adapter_dev:
+- put_device(&adapter->dev);
+- return ret;
+-}
+-
+-static int npcm_peci_remove(struct platform_device *pdev)
+-{
+- struct npcm_peci *priv = dev_get_drvdata(&pdev->dev);
+-
+- clk_disable_unprepare(priv->clk);
+- peci_del_adapter(priv->adapter);
+- of_node_put(priv->adapter->dev.of_node);
+-
+- return 0;
+-}
+-
+-static const struct of_device_id npcm_peci_of_table[] = {
+- { .compatible = "nuvoton,npcm750-peci", },
+- { }
+-};
+-MODULE_DEVICE_TABLE(of, npcm_peci_of_table);
+-
+-static struct platform_driver npcm_peci_driver = {
+- .probe = npcm_peci_probe,
+- .remove = npcm_peci_remove,
+- .driver = {
+- .name = "peci-npcm",
+- .of_match_table = of_match_ptr(npcm_peci_of_table),
+- },
+-};
+-module_platform_driver(npcm_peci_driver);
+-
+-MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
+-MODULE_DESCRIPTION("NPCM Platform Environment Control Interface (PECI) driver");
+-MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/intel-peci-client.h b/include/linux/mfd/intel-peci-client.h
-index 8f6d823a59cd..1f1b07a9aeab 100644
+index 8f6d823a59cd..7b62a02e46ee 100644
--- a/include/linux/mfd/intel-peci-client.h
+++ b/include/linux/mfd/intel-peci-client.h
@@ -1,5 +1,5 @@
@@ -3768,7 +4659,7 @@ index 8f6d823a59cd..1f1b07a9aeab 100644
#ifndef __LINUX_MFD_INTEL_PECI_CLIENT_H
#define __LINUX_MFD_INTEL_PECI_CLIENT_H
-@@ -9,7 +9,7 @@
+@@ -9,14 +9,15 @@
#if IS_ENABLED(CONFIG_X86)
#include <asm/intel-family.h>
#else
@@ -3777,7 +4668,29 @@ index 8f6d823a59cd..1f1b07a9aeab 100644
* Architectures other than x86 cannot include the header file so define these
* at here. These are needed for detecting type of client x86 CPUs behind a PECI
* connection.
-@@ -58,7 +58,6 @@ struct cpu_gen_info {
+ */
+-#define INTEL_FAM6_HASWELL_X 0x3F
+-#define INTEL_FAM6_BROADWELL_X 0x4F
+-#define INTEL_FAM6_SKYLAKE_X 0x55
++#define INTEL_FAM6_HASWELL_X 0x3F
++#define INTEL_FAM6_BROADWELL_X 0x4F
++#define INTEL_FAM6_BROADWELL_XEON_D 0x56
++#define INTEL_FAM6_SKYLAKE_X 0x55
+ #endif
+
+ #define CORE_MAX_ON_HSX 18 /* Max number of cores on Haswell */
+@@ -27,6 +28,10 @@
+ #define CHAN_RANK_MAX_ON_BDX 4 /* Max number of channel ranks on Broadwell */
+ #define DIMM_IDX_MAX_ON_BDX 3 /* Max DIMM index per channel on Broadwell */
+
++#define CORE_MAX_ON_XD 16 /* Max number of cores on Xeon D */
++#define CHAN_RANK_MAX_ON_XD 2 /* Max number of channel ranks on Xeon D */
++#define DIMM_IDX_MAX_ON_XD 2 /* Max DIMM index per channel on Xeon D */
++
+ #define CORE_MAX_ON_SKX 28 /* Max number of cores on Skylake */
+ #define CHAN_RANK_MAX_ON_SKX 6 /* Max number of channel ranks on Skylake */
+ #define DIMM_IDX_MAX_ON_SKX 2 /* Max DIMM index per channel on Skylake */
+@@ -58,7 +63,6 @@ struct cpu_gen_info {
/**
* struct peci_client_manager - PECI client manager information
* @client; pointer to the PECI client
@@ -3785,7 +4698,7 @@ index 8f6d823a59cd..1f1b07a9aeab 100644
* @name: PECI client manager name
* @gen_info: CPU generation info of the detected CPU
*
-@@ -67,7 +66,6 @@ struct cpu_gen_info {
+@@ -67,7 +71,6 @@ struct cpu_gen_info {
*/
struct peci_client_manager {
struct peci_client *client;
@@ -3793,6 +4706,35 @@ index 8f6d823a59cd..1f1b07a9aeab 100644
char name[PECI_NAME_SIZE];
const struct cpu_gen_info *gen_info;
};
+@@ -93,18 +96,23 @@ peci_client_read_package_config(struct peci_client_manager *priv,
+ u8 index, u16 param, u8 *data)
+ {
+ struct peci_rd_pkg_cfg_msg msg;
+- int rc;
++ int ret;
+
+ msg.addr = priv->client->addr;
+ msg.index = index;
+ msg.param = param;
+ msg.rx_len = 4;
+
+- rc = peci_command(priv->client->adapter, PECI_CMD_RD_PKG_CFG, &msg);
+- if (!rc)
+- memcpy(data, msg.pkg_config, 4);
++ ret = peci_command(priv->client->adapter, PECI_CMD_RD_PKG_CFG, &msg);
++ if (ret)
++ return ret;
++
++ if (msg.cc != PECI_DEV_CC_SUCCESS)
++ return -EAGAIN;
++
++ memcpy(data, msg.pkg_config, 4);
+
+- return rc;
++ return 0;
+ }
+
+ #endif /* __LINUX_MFD_INTEL_PECI_CLIENT_H */
diff --git a/include/linux/peci.h b/include/linux/peci.h
index d0e47d45d1d0..6fc424dc2a73 100644
--- a/include/linux/peci.h
@@ -3890,7 +4832,7 @@ index d0e47d45d1d0..6fc424dc2a73 100644
int peci_get_cpu_id(struct peci_adapter *adapter, u8 addr, u32 *cpu_id);
diff --git a/include/uapi/linux/peci-ioctl.h b/include/uapi/linux/peci-ioctl.h
-index a6dae71cbff5..8467b2fbee1f 100644
+index a6dae71cbff5..253fb42e38b7 100644
--- a/include/uapi/linux/peci-ioctl.h
+++ b/include/uapi/linux/peci-ioctl.h
@@ -1,5 +1,5 @@
@@ -3900,7 +4842,7 @@ index a6dae71cbff5..8467b2fbee1f 100644
#ifndef __PECI_IOCTL_H
#define __PECI_IOCTL_H
-@@ -7,136 +7,34 @@
+@@ -7,136 +7,35 @@
#include <linux/ioctl.h>
#include <linux/types.h>
@@ -3981,13 +4923,13 @@ index a6dae71cbff5..8467b2fbee1f 100644
-#define MBX_INDEX_DIMM_AMBIENT 19
-#define MBX_INDEX_DIMM_TEMP 24
+/* The PECI client's default address of 0x30 */
-+#define PECI_BASE_ADDR 0x30
++#define PECI_BASE_ADDR 0x30
+
+/* Max number of CPU clients */
-+#define PECI_OFFSET_MAX 8
++#define PECI_OFFSET_MAX 8
+
+/* PECI read/write data buffer size max */
-+#define PECI_BUFFER_SIZE 255
++#define PECI_BUFFER_SIZE 255
/* Device Specific Completion Code (CC) Definition */
-#define DEV_PECI_CC_SUCCESS 0x40
@@ -3995,17 +4937,22 @@ index a6dae71cbff5..8467b2fbee1f 100644
-#define DEV_PECI_CC_OUT_OF_RESOURCE 0x81
-#define DEV_PECI_CC_UNAVAIL_RESOURCE 0x82
-#define DEV_PECI_CC_INVALID_REQ 0x90
-+#define PECI_DEV_CC_SUCCESS 0x40
-+#define PECI_DEV_CC_TIMEOUT 0x80
-+#define PECI_DEV_CC_OUT_OF_RESOURCE 0x81
-+#define PECI_DEV_CC_UNAVAIL_RESOURCE 0x82
-+#define PECI_DEV_CC_INVALID_REQ 0x90
++#define PECI_DEV_CC_SUCCESS 0x40
++#define PECI_DEV_CC_NEED_RETRY 0x80
++#define PECI_DEV_CC_OUT_OF_RESOURCE 0x81
++#define PECI_DEV_CC_UNAVAIL_RESOURCE 0x82
++#define PECI_DEV_CC_INVALID_REQ 0x90
++#define PECI_DEV_CC_MCA_ERROR 0x91
++#define PECI_DEV_CC_CATASTROPHIC_MCA_ERROR 0x93
++#define PECI_DEV_CC_FATAL_MCA_DETECTED 0x94
++#define PECI_DEV_CC_PARITY_ERROR_ON_GPSB_OR_PMSB 0x98
++#define PECI_DEV_CC_PARITY_ERROR_ON_GPSB_OR_PMSB_IERR 0x9B
++#define PECI_DEV_CC_PARITY_ERROR_ON_GPSB_OR_PMSB_MCA 0x9C
/* Completion Code mask to check retry needs */
-#define DEV_PECI_CC_RETRY_CHECK_MASK 0xf0
-#define DEV_PECI_CC_NEED_RETRY 0x80
-+#define PECI_DEV_CC_RETRY_CHECK_MASK 0xf0
-+#define PECI_DEV_CC_NEED_RETRY 0x80
++#define PECI_DEV_CC_RETRY_CHECK_MASK 0xf0
/* Skylake EDS says to retry for 250ms */
-#define DEV_PECI_RETRY_TIME_MS 250
@@ -4037,13 +4984,9 @@ index a6dae71cbff5..8467b2fbee1f 100644
-#define RDPCICFG_WRITE_LEN 6
-#define RDPCICFG_READ_LEN 5
-#define RDPCICFG_PECI_CMD 0x61
-+#define PECI_DEV_RETRY_TIME_MS 250
-+#define PECI_DEV_RETRY_INTERVAL_USEC 10000
-+#define PECI_DEV_RETRY_BIT 0x01
-
+-
-#define WRPCICFG_PECI_CMD 0x65
-+#define PECI_WRIAMSR_CMD 0xb5
-
+-
-#define RDPCICFGLOCAL_WRITE_LEN 5
-#define RDPCICFGLOCAL_READ_LEN_BASE 1
-#define RDPCICFGLOCAL_PECI_CMD 0xe1
@@ -4053,11 +4996,13 @@ index a6dae71cbff5..8467b2fbee1f 100644
-#define WRPCICFGLOCAL_PECI_CMD 0xe5
-
-#define PECI_BUFFER_SIZE 32
-+#define PECI_WRPCICFG_CMD 0x65
++#define PECI_DEV_RETRY_TIME_MS 250
++#define PECI_DEV_RETRY_INTERVAL_USEC 10000
++#define PECI_DEV_RETRY_BIT 0x01
/**
* enum peci_cmd - PECI client commands
-@@ -186,11 +84,12 @@ enum peci_cmd {
+@@ -186,11 +85,12 @@ enum peci_cmd {
* raw PECI transfer
*/
struct peci_xfer_msg {
@@ -4075,7 +5020,7 @@ index a6dae71cbff5..8467b2fbee1f 100644
} __attribute__((__packed__));
/**
-@@ -202,7 +101,8 @@ struct peci_xfer_msg {
+@@ -202,7 +102,8 @@ struct peci_xfer_msg {
* powered-off, etc.
*/
struct peci_ping_msg {
@@ -4085,7 +5030,7 @@ index a6dae71cbff5..8467b2fbee1f 100644
} __attribute__((__packed__));
/**
-@@ -216,8 +116,13 @@ struct peci_ping_msg {
+@@ -216,8 +117,13 @@ struct peci_ping_msg {
* command.
*/
struct peci_get_dib_msg {
@@ -4101,7 +5046,7 @@ index a6dae71cbff5..8467b2fbee1f 100644
} __attribute__((__packed__));
/**
-@@ -232,8 +137,14 @@ struct peci_get_dib_msg {
+@@ -232,8 +138,13 @@ struct peci_get_dib_msg {
* below the maximum processor junction temperature.
*/
struct peci_get_temp_msg {
@@ -4112,13 +5057,20 @@ index a6dae71cbff5..8467b2fbee1f 100644
+#define PECI_GET_TEMP_CMD 0x01
+
+ __u8 addr;
-+ __u8 padding0[3];
++ __u8 padding;
+ __s16 temp_raw;
-+ __u8 padding1[2];
} __attribute__((__packed__));
/**
-@@ -251,11 +162,72 @@ struct peci_get_temp_msg {
+@@ -242,6 +153,7 @@ struct peci_get_temp_msg {
+ * @index: encoding index for the requested service
+ * @param: specific data being requested
+ * @rx_len: number of data to be read in bytes
++ * @cc: completion code
+ * @pkg_config: package config data to be read
+ *
+ * The RdPkgConfig() command provides read access to the Package Configuration
+@@ -251,11 +163,73 @@ struct peci_get_temp_msg {
* DIMM temperatures and so on.
*/
struct peci_rd_pkg_cfg_msg {
@@ -4191,12 +5143,21 @@ index a6dae71cbff5..8467b2fbee1f 100644
+#define PECI_PKG_ID_MACHINE_CHECK_STATUS 0x0005 /* Machine Check Status */
+
+ __u8 rx_len;
-+ __u8 padding[3];
++ __u8 cc;
++ __u8 padding[2];
+ __u8 pkg_config[4];
} __attribute__((__packed__));
/**
-@@ -272,11 +244,19 @@ struct peci_rd_pkg_cfg_msg {
+@@ -264,6 +238,7 @@ struct peci_rd_pkg_cfg_msg {
+ * @index: encoding index for the requested service
+ * @param: specific data being requested
+ * @tx_len: number of data to be written in bytes
++ * @cc: completion code
+ * @value: package config data to be written
+ *
+ * The WrPkgConfig() command provides write access to the Package Configuration
+@@ -272,11 +247,20 @@ struct peci_rd_pkg_cfg_msg {
* may include power limiting, thermal averaging constant programming and so on.
*/
struct peci_wr_pkg_cfg_msg {
@@ -4216,12 +5177,20 @@ index a6dae71cbff5..8467b2fbee1f 100644
+
+ __u16 param;
+ __u8 tx_len;
-+ __u8 padding[3];
++ __u8 cc;
++ __u8 padding[2];
+ __u32 value;
} __attribute__((__packed__));
/**
-@@ -290,10 +270,34 @@ struct peci_wr_pkg_cfg_msg {
+@@ -284,16 +268,47 @@ struct peci_wr_pkg_cfg_msg {
+ * @addr: address of the client
+ * @thread_id: ID of the specific logical processor
+ * @address: address of MSR to read from
++ * @cc: completion code
+ * @value: data to be read
+ *
+ * The RdIAMSR() PECI command provides read access to Model Specific Registers
* (MSRs) defined in the processor's Intel Architecture (IA).
*/
struct peci_rd_ia_msr_msg {
@@ -4236,6 +5205,8 @@ index a6dae71cbff5..8467b2fbee1f 100644
+ __u8 addr;
+ __u8 thread_id;
+ __u16 address;
++ __u8 cc;
++ __u8 padding[3];
+ __u64 value;
+} __attribute__((__packed__));
+
@@ -4245,22 +5216,34 @@ index a6dae71cbff5..8467b2fbee1f 100644
+ * @thread_id: ID of the specific logical processor
+ * @address: address of MSR to write to
+ * @tx_len: number of data to be written in bytes
++ * @cc: completion code
+ * @value: data to be written
+ *
+ * The WrIAMSR() PECI command provides write access to Model Specific Registers
+ * (MSRs) defined in the processor's Intel Architecture (IA).
+ */
+struct peci_wr_ia_msr_msg {
++#define PECI_WRIAMSR_CMD 0xb5
++
+ __u8 addr;
+ __u8 thread_id;
+ __u16 address;
+ __u8 tx_len;
-+ __u8 padding[3];
++ __u8 cc;
++ __u8 padding[2];
+ __u64 value;
} __attribute__((__packed__));
/**
-@@ -310,12 +314,52 @@ struct peci_rd_ia_msr_msg {
+@@ -303,6 +318,7 @@ struct peci_rd_ia_msr_msg {
+ * @device: PCI device number
+ * @function: specific function to read from
+ * @reg: specific register to read from
++ * @cc: completion code
+ * @pci_config: config data to be read
+ *
+ * The RdPCIConfig() command provides sideband read access to the PCI
+@@ -310,12 +326,56 @@ struct peci_rd_ia_msr_msg {
* processor.
*/
struct peci_rd_pci_cfg_msg {
@@ -4289,7 +5272,8 @@ index a6dae71cbff5..8467b2fbee1f 100644
+ __u8 device;
+ __u8 function;
+ __u16 reg;
-+ __u8 padding[2];
++ __u8 cc;
++ __u8 padding[1];
+ __u8 pci_config[4];
+} __attribute__((__packed__));
+
@@ -4301,6 +5285,7 @@ index a6dae71cbff5..8467b2fbee1f 100644
+ * @function: specific function to write to
+ * @reg: specific register to write to
+ * @tx_len: number of data to be written in bytes
++ * @cc: completion code
+ * @pci_config: config data to be written
+ *
+ * The RdPCIConfig() command provides sideband write access to the PCI
@@ -4308,18 +5293,28 @@ index a6dae71cbff5..8467b2fbee1f 100644
+ * processor.
+ */
+struct peci_wr_pci_cfg_msg {
++#define PECI_WRPCICFG_CMD 0x65
++
+ __u8 addr;
+ __u8 bus;
+ __u8 device;
+ __u8 function;
+ __u16 reg;
+ __u8 tx_len;
-+ __u8 padding;
++ __u8 cc;
+ __u8 pci_config[4];
} __attribute__((__packed__));
/**
-@@ -333,13 +377,18 @@ struct peci_rd_pci_cfg_msg {
+@@ -326,6 +386,7 @@ struct peci_rd_pci_cfg_msg {
+ * @function: specific function to read from
+ * @reg: specific register to read from
+ * @rx_len: number of data to be read in bytes
++ * @cc: completion code
+ * @pci_config: config data to be read
+ *
+ * The RdPCIConfigLocal() command provides sideband read access to the PCI
+@@ -333,13 +394,18 @@ struct peci_rd_pci_cfg_msg {
* processor IIO and uncore registers within the PCI configuration space.
*/
struct peci_rd_pci_cfg_local_msg {
@@ -4340,12 +5335,20 @@ index a6dae71cbff5..8467b2fbee1f 100644
+ __u8 function;
+ __u16 reg;
+ __u8 rx_len;
-+ __u8 padding[3];
++ __u8 cc;
+ __u8 pci_config[4];
} __attribute__((__packed__));
/**
-@@ -357,13 +406,18 @@ struct peci_rd_pci_cfg_local_msg {
+@@ -350,6 +416,7 @@ struct peci_rd_pci_cfg_local_msg {
+ * @function: specific function to read from
+ * @reg: specific register to read from
+ * @tx_len: number of data to be written in bytes
++ * @cc: completion code
+ * @value: config data to be written
+ *
+ * The WrPCIConfigLocal() command provides sideband write access to the PCI
+@@ -357,13 +424,18 @@ struct peci_rd_pci_cfg_local_msg {
* access this space even before BIOS enumeration of the system buses.
*/
struct peci_wr_pci_cfg_local_msg {
@@ -4366,12 +5369,12 @@ index a6dae71cbff5..8467b2fbee1f 100644
+ __u8 function;
+ __u16 reg;
+ __u8 tx_len;
-+ __u8 padding[3];
++ __u8 cc;
+ __u32 value;
} __attribute__((__packed__));
#define PECI_IOC_BASE 0xb7
-@@ -389,9 +443,15 @@ struct peci_wr_pci_cfg_local_msg {
+@@ -389,9 +461,15 @@ struct peci_wr_pci_cfg_local_msg {
#define PECI_IOC_RD_IA_MSR \
_IOWR(PECI_IOC_BASE, PECI_CMD_RD_IA_MSR, struct peci_rd_ia_msr_msg)