summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0018-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/0018-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0018-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch5611
1 files changed, 0 insertions, 5611 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0018-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0018-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch
deleted file mode 100644
index d1da4c599..000000000
--- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0018-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch
+++ /dev/null
@@ -1,5611 +0,0 @@
-From edeea958f026102ce28c8b760f7a96b9ffd7f65a 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
-
-Upstreaming is in holding. It's for adding DTS sensor with PECI
-subsystem code update.
-
-Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com>
-Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
----
- Documentation/hwmon/peci-cputemp | 34 +-
- drivers/hwmon/Kconfig | 4 +-
- drivers/hwmon/peci-cputemp.c | 171 +++---
- drivers/hwmon/peci-dimmtemp.c | 184 +++++--
- drivers/hwmon/peci-hwmon.h | 9 +-
- drivers/mfd/Kconfig | 5 +-
- drivers/mfd/intel-peci-client.c | 51 +-
- drivers/peci/Kconfig | 46 +-
- drivers/peci/Makefile | 7 +-
- drivers/peci/busses/Kconfig | 32 ++
- drivers/peci/busses/Makefile | 7 +
- drivers/peci/busses/peci-aspeed.c | 492 +++++++++++++++++
- drivers/peci/busses/peci-npcm.c | 410 +++++++++++++++
- drivers/peci/peci-aspeed.c | 505 ------------------
- drivers/peci/peci-core.c | 959 +++++++++++++++++++---------------
- drivers/peci/peci-dev.c | 346 ++++++++++++
- drivers/peci/peci-npcm.c | 410 ---------------
- include/linux/mfd/intel-peci-client.h | 31 +-
- include/linux/peci.h | 30 +-
- include/uapi/linux/peci-ioctl.h | 416 +++++++++------
- 20 files changed, 2446 insertions(+), 1703 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 821a925..a3a3e46 100644
---- a/Documentation/hwmon/peci-cputemp
-+++ b/Documentation/hwmon/peci-cputemp
-@@ -51,28 +51,38 @@ temp1_crit Provides shutdown temperature of the CPU package which
- temp1_crit_hyst Provides the hysteresis value from Tcontrol to Tjmax of
- the CPU package.
-
--temp2_label "Tcontrol"
--temp2_input Provides current Tcontrol temperature of the CPU
-+temp2_label "DTS"
-+temp2_input Provides current DTS temperature of the CPU package.
-+temp2_max Provides thermal control temperature of the CPU package
-+ which is also known as Tcontrol.
-+temp2_crit Provides shutdown temperature of the CPU package which
-+ is also known as the maximum processor junction
-+ temperature, Tjmax or Tprochot.
-+temp2_crit_hyst Provides the hysteresis value from Tcontrol to Tjmax of
-+ the CPU package.
-+
-+temp3_label "Tcontrol"
-+temp3_input Provides current Tcontrol temperature of the CPU
- package which is also known as Fan Temperature target.
- Indicates the relative value from thermal monitor trip
- temperature at which fans should be engaged.
--temp2_crit Provides Tcontrol critical value of the CPU package
-+temp3_crit Provides Tcontrol critical value of the CPU package
- which is same to Tjmax.
-
--temp3_label "Tthrottle"
--temp3_input Provides current Tthrottle temperature of the CPU
-+temp4_label "Tthrottle"
-+temp4_input Provides current Tthrottle temperature of the CPU
- package. Used for throttling temperature. If this value
- is allowed and lower than Tjmax - the throttle will
- occur and reported at lower than Tjmax.
-
--temp4_label "Tjmax"
--temp4_input Provides the maximum junction temperature, Tjmax of the
-+temp5_label "Tjmax"
-+temp5_input Provides the maximum junction temperature, Tjmax of the
- CPU package.
-
--temp[5-*]_label Provides string "Core X", where X is resolved core
-+temp[6-*]_label Provides string "Core X", where X is resolved core
- number.
--temp[5-*]_input Provides current temperature of each core.
--temp[5-*]_max Provides thermal control temperature of the core.
--temp[5-*]_crit Provides shutdown temperature of the core.
--temp[5-*]_crit_hyst Provides the hysteresis value from Tcontrol to Tjmax of
-+temp[6-*]_input Provides current temperature of each core.
-+temp[6-*]_max Provides thermal control temperature of the core.
-+temp[6-*]_crit Provides shutdown temperature of the core.
-+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 c0623fa..7399c3c 100644
---- a/drivers/hwmon/Kconfig
-+++ b/drivers/hwmon/Kconfig
-@@ -1333,7 +1333,7 @@ config SENSORS_PECI_CPUTEMP
- the PECI Client Command Suite via the processor PECI client.
- Check Documentation/hwmon/peci-cputemp for details.
-
-- This driver can also be built as a module. If so, the module
-+ This driver can also be built as a module. If so, the module
- will be called peci-cputemp.
-
- config SENSORS_PECI_DIMMTEMP
-@@ -1347,7 +1347,7 @@ config SENSORS_PECI_DIMMTEMP
- Suite via the processor PECI client.
- Check Documentation/hwmon/peci-dimmtemp for details.
-
-- This driver can also be built as a module. If so, the module
-+ This driver can also be built as a module. If so, the module
- will be called peci-dimmtemp.
-
- source "drivers/hwmon/pmbus/Kconfig"
-diff --git a/drivers/hwmon/peci-cputemp.c b/drivers/hwmon/peci-cputemp.c
-index 11880c8..d0d68e8 100644
---- a/drivers/hwmon/peci-cputemp.c
-+++ b/drivers/hwmon/peci-cputemp.c
-@@ -1,5 +1,5 @@
- // SPDX-License-Identifier: GPL-2.0
--// Copyright (c) 2018 Intel Corporation
-+// Copyright (c) 2018-2019 Intel Corporation
-
- #include <linux/hwmon.h>
- #include <linux/jiffies.h>
-@@ -9,18 +9,13 @@
- #include <linux/platform_device.h>
- #include "peci-hwmon.h"
-
--#define DEFAULT_CHANNEL_NUMS 4
-+#define DEFAULT_CHANNEL_NUMS 5
- #define CORETEMP_CHANNEL_NUMS CORE_NUMS_MAX
- #define CPUTEMP_CHANNEL_NUMS (DEFAULT_CHANNEL_NUMS + CORETEMP_CHANNEL_NUMS)
-
--/* The RESOLVED_CORES register in PCU of a client CPU */
--#define REG_RESOLVED_CORES_BUS 1
--#define REG_RESOLVED_CORES_DEVICE 30
--#define REG_RESOLVED_CORES_FUNCTION 3
--#define REG_RESOLVED_CORES_OFFSET 0xB4
--
- struct temp_group {
- struct temp_data die;
-+ struct temp_data dts;
- struct temp_data tcontrol;
- struct temp_data tthrottle;
- struct temp_data tjmax;
-@@ -43,6 +38,7 @@ struct peci_cputemp {
-
- enum cputemp_channels {
- channel_die,
-+ channel_dts,
- channel_tcontrol,
- channel_tthrottle,
- channel_tjmax,
-@@ -54,6 +50,10 @@ static const u32 config_table[DEFAULT_CHANNEL_NUMS + 1] = {
- HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |
- HWMON_T_CRIT_HYST,
-
-+ /* DTS margin */
-+ HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT |
-+ HWMON_T_CRIT_HYST,
-+
- /* Tcontrol temperature */
- HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_CRIT,
-
-@@ -70,6 +70,7 @@ static const u32 config_table[DEFAULT_CHANNEL_NUMS + 1] = {
-
- static const char *cputemp_label[CPUTEMP_CHANNEL_NUMS] = {
- "Die",
-+ "DTS",
- "Tcontrol",
- "Tthrottle",
- "Tjmax",
-@@ -92,19 +93,20 @@ static int get_temp_targets(struct peci_cputemp *priv)
- s32 tthrottle_offset;
- s32 tcontrol_margin;
- u8 pkg_cfg[4];
-- int rc;
-+ int ret;
-
-- /**
-+ /*
- * Just use only the tcontrol marker to determine if target values need
- * update.
- */
- if (!peci_temp_need_update(&priv->temp.tcontrol))
- return 0;
-
-- rc = peci_client_read_package_config(priv->mgr,
-- MBX_INDEX_TEMP_TARGET, 0, pkg_cfg);
-- if (rc)
-- return rc;
-+ ret = peci_client_read_package_config(priv->mgr,
-+ PECI_MBX_INDEX_TEMP_TARGET, 0,
-+ pkg_cfg);
-+ if (ret)
-+ return ret;
-
- priv->temp.tjmax.value = pkg_cfg[2] * 1000;
-
-@@ -123,17 +125,16 @@ static int get_temp_targets(struct peci_cputemp *priv)
- static int get_die_temp(struct peci_cputemp *priv)
- {
- struct peci_get_temp_msg msg;
-- int rc;
-+ int ret;
-
- if (!peci_temp_need_update(&priv->temp.die))
- return 0;
-
- msg.addr = priv->mgr->client->addr;
-
-- rc = peci_command(priv->mgr->client->adapter, PECI_CMD_GET_TEMP,
-- &msg);
-- if (rc)
-- return rc;
-+ ret = peci_command(priv->mgr->client->adapter, PECI_CMD_GET_TEMP, &msg);
-+ if (ret)
-+ return ret;
-
- /* Note that the tjmax should be available before calling it */
- priv->temp.die.value = priv->temp.tjmax.value +
-@@ -144,24 +145,64 @@ static int get_die_temp(struct peci_cputemp *priv)
- return 0;
- }
-
-+static int get_dts(struct peci_cputemp *priv)
-+{
-+ s32 dts_margin;
-+ u8 pkg_cfg[4];
-+ int ret;
-+
-+ if (!peci_temp_need_update(&priv->temp.dts))
-+ return 0;
-+
-+ ret = peci_client_read_package_config(priv->mgr,
-+ PECI_MBX_INDEX_DTS_MARGIN, 0,
-+ pkg_cfg);
-+
-+ if (ret)
-+ return ret;
-+
-+ dts_margin = (pkg_cfg[1] << 8) | pkg_cfg[0];
-+
-+ /**
-+ * Processors return a value of DTS reading in 10.6 format
-+ * (10 bits signed decimal, 6 bits fractional).
-+ * Error codes:
-+ * 0x8000: General sensor error
-+ * 0x8001: Reserved
-+ * 0x8002: Underflow on reading value
-+ * 0x8003-0x81ff: Reserved
-+ */
-+ if (dts_margin >= 0x8000 && dts_margin <= 0x81ff)
-+ return -EIO;
-+
-+ dts_margin = ten_dot_six_to_millidegree(dts_margin);
-+
-+ /* Note that the tcontrol should be available before calling it */
-+ priv->temp.dts.value = priv->temp.tcontrol.value - dts_margin;
-+
-+ peci_temp_mark_updated(&priv->temp.dts);
-+
-+ return 0;
-+}
-+
- static int get_core_temp(struct peci_cputemp *priv, int core_index)
- {
- s32 core_dts_margin;
- u8 pkg_cfg[4];
-- int rc;
-+ int ret;
-
- if (!peci_temp_need_update(&priv->temp.core[core_index]))
- return 0;
-
-- rc = peci_client_read_package_config(priv->mgr,
-- MBX_INDEX_PER_CORE_DTS_TEMP,
-- core_index, pkg_cfg);
-- if (rc)
-- return rc;
-+ ret = peci_client_read_package_config(priv->mgr,
-+ PECI_MBX_INDEX_PER_CORE_DTS_TEMP,
-+ core_index, pkg_cfg);
-+ if (ret)
-+ return ret;
-
- core_dts_margin = le16_to_cpup((__le16 *)pkg_cfg);
-
-- /**
-+ /*
- * Processors return a value of the core DTS reading in 10.6 format
- * (10 bits signed decimal, 6 bits fractional).
- * Error codes:
-@@ -192,6 +233,7 @@ static int cputemp_read_string(struct device *dev,
- return -EOPNOTSUPP;
-
- *str = cputemp_label[channel];
-+
- return 0;
- }
-
-@@ -200,26 +242,33 @@ static int cputemp_read(struct device *dev,
- u32 attr, int channel, long *val)
- {
- struct peci_cputemp *priv = dev_get_drvdata(dev);
-- int rc, core_index;
-+ int ret, core_index;
-
- if (channel >= CPUTEMP_CHANNEL_NUMS ||
- !(priv->temp_config[channel] & BIT(attr)))
- return -EOPNOTSUPP;
-
-- rc = get_temp_targets(priv);
-- if (rc)
-- return rc;
-+ ret = get_temp_targets(priv);
-+ if (ret)
-+ return ret;
-
- switch (attr) {
- case hwmon_temp_input:
- switch (channel) {
- case channel_die:
-- rc = get_die_temp(priv);
-- if (rc)
-+ ret = get_die_temp(priv);
-+ if (ret)
- break;
-
- *val = priv->temp.die.value;
- break;
-+ case channel_dts:
-+ ret = get_dts(priv);
-+ if (ret)
-+ break;
-+
-+ *val = priv->temp.dts.value;
-+ break;
- case channel_tcontrol:
- *val = priv->temp.tcontrol.value;
- break;
-@@ -231,8 +280,8 @@ static int cputemp_read(struct device *dev,
- break;
- default:
- core_index = channel - DEFAULT_CHANNEL_NUMS;
-- rc = get_core_temp(priv, core_index);
-- if (rc)
-+ ret = get_core_temp(priv, core_index);
-+ if (ret)
- break;
-
- *val = priv->temp.core[core_index].value;
-@@ -249,11 +298,11 @@ static int cputemp_read(struct device *dev,
- *val = priv->temp.tjmax.value - priv->temp.tcontrol.value;
- break;
- default:
-- rc = -EOPNOTSUPP;
-+ ret = -EOPNOTSUPP;
- break;
- }
-
-- return rc;
-+ return ret;
- }
-
- static umode_t cputemp_is_visible(const void *data,
-@@ -262,11 +311,11 @@ static umode_t cputemp_is_visible(const void *data,
- {
- const struct peci_cputemp *priv = data;
-
-- if (priv->temp_config[channel] & BIT(attr))
-- if (channel < DEFAULT_CHANNEL_NUMS ||
-- (channel >= DEFAULT_CHANNEL_NUMS &&
-- (priv->core_mask & BIT(channel - DEFAULT_CHANNEL_NUMS))))
-- return 0444;
-+ if ((priv->temp_config[channel] & BIT(attr)) &&
-+ (channel < DEFAULT_CHANNEL_NUMS ||
-+ (channel >= DEFAULT_CHANNEL_NUMS &&
-+ (priv->core_mask & BIT(channel - DEFAULT_CHANNEL_NUMS)))))
-+ return 0444;
-
- return 0;
- }
-@@ -280,40 +329,43 @@ static const struct hwmon_ops cputemp_ops = {
- static int check_resolved_cores(struct peci_cputemp *priv)
- {
- struct peci_rd_pci_cfg_local_msg msg;
-- int rc;
-+ int ret;
-
- /* Get the RESOLVED_CORES register value */
- msg.addr = priv->mgr->client->addr;
-- msg.bus = REG_RESOLVED_CORES_BUS;
-- msg.device = REG_RESOLVED_CORES_DEVICE;
-- msg.function = REG_RESOLVED_CORES_FUNCTION;
-- msg.reg = REG_RESOLVED_CORES_OFFSET;
-+ msg.bus = 1;
-+ msg.device = 30;
-+ msg.function = 3;
-+ msg.reg = 0xb4;
- msg.rx_len = 4;
-
-- rc = peci_command(priv->mgr->client->adapter,
-- PECI_CMD_RD_PCI_CFG_LOCAL, &msg);
-- if (rc)
-- return rc;
-+ ret = peci_command(priv->mgr->client->adapter,
-+ PECI_CMD_RD_PCI_CFG_LOCAL, &msg);
-+ if (msg.cc != PECI_DEV_CC_SUCCESS)
-+ ret = -EAGAIN;
-+ if (ret)
-+ return ret;
-
- priv->core_mask = le32_to_cpup((__le32 *)msg.pci_config);
- if (!priv->core_mask)
- return -EAGAIN;
-
- dev_dbg(priv->dev, "Scanned resolved cores: 0x%x\n", priv->core_mask);
-+
- return 0;
- }
-
- static int create_core_temp_info(struct peci_cputemp *priv)
- {
-- int rc, i;
-+ int ret, i;
-
-- rc = check_resolved_cores(priv);
-- if (rc)
-- return rc;
-+ ret = check_resolved_cores(priv);
-+ if (ret)
-+ return ret;
-
- for (i = 0; i < priv->gen_info->core_max; i++)
- if (priv->core_mask & BIT(i))
-- while (i + DEFAULT_CHANNEL_NUMS >= priv->config_idx)
-+ while (priv->config_idx <= i + DEFAULT_CHANNEL_NUMS)
- priv->temp_config[priv->config_idx++] =
- config_table[channel_core];
-
-@@ -326,7 +378,7 @@ static int peci_cputemp_probe(struct platform_device *pdev)
- struct device *dev = &pdev->dev;
- struct peci_cputemp *priv;
- struct device *hwmon_dev;
-- int rc;
-+ int ret;
-
- if ((mgr->client->adapter->cmd_mask &
- (BIT(PECI_CMD_GET_TEMP) | BIT(PECI_CMD_RD_PKG_CFG))) !=
-@@ -346,12 +398,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];
-+ priv->temp_config[priv->config_idx++] = config_table[channel_dts];
- priv->temp_config[priv->config_idx++] = config_table[channel_tcontrol];
- priv->temp_config[priv->config_idx++] = config_table[channel_tthrottle];
- priv->temp_config[priv->config_idx++] = config_table[channel_tjmax];
-
-- rc = create_core_temp_info(priv);
-- if (rc)
-+ ret = create_core_temp_info(priv);
-+ if (ret)
- dev_dbg(dev, "Skipped creating core temp info\n");
-
- priv->chip.ops = &cputemp_ops;
-@@ -385,7 +438,7 @@ MODULE_DEVICE_TABLE(platform, peci_cputemp_ids);
- static struct platform_driver peci_cputemp_driver = {
- .probe = peci_cputemp_probe,
- .id_table = peci_cputemp_ids,
-- .driver = { .name = "peci-cputemp", },
-+ .driver = { .name = KBUILD_MODNAME, },
- };
- module_platform_driver(peci_cputemp_driver);
-
-diff --git a/drivers/hwmon/peci-dimmtemp.c b/drivers/hwmon/peci-dimmtemp.c
-index 86a45a9..a404b6e 100644
---- a/drivers/hwmon/peci-dimmtemp.c
-+++ b/drivers/hwmon/peci-dimmtemp.c
-@@ -1,5 +1,5 @@
- // SPDX-License-Identifier: GPL-2.0
--// Copyright (c) 2018 Intel Corporation
-+// Copyright (c) 2018-2019 Intel Corporation
-
- #include <linux/hwmon.h>
- #include <linux/jiffies.h>
-@@ -21,6 +21,8 @@ struct peci_dimmtemp {
- struct workqueue_struct *work_queue;
- struct delayed_work work_handler;
- struct temp_data temp[DIMM_NUMS_MAX];
-+ long temp_max[DIMM_NUMS_MAX];
-+ long temp_crit[DIMM_NUMS_MAX];
- u32 dimm_mask;
- int retry_count;
- u32 temp_config[DIMM_NUMS_MAX + 1];
-@@ -44,20 +46,106 @@ static int get_dimm_temp(struct peci_dimmtemp *priv, int dimm_no)
- {
- int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
- int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
-+ struct peci_rd_pci_cfg_local_msg rp_msg;
- u8 cfg_data[4];
-- int rc;
-+ int ret;
-
- if (!peci_temp_need_update(&priv->temp[dimm_no]))
- return 0;
-
-- rc = peci_client_read_package_config(priv->mgr,
-- MBX_INDEX_DDR_DIMM_TEMP,
-- chan_rank, cfg_data);
-- if (rc)
-- return rc;
-+ ret = peci_client_read_package_config(priv->mgr,
-+ PECI_MBX_INDEX_DDR_DIMM_TEMP,
-+ chan_rank, cfg_data);
-+ if (ret)
-+ return ret;
-
- priv->temp[dimm_no].value = cfg_data[dimm_order] * 1000;
-
-+ switch (priv->gen_info->model) {
-+ case INTEL_FAM6_SKYLAKE_X:
-+ rp_msg.addr = priv->mgr->client->addr;
-+ rp_msg.bus = 2;
-+ /*
-+ * Device 10, Function 2: IMC 0 channel 0 -> rank 0
-+ * Device 10, Function 6: IMC 0 channel 1 -> rank 1
-+ * Device 11, Function 2: IMC 0 channel 2 -> rank 2
-+ * Device 12, Function 2: IMC 1 channel 0 -> rank 3
-+ * Device 12, Function 6: IMC 1 channel 1 -> rank 4
-+ * Device 13, Function 2: IMC 1 channel 2 -> rank 5
-+ */
-+ rp_msg.device = 10 + chan_rank / 3 * 2 +
-+ (chan_rank % 3 == 2 ? 1 : 0);
-+ rp_msg.function = chan_rank % 3 == 1 ? 6 : 2;
-+ rp_msg.reg = 0x120 + dimm_order * 4;
-+ rp_msg.rx_len = 4;
-+
-+ ret = peci_command(priv->mgr->client->adapter,
-+ PECI_CMD_RD_PCI_CFG_LOCAL, &rp_msg);
-+ if (rp_msg.cc != PECI_DEV_CC_SUCCESS)
-+ ret = -EAGAIN;
-+ if (ret)
-+ return ret;
-+
-+ priv->temp_max[dimm_no] = rp_msg.pci_config[1] * 1000;
-+ priv->temp_crit[dimm_no] = rp_msg.pci_config[2] * 1000;
-+ break;
-+ case INTEL_FAM6_SKYLAKE_XD:
-+ rp_msg.addr = priv->mgr->client->addr;
-+ rp_msg.bus = 2;
-+ /*
-+ * Device 10, Function 2: IMC 0 channel 0 -> rank 0
-+ * Device 10, Function 6: IMC 0 channel 1 -> rank 1
-+ * Device 12, Function 2: IMC 1 channel 0 -> rank 2
-+ * Device 12, Function 6: IMC 1 channel 1 -> rank 3
-+ */
-+ rp_msg.device = 10 + chan_rank / 2 * 2;
-+ rp_msg.function = chan_rank % 2 ? 6 : 2;
-+ rp_msg.reg = 0x120 + dimm_order * 4;
-+ rp_msg.rx_len = 4;
-+
-+ ret = peci_command(priv->mgr->client->adapter,
-+ PECI_CMD_RD_PCI_CFG_LOCAL, &rp_msg);
-+ if (rp_msg.cc != PECI_DEV_CC_SUCCESS)
-+ ret = -EAGAIN;
-+ if (ret)
-+ return ret;
-+
-+ priv->temp_max[dimm_no] = rp_msg.pci_config[1] * 1000;
-+ priv->temp_crit[dimm_no] = rp_msg.pci_config[2] * 1000;
-+ break;
-+ case INTEL_FAM6_HASWELL_X:
-+ case INTEL_FAM6_BROADWELL_X:
-+ rp_msg.addr = priv->mgr->client->addr;
-+ rp_msg.bus = 1;
-+ /*
-+ * Device 20, Function 0: IMC 0 channel 0 -> rank 0
-+ * Device 20, Function 1: IMC 0 channel 1 -> rank 1
-+ * Device 21, Function 0: IMC 0 channel 2 -> rank 2
-+ * Device 21, Function 1: IMC 0 channel 3 -> rank 3
-+ * Device 23, Function 0: IMC 1 channel 0 -> rank 4
-+ * Device 23, Function 1: IMC 1 channel 1 -> rank 5
-+ * Device 24, Function 0: IMC 1 channel 2 -> rank 6
-+ * Device 24, Function 1: IMC 1 channel 3 -> rank 7
-+ */
-+ rp_msg.device = 20 + chan_rank / 2 + chan_rank / 4;
-+ rp_msg.function = chan_rank % 2;
-+ rp_msg.reg = 0x120 + dimm_order * 4;
-+ rp_msg.rx_len = 4;
-+
-+ ret = peci_command(priv->mgr->client->adapter,
-+ PECI_CMD_RD_PCI_CFG_LOCAL, &rp_msg);
-+ if (rp_msg.cc != PECI_DEV_CC_SUCCESS)
-+ ret = -EAGAIN;
-+ if (ret)
-+ return ret;
-+
-+ priv->temp_max[dimm_no] = rp_msg.pci_config[1] * 1000;
-+ priv->temp_crit[dimm_no] = rp_msg.pci_config[2] * 1000;
-+ break;
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+
- peci_temp_mark_updated(&priv->temp[dimm_no]);
-
- return 0;
-@@ -77,6 +165,7 @@ static int dimmtemp_read_string(struct device *dev,
- chan_rank = channel / dimm_idx_max;
- dimm_idx = channel % dimm_idx_max;
- *str = dimmtemp_label[chan_rank][dimm_idx];
-+
- return 0;
- }
-
-@@ -84,17 +173,28 @@ static int dimmtemp_read(struct device *dev, enum hwmon_sensor_types type,
- u32 attr, int channel, long *val)
- {
- struct peci_dimmtemp *priv = dev_get_drvdata(dev);
-- int rc;
--
-- if (attr != hwmon_temp_input)
-- return -EOPNOTSUPP;
--
-- rc = get_dimm_temp(priv, channel);
-- if (rc)
-- return rc;
-+ int ret;
-+
-+ ret = get_dimm_temp(priv, channel);
-+ if (ret)
-+ return ret;
-+
-+ switch (attr) {
-+ case hwmon_temp_input:
-+ *val = priv->temp[channel].value;
-+ break;
-+ case hwmon_temp_max:
-+ *val = priv->temp_max[channel];
-+ break;
-+ case hwmon_temp_crit:
-+ *val = priv->temp_crit[channel];
-+ break;
-+ default:
-+ ret = -EOPNOTSUPP;
-+ break;
-+ }
-
-- *val = priv->temp[channel].value;
-- return 0;
-+ return ret;
- }
-
- static umode_t dimmtemp_is_visible(const void *data,
-@@ -120,16 +220,16 @@ static int check_populated_dimms(struct peci_dimmtemp *priv)
- {
- u32 chan_rank_max = priv->gen_info->chan_rank_max;
- u32 dimm_idx_max = priv->gen_info->dimm_idx_max;
-- int chan_rank, dimm_idx, rc;
-+ int chan_rank, dimm_idx, ret;
- u8 cfg_data[4];
-
- for (chan_rank = 0; chan_rank < chan_rank_max; chan_rank++) {
-- rc = peci_client_read_package_config(priv->mgr,
-- MBX_INDEX_DDR_DIMM_TEMP,
-- chan_rank, cfg_data);
-- if (rc) {
-+ ret = peci_client_read_package_config(priv->mgr,
-+ PECI_MBX_INDEX_DDR_DIMM_TEMP,
-+ chan_rank, cfg_data);
-+ if (ret) {
- priv->dimm_mask = 0;
-- return rc;
-+ return ret;
- }
-
- for (dimm_idx = 0; dimm_idx < dimm_idx_max; dimm_idx++)
-@@ -143,17 +243,18 @@ static int check_populated_dimms(struct peci_dimmtemp *priv)
- return -EAGAIN;
-
- dev_dbg(priv->dev, "Scanned populated DIMMs: 0x%x\n", priv->dimm_mask);
-+
- return 0;
- }
-
- static int create_dimm_temp_info(struct peci_dimmtemp *priv)
- {
-- int rc, i, config_idx, channels;
-+ int ret, i, config_idx, channels;
- struct device *hwmon_dev;
-
-- rc = check_populated_dimms(priv);
-- if (rc) {
-- if (rc == -EAGAIN) {
-+ ret = check_populated_dimms(priv);
-+ if (ret) {
-+ if (ret == -EAGAIN) {
- if (priv->retry_count < DIMM_MASK_CHECK_RETRY_MAX) {
- queue_delayed_work(priv->work_queue,
- &priv->work_handler,
-@@ -164,11 +265,11 @@ static int create_dimm_temp_info(struct peci_dimmtemp *priv)
- } else {
- dev_err(priv->dev,
- "Timeout DIMM temp info creation\n");
-- rc = -ETIMEDOUT;
-+ ret = -ETIMEDOUT;
- }
- }
-
-- return rc;
-+ return ret;
- }
-
- channels = priv->gen_info->chan_rank_max *
-@@ -177,7 +278,8 @@ static int create_dimm_temp_info(struct peci_dimmtemp *priv)
- if (priv->dimm_mask & BIT(i))
- while (i >= config_idx)
- priv->temp_config[config_idx++] =
-- HWMON_T_LABEL | HWMON_T_INPUT;
-+ HWMON_T_LABEL | HWMON_T_INPUT |
-+ HWMON_T_MAX | HWMON_T_CRIT;
-
- priv->chip.ops = &dimmtemp_ops;
- priv->chip.info = priv->info;
-@@ -192,12 +294,12 @@ static int create_dimm_temp_info(struct peci_dimmtemp *priv)
- priv,
- &priv->chip,
- NULL);
-- rc = PTR_ERR_OR_ZERO(hwmon_dev);
-- if (!rc)
-+ ret = PTR_ERR_OR_ZERO(hwmon_dev);
-+ if (!ret)
- dev_dbg(priv->dev, "%s: sensor '%s'\n",
- dev_name(hwmon_dev), priv->name);
-
-- return rc;
-+ return ret;
- }
-
- static void create_dimm_temp_info_delayed(struct work_struct *work)
-@@ -205,10 +307,10 @@ static void create_dimm_temp_info_delayed(struct work_struct *work)
- struct delayed_work *dwork = to_delayed_work(work);
- struct peci_dimmtemp *priv = container_of(dwork, struct peci_dimmtemp,
- work_handler);
-- int rc;
-+ int ret;
-
-- rc = create_dimm_temp_info(priv);
-- if (rc && rc != -EAGAIN)
-+ ret = create_dimm_temp_info(priv);
-+ if (ret && ret != -EAGAIN)
- dev_dbg(priv->dev, "Failed to create DIMM temp info\n");
- }
-
-@@ -217,7 +319,7 @@ static int peci_dimmtemp_probe(struct platform_device *pdev)
- struct peci_client_manager *mgr = dev_get_drvdata(pdev->dev.parent);
- struct device *dev = &pdev->dev;
- struct peci_dimmtemp *priv;
-- int rc;
-+ int ret;
-
- if ((mgr->client->adapter->cmd_mask &
- (BIT(PECI_CMD_GET_TEMP) | BIT(PECI_CMD_RD_PKG_CFG))) !=
-@@ -242,8 +344,8 @@ static int peci_dimmtemp_probe(struct platform_device *pdev)
-
- INIT_DELAYED_WORK(&priv->work_handler, create_dimm_temp_info_delayed);
-
-- rc = create_dimm_temp_info(priv);
-- if (rc && rc != -EAGAIN) {
-+ ret = create_dimm_temp_info(priv);
-+ if (ret && ret != -EAGAIN) {
- dev_err(dev, "Failed to create DIMM temp info\n");
- goto err_free_wq;
- }
-@@ -252,7 +354,7 @@ static int peci_dimmtemp_probe(struct platform_device *pdev)
-
- err_free_wq:
- destroy_workqueue(priv->work_queue);
-- return rc;
-+ return ret;
- }
-
- static int peci_dimmtemp_remove(struct platform_device *pdev)
-@@ -275,7 +377,7 @@ static struct platform_driver peci_dimmtemp_driver = {
- .probe = peci_dimmtemp_probe,
- .remove = peci_dimmtemp_remove,
- .id_table = peci_dimmtemp_ids,
-- .driver = { .name = "peci-dimmtemp", },
-+ .driver = { .name = KBUILD_MODNAME, },
- };
- module_platform_driver(peci_dimmtemp_driver);
-
-diff --git a/drivers/hwmon/peci-hwmon.h b/drivers/hwmon/peci-hwmon.h
-index 6ca1855..ce6b470 100644
---- a/drivers/hwmon/peci-hwmon.h
-+++ b/drivers/hwmon/peci-hwmon.h
-@@ -1,5 +1,5 @@
- /* SPDX-License-Identifier: GPL-2.0 */
--/* Copyright (c) 2018 Intel Corporation */
-+/* Copyright (c) 2018-2019 Intel Corporation */
-
- #ifndef __PECI_HWMON_H
- #define __PECI_HWMON_H
-@@ -29,11 +29,8 @@ struct temp_data {
- */
- static inline bool peci_temp_need_update(struct temp_data *temp)
- {
-- if (temp->valid &&
-- time_before(jiffies, temp->last_updated + UPDATE_INTERVAL))
-- return false;
--
-- return true;
-+ return !temp->valid ||
-+ time_after(jiffies, temp->last_updated + UPDATE_INTERVAL);
- }
-
- /**
-diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
-index 5d89546..46f52a3 100644
---- a/drivers/mfd/Kconfig
-+++ b/drivers/mfd/Kconfig
-@@ -630,7 +630,7 @@ config MFD_INTEL_MSIC
- devices used in Intel Medfield platforms.
-
- config MFD_INTEL_PECI_CLIENT
-- bool "Intel PECI client"
-+ tristate "Intel PECI client"
- depends on (PECI || COMPILE_TEST)
- select MFD_CORE
- help
-@@ -643,6 +643,9 @@ config MFD_INTEL_PECI_CLIENT
- Additional drivers must be enabled in order to use the functionality
- of the device.
-
-+ This driver can also be built as a module. If so, the module
-+ will be called intel-peci-client.
-+
- config MFD_IPAQ_MICRO
- 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 d53e4f1..18bf0af 100644
---- a/drivers/mfd/intel-peci-client.c
-+++ b/drivers/mfd/intel-peci-client.c
-@@ -1,12 +1,12 @@
- // SPDX-License-Identifier: GPL-2.0
--// Copyright (c) 2018 Intel Corporation
-+// Copyright (c) 2018-2019 Intel Corporation
-
- #include <linux/bitfield.h>
- #include <linux/mfd/core.h>
- #include <linux/mfd/intel-peci-client.h>
- #include <linux/module.h>
--#include <linux/peci.h>
- #include <linux/of_device.h>
-+#include <linux/peci.h>
-
- #define CPU_ID_MODEL_MASK GENMASK(7, 4)
- #define CPU_ID_FAMILY_MASK GENMASK(11, 8)
-@@ -18,12 +18,6 @@
- #define LOWER_BYTE_MASK GENMASK(7, 0)
- #define UPPER_BYTE_MASK GENMASK(16, 8)
-
--enum cpu_gens {
-- CPU_GEN_HSX = 0, /* Haswell Xeon */
-- CPU_GEN_BRX, /* Broadwell Xeon */
-- CPU_GEN_SKX, /* Skylake Xeon */
--};
--
- static struct mfd_cell peci_functions[] = {
- { .name = "peci-cputemp", },
- { .name = "peci-dimmtemp", },
-@@ -31,38 +25,45 @@ static struct mfd_cell peci_functions[] = {
- };
-
- static const struct cpu_gen_info cpu_gen_info_table[] = {
-- [CPU_GEN_HSX] = {
-+ { /* Haswell Xeon */
- .family = 6, /* Family code */
- .model = INTEL_FAM6_HASWELL_X,
- .core_max = CORE_MAX_ON_HSX,
- .chan_rank_max = CHAN_RANK_MAX_ON_HSX,
- .dimm_idx_max = DIMM_IDX_MAX_ON_HSX },
-- [CPU_GEN_BRX] = {
-+ { /* Broadwell Xeon */
- .family = 6, /* Family code */
- .model = INTEL_FAM6_BROADWELL_X,
- .core_max = CORE_MAX_ON_BDX,
- .chan_rank_max = CHAN_RANK_MAX_ON_BDX,
- .dimm_idx_max = DIMM_IDX_MAX_ON_BDX },
-- [CPU_GEN_SKX] = {
-+ { /* Skylake Xeon */
- .family = 6, /* Family code */
- .model = INTEL_FAM6_SKYLAKE_X,
- .core_max = CORE_MAX_ON_SKX,
- .chan_rank_max = CHAN_RANK_MAX_ON_SKX,
- .dimm_idx_max = DIMM_IDX_MAX_ON_SKX },
-+ { /* Skylake Xeon D */
-+ .family = 6, /* Family code */
-+ .model = INTEL_FAM6_SKYLAKE_XD,
-+ .core_max = CORE_MAX_ON_SKXD,
-+ .chan_rank_max = CHAN_RANK_MAX_ON_SKXD,
-+ .dimm_idx_max = DIMM_IDX_MAX_ON_SKXD },
- };
-
- static int peci_client_get_cpu_gen_info(struct peci_client_manager *priv)
- {
-+ struct device *dev = &priv->client->dev;
- u32 cpu_id;
- u16 family;
- u8 model;
-- int rc;
-+ int ret;
- int i;
-
-- rc = peci_get_cpu_id(priv->client->adapter, priv->client->addr,
-- &cpu_id);
-- if (rc)
-- return rc;
-+ ret = peci_get_cpu_id(priv->client->adapter, priv->client->addr,
-+ &cpu_id);
-+ if (ret)
-+ return ret;
-
- family = FIELD_PREP(LOWER_BYTE_MASK,
- FIELD_GET(CPU_ID_FAMILY_MASK, cpu_id)) |
-@@ -83,11 +84,11 @@ static int peci_client_get_cpu_gen_info(struct peci_client_manager *priv)
- }
-
- if (!priv->gen_info) {
-- dev_err(priv->dev, "Can't support this CPU: 0x%x\n", cpu_id);
-- rc = -ENODEV;
-+ dev_err(dev, "Can't support this CPU: 0x%x\n", cpu_id);
-+ ret = -ENODEV;
- }
-
-- return rc;
-+ return ret;
- }
-
- 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;
-- priv->dev = dev;
- cpu_no = client->addr - PECI_BASE_ADDR;
-
- ret = peci_client_get_cpu_gen_info(priv);
- if (ret)
- return ret;
-
-- ret = devm_mfd_add_devices(priv->dev, cpu_no, peci_functions,
-+ ret = devm_mfd_add_devices(dev, cpu_no, peci_functions,
- ARRAY_SIZE(peci_functions), NULL, 0, NULL);
- if (ret < 0) {
-- dev_err(priv->dev, "Failed to register child devices: %d\n",
-- ret);
-+ dev_err(dev, "Failed to register child devices: %d\n", ret);
- return ret;
- }
-
- return 0;
- }
-
--#ifdef CONFIG_OF
-+#if IS_ENABLED(CONFIG_OF)
- static const struct of_device_id peci_client_of_table[] = {
- { .compatible = "intel,peci-client" },
- { }
- };
- MODULE_DEVICE_TABLE(of, peci_client_of_table);
--#endif
-+#endif /* CONFIG_OF */
-
- static const struct peci_device_id peci_client_ids[] = {
- { .name = "peci-client" },
-@@ -139,7 +138,7 @@ static struct peci_driver peci_client_driver = {
- .probe = peci_client_probe,
- .id_table = peci_client_ids,
- .driver = {
-- .name = "peci-client",
-+ .name = KBUILD_MODNAME,
- .of_match_table = of_match_ptr(peci_client_of_table),
- },
- };
-diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
-index 7293108..9752fee 100644
---- a/drivers/peci/Kconfig
-+++ b/drivers/peci/Kconfig
-@@ -2,10 +2,12 @@
- # Platform Environment Control Interface (PECI) subsystem configuration
- #
-
-+menu "PECI support"
-+
- config PECI
-- bool "PECI support"
-- select RT_MUTEXES
-+ tristate "PECI support"
- select CRC8
-+ default n
- help
- The Platform Environment Control Interface (PECI) is a one-wire bus
- interface that provides a communication channel from Intel processors
-@@ -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.
-
--if PECI
--
--#
--# 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.
-
-- This support is also available as a module. If so, the module
-- will be called peci-aspeed.
-+if PECI
-
--config PECI_NPCM
-- tristate "Nuvoton NPCM PECI support"
-- select REGMAP_MMIO
-- depends on OF
-- 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 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-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 3326da5..da8b0a3 100644
---- a/drivers/peci/Makefile
-+++ b/drivers/peci/Makefile
-@@ -1,10 +1,11 @@
-+# SPDX-License-Identifier: GPL-2.0
- #
--# Makefile for the PECI core and bus drivers.
-+# Makefile for the PECI core drivers.
- #
-
- # Core functionality
- obj-$(CONFIG_PECI) += peci-core.o
-+obj-$(CONFIG_PECI_CHARDEV) += peci-dev.o
-
- # 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 0000000..bfacafb
---- /dev/null
-+++ b/drivers/peci/busses/Kconfig
-@@ -0,0 +1,32 @@
-+#
-+# PECI hardware bus configuration
-+#
-+
-+menu "PECI Hardware Bus support"
-+
-+config PECI_ASPEED
-+ tristate "ASPEED PECI support"
-+ depends on ARCH_ASPEED || COMPILE_TEST
-+ depends on OF
-+ depends on PECI
-+ 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-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 0000000..aa8ce3a
---- /dev/null
-+++ b/drivers/peci/busses/Makefile
-@@ -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 0000000..851b71e3
---- /dev/null
-+++ b/drivers/peci/busses/peci-aspeed.c
-@@ -0,0 +1,492 @@
-+// SPDX-License-Identifier: GPL-2.0
-+// Copyright (C) 2012-2017 ASPEED Technology Inc.
-+// Copyright (c) 2018-2019 Intel Corporation
-+
-+#include <linux/bitfield.h>
-+#include <linux/clk.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/io.h>
-+#include <linux/jiffies.h>
-+#include <linux/module.h>
-+#include <linux/of.h>
-+#include <linux/peci.h>
-+#include <linux/platform_device.h>
-+#include <linux/reset.h>
-+
-+/* ASPEED PECI Registers */
-+/* Control Register */
-+#define ASPEED_PECI_CTRL 0x00
-+#define ASPEED_PECI_CTRL_SAMPLING_MASK GENMASK(19, 16)
-+#define ASPEED_PECI_CTRL_READ_MODE_MASK GENMASK(13, 12)
-+#define ASPEED_PECI_CTRL_READ_MODE_COUNT BIT(12)
-+#define ASPEED_PECI_CTRL_READ_MODE_DBG BIT(13)
-+#define ASPEED_PECI_CTRL_CLK_SOURCE_MASK BIT(11)
-+#define ASPEED_PECI_CTRL_CLK_DIV_MASK GENMASK(10, 8)
-+#define ASPEED_PECI_CTRL_INVERT_OUT BIT(7)
-+#define ASPEED_PECI_CTRL_INVERT_IN BIT(6)
-+#define ASPEED_PECI_CTRL_BUS_CONTENT_EN BIT(5)
-+#define ASPEED_PECI_CTRL_PECI_EN BIT(4)
-+#define ASPEED_PECI_CTRL_PECI_CLK_EN BIT(0)
-+
-+/* Timing Negotiation Register */
-+#define ASPEED_PECI_TIMING_NEGOTIATION 0x04
-+#define ASPEED_PECI_TIMING_MESSAGE_MASK GENMASK(15, 8)
-+#define ASPEED_PECI_TIMING_ADDRESS_MASK GENMASK(7, 0)
-+
-+/* Command Register */
-+#define ASPEED_PECI_CMD 0x08
-+#define ASPEED_PECI_CMD_PIN_MON BIT(31)
-+#define ASPEED_PECI_CMD_STS_MASK GENMASK(27, 24)
-+#define ASPEED_PECI_CMD_IDLE_MASK (ASPEED_PECI_CMD_STS_MASK | \
-+ ASPEED_PECI_CMD_PIN_MON)
-+#define ASPEED_PECI_CMD_FIRE BIT(0)
-+
-+/* Read/Write Length Register */
-+#define ASPEED_PECI_RW_LENGTH 0x0c
-+#define ASPEED_PECI_AW_FCS_EN BIT(31)
-+#define ASPEED_PECI_READ_LEN_MASK GENMASK(23, 16)
-+#define ASPEED_PECI_WRITE_LEN_MASK GENMASK(15, 8)
-+#define ASPEED_PECI_TAGET_ADDR_MASK GENMASK(7, 0)
-+
-+/* Expected FCS Data Register */
-+#define ASPEED_PECI_EXP_FCS 0x10
-+#define ASPEED_PECI_EXP_READ_FCS_MASK GENMASK(23, 16)
-+#define ASPEED_PECI_EXP_AW_FCS_AUTO_MASK GENMASK(15, 8)
-+#define ASPEED_PECI_EXP_WRITE_FCS_MASK GENMASK(7, 0)
-+
-+/* Captured FCS Data Register */
-+#define ASPEED_PECI_CAP_FCS 0x14
-+#define ASPEED_PECI_CAP_READ_FCS_MASK GENMASK(23, 16)
-+#define ASPEED_PECI_CAP_WRITE_FCS_MASK GENMASK(7, 0)
-+
-+/* Interrupt Register */
-+#define ASPEED_PECI_INT_CTRL 0x18
-+#define ASPEED_PECI_TIMING_NEGO_SEL_MASK GENMASK(31, 30)
-+#define ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO 0
-+#define ASPEED_PECI_2ND_BIT_OF_ADDR_NEGO 1
-+#define ASPEED_PECI_MESSAGE_NEGO 2
-+#define ASPEED_PECI_INT_MASK GENMASK(4, 0)
-+#define ASPEED_PECI_INT_BUS_TIMEOUT BIT(4)
-+#define ASPEED_PECI_INT_BUS_CONNECT BIT(3)
-+#define ASPEED_PECI_INT_W_FCS_BAD BIT(2)
-+#define ASPEED_PECI_INT_W_FCS_ABORT BIT(1)
-+#define ASPEED_PECI_INT_CMD_DONE BIT(0)
-+
-+/* Interrupt Status Register */
-+#define ASPEED_PECI_INT_STS 0x1c
-+#define ASPEED_PECI_INT_TIMING_RESULT_MASK GENMASK(29, 16)
-+ /* bits[4..0]: Same bit fields in the 'Interrupt Register' */
-+
-+/* Rx/Tx Data Buffer Registers */
-+#define ASPEED_PECI_W_DATA0 0x20
-+#define ASPEED_PECI_W_DATA1 0x24
-+#define ASPEED_PECI_W_DATA2 0x28
-+#define ASPEED_PECI_W_DATA3 0x2c
-+#define ASPEED_PECI_R_DATA0 0x30
-+#define ASPEED_PECI_R_DATA1 0x34
-+#define ASPEED_PECI_R_DATA2 0x38
-+#define ASPEED_PECI_R_DATA3 0x3c
-+#define ASPEED_PECI_W_DATA4 0x40
-+#define ASPEED_PECI_W_DATA5 0x44
-+#define ASPEED_PECI_W_DATA6 0x48
-+#define ASPEED_PECI_W_DATA7 0x4c
-+#define ASPEED_PECI_R_DATA4 0x50
-+#define ASPEED_PECI_R_DATA5 0x54
-+#define ASPEED_PECI_R_DATA6 0x58
-+#define ASPEED_PECI_R_DATA7 0x5c
-+#define ASPEED_PECI_DATA_BUF_SIZE_MAX 32
-+
-+/* Timing Negotiation */
-+#define ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT 8
-+#define ASPEED_PECI_RD_SAMPLING_POINT_MAX 15
-+#define ASPEED_PECI_CLK_DIV_DEFAULT 0
-+#define ASPEED_PECI_CLK_DIV_MAX 7
-+#define ASPEED_PECI_MSG_TIMING_DEFAULT 1
-+#define ASPEED_PECI_MSG_TIMING_MAX 255
-+#define ASPEED_PECI_ADDR_TIMING_DEFAULT 1
-+#define ASPEED_PECI_ADDR_TIMING_MAX 255
-+
-+/* Timeout */
-+#define ASPEED_PECI_IDLE_CHECK_TIMEOUT_USEC 50000
-+#define ASPEED_PECI_IDLE_CHECK_INTERVAL_USEC 10000
-+#define ASPEED_PECI_CMD_TIMEOUT_MS_DEFAULT 1000
-+#define ASPEED_PECI_CMD_TIMEOUT_MS_MAX 60000
-+
-+struct aspeed_peci {
-+ struct peci_adapter *adapter;
-+ struct device *dev;
-+ void __iomem *base;
-+ struct clk *clk;
-+ struct reset_control *rst;
-+ int irq;
-+ spinlock_t lock; /* to sync completion status handling */
-+ struct completion xfer_complete;
-+ u32 status;
-+ u32 cmd_timeout_ms;
-+};
-+
-+static int aspeed_peci_check_idle(struct aspeed_peci *priv)
-+{
-+ ulong timeout = jiffies + usecs_to_jiffies(ASPEED_PECI_IDLE_CHECK_TIMEOUT_USEC);
-+ u32 cmd_sts;
-+
-+ for (;;) {
-+ cmd_sts = readl(priv->base + ASPEED_PECI_CMD);
-+ if (!(cmd_sts & ASPEED_PECI_CMD_IDLE_MASK))
-+ break;
-+ if (time_after(jiffies, timeout)) {
-+ cmd_sts = readl(priv->base + ASPEED_PECI_CMD);
-+ break;
-+ }
-+ usleep_range((ASPEED_PECI_IDLE_CHECK_INTERVAL_USEC >> 2) + 1,
-+ ASPEED_PECI_IDLE_CHECK_INTERVAL_USEC);
-+ }
-+
-+ return !(cmd_sts & ASPEED_PECI_CMD_IDLE_MASK) ? 0 : -ETIMEDOUT;
-+}
-+
-+static int aspeed_peci_xfer(struct peci_adapter *adapter,
-+ struct peci_xfer_msg *msg)
-+{
-+ struct aspeed_peci *priv = peci_get_adapdata(adapter);
-+ long err, timeout = msecs_to_jiffies(priv->cmd_timeout_ms);
-+ u32 peci_head, peci_state, rx_data = 0;
-+ ulong flags;
-+ int i, ret;
-+ uint reg;
-+
-+ if (msg->tx_len > ASPEED_PECI_DATA_BUF_SIZE_MAX ||
-+ msg->rx_len > ASPEED_PECI_DATA_BUF_SIZE_MAX)
-+ return -EINVAL;
-+
-+ /* Check command sts and bus idle state */
-+ ret = aspeed_peci_check_idle(priv);
-+ if (ret)
-+ return ret; /* -ETIMEDOUT */
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+ reinit_completion(&priv->xfer_complete);
-+
-+ peci_head = FIELD_PREP(ASPEED_PECI_TAGET_ADDR_MASK, msg->addr) |
-+ FIELD_PREP(ASPEED_PECI_WRITE_LEN_MASK, msg->tx_len) |
-+ FIELD_PREP(ASPEED_PECI_READ_LEN_MASK, msg->rx_len);
-+
-+ writel(peci_head, priv->base + ASPEED_PECI_RW_LENGTH);
-+
-+ for (i = 0; i < msg->tx_len; i += 4) {
-+ reg = i < 16 ? ASPEED_PECI_W_DATA0 + i % 16 :
-+ ASPEED_PECI_W_DATA4 + i % 16;
-+ writel(le32_to_cpup((__le32 *)&msg->tx_buf[i]),
-+ priv->base + reg);
-+ }
-+
-+ dev_dbg(priv->dev, "HEAD : 0x%08x\n", peci_head);
-+ print_hex_dump_debug("TX : ", DUMP_PREFIX_NONE, 16, 1,
-+ msg->tx_buf, msg->tx_len, true);
-+
-+ priv->status = 0;
-+ writel(ASPEED_PECI_CMD_FIRE, priv->base + ASPEED_PECI_CMD);
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+
-+ err = wait_for_completion_interruptible_timeout(&priv->xfer_complete,
-+ timeout);
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+ dev_dbg(priv->dev, "INT_STS : 0x%08x\n", priv->status);
-+ peci_state = readl(priv->base + ASPEED_PECI_CMD);
-+ dev_dbg(priv->dev, "PECI_STATE : 0x%lx\n",
-+ FIELD_GET(ASPEED_PECI_CMD_STS_MASK, peci_state));
-+
-+ writel(0, priv->base + ASPEED_PECI_CMD);
-+
-+ if (err <= 0 || priv->status != ASPEED_PECI_INT_CMD_DONE) {
-+ if (err < 0) { /* -ERESTARTSYS */
-+ ret = (int)err;
-+ goto err_irqrestore;
-+ } else if (err == 0) {
-+ dev_dbg(priv->dev, "Timeout waiting for a response!\n");
-+ ret = -ETIMEDOUT;
-+ goto err_irqrestore;
-+ }
-+
-+ dev_dbg(priv->dev, "No valid response!\n");
-+ ret = -EIO;
-+ goto err_irqrestore;
-+ }
-+
-+ /*
-+ * Note that rx_len and rx_buf size can be an odd number.
-+ * Byte handling is more efficient.
-+ */
-+ for (i = 0; i < msg->rx_len; i++) {
-+ u8 byte_offset = i % 4;
-+
-+ if (byte_offset == 0) {
-+ reg = i < 16 ? ASPEED_PECI_R_DATA0 + i % 16 :
-+ ASPEED_PECI_R_DATA4 + i % 16;
-+ rx_data = readl(priv->base + reg);
-+ }
-+
-+ msg->rx_buf[i] = (u8)(rx_data >> (byte_offset << 3));
-+ }
-+
-+ print_hex_dump_debug("RX : ", DUMP_PREFIX_NONE, 16, 1,
-+ msg->rx_buf, msg->rx_len, true);
-+
-+ peci_state = readl(priv->base + ASPEED_PECI_CMD);
-+ dev_dbg(priv->dev, "PECI_STATE : 0x%lx\n",
-+ FIELD_GET(ASPEED_PECI_CMD_STS_MASK, peci_state));
-+ dev_dbg(priv->dev, "------------------------\n");
-+
-+err_irqrestore:
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+ return ret;
-+}
-+
-+static irqreturn_t aspeed_peci_irq_handler(int irq, void *arg)
-+{
-+ struct aspeed_peci *priv = arg;
-+ u32 status;
-+
-+ spin_lock(&priv->lock);
-+ status = readl(priv->base + ASPEED_PECI_INT_STS);
-+ writel(status, priv->base + ASPEED_PECI_INT_STS);
-+ priv->status |= (status & ASPEED_PECI_INT_MASK);
-+
-+ /*
-+ * In most cases, interrupt bits will be set one by one but also note
-+ * that multiple interrupt bits could be set at the same time.
-+ */
-+ if (status & ASPEED_PECI_INT_BUS_TIMEOUT) {
-+ dev_dbg(priv->dev, "ASPEED_PECI_INT_BUS_TIMEOUT\n");
-+ }
-+
-+ if (status & ASPEED_PECI_INT_BUS_CONNECT) {
-+ dev_dbg(priv->dev, "ASPEED_PECI_INT_BUS_CONNECT\n");
-+ }
-+
-+ if (status & ASPEED_PECI_INT_W_FCS_BAD) {
-+ dev_dbg(priv->dev, "ASPEED_PECI_INT_W_FCS_BAD\n");
-+ }
-+
-+ if (status & ASPEED_PECI_INT_W_FCS_ABORT) {
-+ dev_dbg(priv->dev, "ASPEED_PECI_INT_W_FCS_ABORT\n");
-+ }
-+
-+ /*
-+ * All commands should be ended up with a ASPEED_PECI_INT_CMD_DONE bit
-+ * set even in an error case.
-+ */
-+ if (status & ASPEED_PECI_INT_CMD_DONE) {
-+ dev_dbg(priv->dev, "ASPEED_PECI_INT_CMD_DONE\n");
-+ complete(&priv->xfer_complete);
-+ }
-+
-+ spin_unlock(&priv->lock);
-+ return IRQ_HANDLED;
-+}
-+
-+static int aspeed_peci_init_ctrl(struct aspeed_peci *priv)
-+{
-+ u32 msg_timing, addr_timing, rd_sampling_point;
-+ u32 clk_freq, clk_divisor, clk_div_val = 0;
-+ int ret;
-+
-+ 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 = device_property_read_u32(priv->dev, "clock-frequency", &clk_freq);
-+ if (ret) {
-+ dev_err(priv->dev,
-+ "Could not read clock-frequency property.\n");
-+ clk_disable_unprepare(priv->clk);
-+ return ret;
-+ }
-+
-+ clk_divisor = clk_get_rate(priv->clk) / clk_freq;
-+
-+ while ((clk_divisor >> 1) && (clk_div_val < ASPEED_PECI_CLK_DIV_MAX))
-+ clk_div_val++;
-+
-+ ret = device_property_read_u32(priv->dev, "msg-timing", &msg_timing);
-+ if (ret || msg_timing > ASPEED_PECI_MSG_TIMING_MAX) {
-+ if (!ret)
-+ dev_warn(priv->dev,
-+ "Invalid msg-timing : %u, Use default : %u\n",
-+ msg_timing, ASPEED_PECI_MSG_TIMING_DEFAULT);
-+ msg_timing = ASPEED_PECI_MSG_TIMING_DEFAULT;
-+ }
-+
-+ ret = device_property_read_u32(priv->dev, "addr-timing", &addr_timing);
-+ if (ret || addr_timing > ASPEED_PECI_ADDR_TIMING_MAX) {
-+ if (!ret)
-+ dev_warn(priv->dev,
-+ "Invalid addr-timing : %u, Use default : %u\n",
-+ addr_timing, ASPEED_PECI_ADDR_TIMING_DEFAULT);
-+ addr_timing = ASPEED_PECI_ADDR_TIMING_DEFAULT;
-+ }
-+
-+ ret = device_property_read_u32(priv->dev, "rd-sampling-point",
-+ &rd_sampling_point);
-+ if (ret || rd_sampling_point > ASPEED_PECI_RD_SAMPLING_POINT_MAX) {
-+ if (!ret)
-+ dev_warn(priv->dev,
-+ "Invalid rd-sampling-point : %u. Use default : %u\n",
-+ rd_sampling_point,
-+ ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT);
-+ rd_sampling_point = ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT;
-+ }
-+
-+ ret = device_property_read_u32(priv->dev, "cmd-timeout-ms",
-+ &priv->cmd_timeout_ms);
-+ if (ret || priv->cmd_timeout_ms > ASPEED_PECI_CMD_TIMEOUT_MS_MAX ||
-+ priv->cmd_timeout_ms == 0) {
-+ if (!ret)
-+ dev_warn(priv->dev,
-+ "Invalid cmd-timeout-ms : %u. Use default : %u\n",
-+ priv->cmd_timeout_ms,
-+ ASPEED_PECI_CMD_TIMEOUT_MS_DEFAULT);
-+ priv->cmd_timeout_ms = ASPEED_PECI_CMD_TIMEOUT_MS_DEFAULT;
-+ }
-+
-+ writel(FIELD_PREP(ASPEED_PECI_CTRL_CLK_DIV_MASK,
-+ ASPEED_PECI_CLK_DIV_DEFAULT) |
-+ ASPEED_PECI_CTRL_PECI_CLK_EN, priv->base + ASPEED_PECI_CTRL);
-+
-+ /*
-+ * Timing negotiation period setting.
-+ * The unit of the programmed value is 4 times of PECI clock period.
-+ */
-+ writel(FIELD_PREP(ASPEED_PECI_TIMING_MESSAGE_MASK, msg_timing) |
-+ FIELD_PREP(ASPEED_PECI_TIMING_ADDRESS_MASK, addr_timing),
-+ priv->base + ASPEED_PECI_TIMING_NEGOTIATION);
-+
-+ /* Clear interrupts */
-+ writel(readl(priv->base + ASPEED_PECI_INT_STS) | ASPEED_PECI_INT_MASK,
-+ priv->base + ASPEED_PECI_INT_STS);
-+
-+ /* Set timing negotiation mode and enable interrupts */
-+ writel(FIELD_PREP(ASPEED_PECI_TIMING_NEGO_SEL_MASK,
-+ ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO) |
-+ ASPEED_PECI_INT_MASK, priv->base + ASPEED_PECI_INT_CTRL);
-+
-+ /* Read sampling point and clock speed setting */
-+ writel(FIELD_PREP(ASPEED_PECI_CTRL_SAMPLING_MASK, rd_sampling_point) |
-+ FIELD_PREP(ASPEED_PECI_CTRL_CLK_DIV_MASK, clk_div_val) |
-+ ASPEED_PECI_CTRL_PECI_EN | ASPEED_PECI_CTRL_PECI_CLK_EN,
-+ priv->base + ASPEED_PECI_CTRL);
-+
-+ return 0;
-+}
-+
-+static int aspeed_peci_probe(struct platform_device *pdev)
-+{
-+ struct peci_adapter *adapter;
-+ struct aspeed_peci *priv;
-+ 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);
-+
-+ priv->base = devm_platform_ioremap_resource(pdev, 0);
-+ if (IS_ERR(priv->base)) {
-+ ret = PTR_ERR(priv->base);
-+ 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, aspeed_peci_irq_handler,
-+ 0, "peci-aspeed-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 = aspeed_peci_xfer;
-+ priv->adapter->use_dma = false;
-+
-+ priv->rst = devm_reset_control_get(&pdev->dev, NULL);
-+ if (IS_ERR(priv->rst)) {
-+ dev_err(&pdev->dev,
-+ "missing or invalid reset controller entry\n");
-+ ret = PTR_ERR(priv->rst);
-+ goto err_put_adapter_dev;
-+ }
-+ reset_control_deassert(priv->rst);
-+
-+ ret = aspeed_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, irq %d\n",
-+ priv->adapter->nr, priv->irq);
-+
-+ return 0;
-+
-+err_put_adapter_dev:
-+ put_device(&adapter->dev);
-+ return ret;
-+}
-+
-+static int aspeed_peci_remove(struct platform_device *pdev)
-+{
-+ struct aspeed_peci *priv = dev_get_drvdata(&pdev->dev);
-+
-+ clk_disable_unprepare(priv->clk);
-+ reset_control_assert(priv->rst);
-+ peci_del_adapter(priv->adapter);
-+ of_node_put(priv->adapter->dev.of_node);
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id aspeed_peci_of_table[] = {
-+ { .compatible = "aspeed,ast2400-peci", },
-+ { .compatible = "aspeed,ast2500-peci", },
-+ { }
-+};
-+MODULE_DEVICE_TABLE(of, aspeed_peci_of_table);
-+
-+static struct platform_driver aspeed_peci_driver = {
-+ .probe = aspeed_peci_probe,
-+ .remove = aspeed_peci_remove,
-+ .driver = {
-+ .name = KBUILD_MODNAME,
-+ .of_match_table = of_match_ptr(aspeed_peci_of_table),
-+ },
-+};
-+module_platform_driver(aspeed_peci_driver);
-+
-+MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
-+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 0000000..f632365
---- /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 51cb256..0000000
---- a/drivers/peci/peci-aspeed.c
-+++ /dev/null
-@@ -1,505 +0,0 @@
--// SPDX-License-Identifier: GPL-2.0
--// Copyright (C) 2012-2017 ASPEED Technology Inc.
--// Copyright (c) 2018 Intel 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/reset.h>
--
--/* ASPEED PECI Registers */
--#define ASPEED_PECI_CTRL 0x00
--#define ASPEED_PECI_TIMING 0x04
--#define ASPEED_PECI_CMD 0x08
--#define ASPEED_PECI_CMD_CTRL 0x0c
--#define ASPEED_PECI_EXP_FCS 0x10
--#define ASPEED_PECI_CAP_FCS 0x14
--#define ASPEED_PECI_INT_CTRL 0x18
--#define ASPEED_PECI_INT_STS 0x1c
--#define ASPEED_PECI_W_DATA0 0x20
--#define ASPEED_PECI_W_DATA1 0x24
--#define ASPEED_PECI_W_DATA2 0x28
--#define ASPEED_PECI_W_DATA3 0x2c
--#define ASPEED_PECI_R_DATA0 0x30
--#define ASPEED_PECI_R_DATA1 0x34
--#define ASPEED_PECI_R_DATA2 0x38
--#define ASPEED_PECI_R_DATA3 0x3c
--#define ASPEED_PECI_W_DATA4 0x40
--#define ASPEED_PECI_W_DATA5 0x44
--#define ASPEED_PECI_W_DATA6 0x48
--#define ASPEED_PECI_W_DATA7 0x4c
--#define ASPEED_PECI_R_DATA4 0x50
--#define ASPEED_PECI_R_DATA5 0x54
--#define ASPEED_PECI_R_DATA6 0x58
--#define ASPEED_PECI_R_DATA7 0x5c
--
--/* ASPEED_PECI_CTRL - 0x00 : Control Register */
--#define PECI_CTRL_SAMPLING_MASK GENMASK(19, 16)
--#define PECI_CTRL_READ_MODE_MASK GENMASK(13, 12)
--#define PECI_CTRL_READ_MODE_COUNT BIT(12)
--#define PECI_CTRL_READ_MODE_DBG BIT(13)
--#define PECI_CTRL_CLK_SOURCE_MASK BIT(11)
--#define PECI_CTRL_CLK_DIV_MASK GENMASK(10, 8)
--#define PECI_CTRL_INVERT_OUT BIT(7)
--#define PECI_CTRL_INVERT_IN BIT(6)
--#define PECI_CTRL_BUS_CONTENT_EN BIT(5)
--#define PECI_CTRL_PECI_EN BIT(4)
--#define PECI_CTRL_PECI_CLK_EN BIT(0)
--
--/* ASPEED_PECI_TIMING - 0x04 : Timing Negotiation Register */
--#define PECI_TIMING_MESSAGE_MASK GENMASK(15, 8)
--#define PECI_TIMING_ADDRESS_MASK GENMASK(7, 0)
--
--/* ASPEED_PECI_CMD - 0x08 : Command Register */
--#define PECI_CMD_PIN_MON BIT(31)
--#define PECI_CMD_STS_MASK GENMASK(27, 24)
--#define PECI_CMD_IDLE_MASK (PECI_CMD_STS_MASK | PECI_CMD_PIN_MON)
--#define PECI_CMD_FIRE BIT(0)
--
--/* ASPEED_PECI_LEN - 0x0C : Read/Write Length Register */
--#define PECI_AW_FCS_EN BIT(31)
--#define PECI_READ_LEN_MASK GENMASK(23, 16)
--#define PECI_WRITE_LEN_MASK GENMASK(15, 8)
--#define PECI_TAGET_ADDR_MASK GENMASK(7, 0)
--
--/* ASPEED_PECI_EXP_FCS - 0x10 : Expected FCS Data Register */
--#define PECI_EXPECT_READ_FCS_MASK GENMASK(23, 16)
--#define PECI_EXPECT_AW_FCS_AUTO_MASK GENMASK(15, 8)
--#define PECI_EXPECT_WRITE_FCS_MASK GENMASK(7, 0)
--
--/* ASPEED_PECI_CAP_FCS - 0x14 : Captured FCS Data Register */
--#define PECI_CAPTURE_READ_FCS_MASK GENMASK(23, 16)
--#define PECI_CAPTURE_WRITE_FCS_MASK GENMASK(7, 0)
--
--/* ASPEED_PECI_INT_CTRL/STS - 0x18/0x1c : Interrupt Register */
--#define PECI_INT_TIMING_RESULT_MASK GENMASK(31, 30)
--#define PECI_INT_TIMEOUT BIT(4)
--#define PECI_INT_CONNECT BIT(3)
--#define PECI_INT_W_FCS_BAD BIT(2)
--#define PECI_INT_W_FCS_ABORT BIT(1)
--#define PECI_INT_CMD_DONE BIT(0)
--
--#define PECI_INT_MASK (PECI_INT_TIMEOUT | PECI_INT_CONNECT | \
-- PECI_INT_W_FCS_BAD | PECI_INT_W_FCS_ABORT | \
-- PECI_INT_CMD_DONE)
--
--#define PECI_IDLE_CHECK_TIMEOUT_USEC 50000
--#define PECI_IDLE_CHECK_INTERVAL_USEC 10000
--
--#define PECI_RD_SAMPLING_POINT_DEFAULT 8
--#define PECI_RD_SAMPLING_POINT_MAX 15
--#define PECI_CLK_DIV_DEFAULT 0
--#define PECI_CLK_DIV_MAX 7
--#define PECI_MSG_TIMING_DEFAULT 1
--#define PECI_MSG_TIMING_MAX 255
--#define PECI_ADDR_TIMING_DEFAULT 1
--#define PECI_ADDR_TIMING_MAX 255
--#define PECI_CMD_TIMEOUT_MS_DEFAULT 1000
--#define PECI_CMD_TIMEOUT_MS_MAX 60000
--
--struct aspeed_peci {
-- struct peci_adapter *adapter;
-- struct device *dev;
-- struct regmap *regmap;
-- struct clk *clk;
-- struct reset_control *rst;
-- int irq;
-- spinlock_t lock; /* to sync completion status handling */
-- struct completion xfer_complete;
-- u32 status;
-- u32 cmd_timeout_ms;
--};
--
--static int aspeed_peci_xfer_native(struct aspeed_peci *priv,
-- struct peci_xfer_msg *msg)
--{
-- long err, timeout = msecs_to_jiffies(priv->cmd_timeout_ms);
-- u32 peci_head, peci_state, rx_data, cmd_sts;
-- unsigned long flags;
-- int i, rc;
-- uint reg;
--
-- /* Check command sts and bus idle state */
-- rc = regmap_read_poll_timeout(priv->regmap, ASPEED_PECI_CMD, cmd_sts,
-- !(cmd_sts & PECI_CMD_IDLE_MASK),
-- PECI_IDLE_CHECK_INTERVAL_USEC,
-- PECI_IDLE_CHECK_TIMEOUT_USEC);
-- if (rc)
-- return rc; /* -ETIMEDOUT */
--
-- spin_lock_irqsave(&priv->lock, flags);
-- reinit_completion(&priv->xfer_complete);
--
-- peci_head = FIELD_PREP(PECI_TAGET_ADDR_MASK, msg->addr) |
-- FIELD_PREP(PECI_WRITE_LEN_MASK, msg->tx_len) |
-- FIELD_PREP(PECI_READ_LEN_MASK, msg->rx_len);
--
-- regmap_write(priv->regmap, ASPEED_PECI_CMD_CTRL, peci_head);
--
-- for (i = 0; i < msg->tx_len; i += 4) {
-- reg = i < 16 ? ASPEED_PECI_W_DATA0 + i % 16 :
-- ASPEED_PECI_W_DATA4 + i % 16;
-- regmap_write(priv->regmap, reg,
-- le32_to_cpup((__le32 *)&msg->tx_buf[i]));
-- }
--
-- dev_dbg(priv->dev, "HEAD : 0x%08x\n", peci_head);
-- print_hex_dump_debug("TX : ", DUMP_PREFIX_NONE, 16, 1,
-- msg->tx_buf, msg->tx_len, true);
--
-- priv->status = 0;
-- regmap_write(priv->regmap, ASPEED_PECI_CMD, PECI_CMD_FIRE);
-- spin_unlock_irqrestore(&priv->lock, flags);
--
-- err = wait_for_completion_interruptible_timeout(&priv->xfer_complete,
-- timeout);
--
-- spin_lock_irqsave(&priv->lock, flags);
-- dev_dbg(priv->dev, "INT_STS : 0x%08x\n", priv->status);
-- regmap_read(priv->regmap, ASPEED_PECI_CMD, &peci_state);
-- dev_dbg(priv->dev, "PECI_STATE : 0x%lx\n",
-- FIELD_GET(PECI_CMD_STS_MASK, peci_state));
--
-- regmap_write(priv->regmap, ASPEED_PECI_CMD, 0);
--
-- if (err <= 0 || priv->status != PECI_INT_CMD_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;
-- }
--
-- /**
-- * Note that rx_len and rx_buf size can be an odd number.
-- * Byte handling is more efficient.
-- */
-- for (i = 0; i < msg->rx_len; i++) {
-- u8 byte_offset = i % 4;
--
-- if (byte_offset == 0) {
-- reg = i < 16 ? ASPEED_PECI_R_DATA0 + i % 16 :
-- ASPEED_PECI_R_DATA4 + i % 16;
-- regmap_read(priv->regmap, reg, &rx_data);
-- }
--
-- msg->rx_buf[i] = (u8)(rx_data >> (byte_offset << 3));
-- }
--
-- print_hex_dump_debug("RX : ", DUMP_PREFIX_NONE, 16, 1,
-- msg->rx_buf, msg->rx_len, true);
--
-- regmap_read(priv->regmap, ASPEED_PECI_CMD, &peci_state);
-- dev_dbg(priv->dev, "PECI_STATE : 0x%lx\n",
-- FIELD_GET(PECI_CMD_STS_MASK, peci_state));
-- dev_dbg(priv->dev, "------------------------\n");
--
--err_irqrestore:
-- spin_unlock_irqrestore(&priv->lock, flags);
-- return rc;
--}
--
--static irqreturn_t aspeed_peci_irq_handler(int irq, void *arg)
--{
-- struct aspeed_peci *priv = arg;
-- u32 status_ack = 0;
-- u32 status;
--
-- spin_lock(&priv->lock);
-- regmap_read(priv->regmap, ASPEED_PECI_INT_STS, &status);
-- priv->status |= (status & PECI_INT_MASK);
--
-- /**
-- * In most cases, interrupt bits will be set one by one but also note
-- * that multiple interrupt bits could be set at the same time.
-- */
-- if (status & PECI_INT_TIMEOUT) {
-- dev_dbg(priv->dev, "PECI_INT_TIMEOUT\n");
-- status_ack |= PECI_INT_TIMEOUT;
-- }
--
-- if (status & PECI_INT_CONNECT) {
-- dev_dbg(priv->dev, "PECI_INT_CONNECT\n");
-- status_ack |= PECI_INT_CONNECT;
-- }
--
-- if (status & PECI_INT_W_FCS_BAD) {
-- dev_dbg(priv->dev, "PECI_INT_W_FCS_BAD\n");
-- status_ack |= PECI_INT_W_FCS_BAD;
-- }
--
-- if (status & PECI_INT_W_FCS_ABORT) {
-- dev_dbg(priv->dev, "PECI_INT_W_FCS_ABORT\n");
-- status_ack |= PECI_INT_W_FCS_ABORT;
-- }
--
-- /**
-- * All commands should be ended up with a PECI_INT_CMD_DONE bit set
-- * even in an error case.
-- */
-- if (status & PECI_INT_CMD_DONE) {
-- dev_dbg(priv->dev, "PECI_INT_CMD_DONE\n");
-- status_ack |= PECI_INT_CMD_DONE;
-- complete(&priv->xfer_complete);
-- }
--
-- regmap_write(priv->regmap, ASPEED_PECI_INT_STS, status_ack);
-- spin_unlock(&priv->lock);
-- return IRQ_HANDLED;
--}
--
--static int aspeed_peci_init_ctrl(struct aspeed_peci *priv)
--{
-- u32 msg_timing, addr_timing, rd_sampling_point;
-- u32 clk_freq, clk_divisor, clk_div_val = 0;
-- int ret;
--
-- 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, "clock-frequency",
-- &clk_freq);
-- if (ret) {
-- dev_err(priv->dev,
-- "Could not read clock-frequency property.\n");
-- clk_disable_unprepare(priv->clk);
-- return ret;
-- }
--
-- clk_divisor = clk_get_rate(priv->clk) / clk_freq;
--
-- while ((clk_divisor >> 1) && (clk_div_val < PECI_CLK_DIV_MAX))
-- clk_div_val++;
--
-- ret = of_property_read_u32(priv->dev->of_node, "msg-timing",
-- &msg_timing);
-- if (ret || msg_timing > PECI_MSG_TIMING_MAX) {
-- if (!ret)
-- dev_warn(priv->dev,
-- "Invalid msg-timing : %u, Use default : %u\n",
-- msg_timing, PECI_MSG_TIMING_DEFAULT);
-- msg_timing = PECI_MSG_TIMING_DEFAULT;
-- }
--
-- ret = of_property_read_u32(priv->dev->of_node, "addr-timing",
-- &addr_timing);
-- if (ret || addr_timing > PECI_ADDR_TIMING_MAX) {
-- if (!ret)
-- dev_warn(priv->dev,
-- "Invalid addr-timing : %u, Use default : %u\n",
-- addr_timing, PECI_ADDR_TIMING_DEFAULT);
-- addr_timing = PECI_ADDR_TIMING_DEFAULT;
-- }
--
-- ret = of_property_read_u32(priv->dev->of_node, "rd-sampling-point",
-- &rd_sampling_point);
-- if (ret || rd_sampling_point > PECI_RD_SAMPLING_POINT_MAX) {
-- if (!ret)
-- dev_warn(priv->dev,
-- "Invalid rd-sampling-point : %u. Use default : %u\n",
-- rd_sampling_point,
-- PECI_RD_SAMPLING_POINT_DEFAULT);
-- rd_sampling_point = PECI_RD_SAMPLING_POINT_DEFAULT;
-- }
--
-- ret = of_property_read_u32(priv->dev->of_node, "cmd-timeout-ms",
-- &priv->cmd_timeout_ms);
-- if (ret || priv->cmd_timeout_ms > PECI_CMD_TIMEOUT_MS_MAX ||
-- priv->cmd_timeout_ms == 0) {
-- if (!ret)
-- dev_warn(priv->dev,
-- "Invalid cmd-timeout-ms : %u. Use default : %u\n",
-- priv->cmd_timeout_ms,
-- PECI_CMD_TIMEOUT_MS_DEFAULT);
-- priv->cmd_timeout_ms = PECI_CMD_TIMEOUT_MS_DEFAULT;
-- }
--
-- regmap_write(priv->regmap, ASPEED_PECI_CTRL,
-- FIELD_PREP(PECI_CTRL_CLK_DIV_MASK, PECI_CLK_DIV_DEFAULT) |
-- PECI_CTRL_PECI_CLK_EN);
--
-- /**
-- * Timing negotiation period setting.
-- * The unit of the programmed value is 4 times of PECI clock period.
-- */
-- regmap_write(priv->regmap, ASPEED_PECI_TIMING,
-- FIELD_PREP(PECI_TIMING_MESSAGE_MASK, msg_timing) |
-- FIELD_PREP(PECI_TIMING_ADDRESS_MASK, addr_timing));
--
-- /* Clear interrupts */
-- regmap_write(priv->regmap, ASPEED_PECI_INT_STS, PECI_INT_MASK);
--
-- /* Enable interrupts */
-- regmap_write(priv->regmap, ASPEED_PECI_INT_CTRL, PECI_INT_MASK);
--
-- /* Read sampling point and clock speed setting */
-- regmap_write(priv->regmap, ASPEED_PECI_CTRL,
-- FIELD_PREP(PECI_CTRL_SAMPLING_MASK, rd_sampling_point) |
-- FIELD_PREP(PECI_CTRL_CLK_DIV_MASK, clk_div_val) |
-- PECI_CTRL_PECI_EN | PECI_CTRL_PECI_CLK_EN);
--
-- return 0;
--}
--
--static const struct regmap_config aspeed_peci_regmap_config = {
-- .reg_bits = 32,
-- .val_bits = 32,
-- .reg_stride = 4,
-- .max_register = ASPEED_PECI_R_DATA7,
-- .val_format_endian = REGMAP_ENDIAN_LITTLE,
-- .fast_io = true,
--};
--
--static int aspeed_peci_xfer(struct peci_adapter *adapter,
-- struct peci_xfer_msg *msg)
--{
-- struct aspeed_peci *priv = peci_get_adapdata(adapter);
--
-- return aspeed_peci_xfer_native(priv, msg);
--}
--
--static int aspeed_peci_probe(struct platform_device *pdev)
--{
-- struct peci_adapter *adapter;
-- struct aspeed_peci *priv;
-- struct resource *res;
-- void __iomem *base;
-- u32 cmd_sts;
-- 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,
-- &aspeed_peci_regmap_config);
-- if (IS_ERR(priv->regmap)) {
-- ret = PTR_ERR(priv->regmap);
-- goto err_put_adapter_dev;
-- }
--
-- /**
-- * We check that the regmap works on this very first access,
-- * but as this is an MMIO-backed regmap, subsequent regmap
-- * access is not going to fail and we skip error checks from
-- * this point.
-- */
-- ret = regmap_read(priv->regmap, ASPEED_PECI_CMD, &cmd_sts);
-- if (ret) {
-- ret = -EIO;
-- 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, aspeed_peci_irq_handler,
-- 0, "peci-aspeed-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 = aspeed_peci_xfer;
--
-- priv->rst = devm_reset_control_get(&pdev->dev, NULL);
-- if (IS_ERR(priv->rst)) {
-- dev_err(&pdev->dev,
-- "missing or invalid reset controller entry");
-- ret = PTR_ERR(priv->rst);
-- goto err_put_adapter_dev;
-- }
-- reset_control_deassert(priv->rst);
--
-- ret = aspeed_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, irq %d\n",
-- priv->adapter->nr, priv->irq);
--
-- return 0;
--
--err_put_adapter_dev:
-- put_device(&adapter->dev);
-- return ret;
--}
--
--static int aspeed_peci_remove(struct platform_device *pdev)
--{
-- struct aspeed_peci *priv = dev_get_drvdata(&pdev->dev);
--
-- clk_disable_unprepare(priv->clk);
-- reset_control_assert(priv->rst);
-- peci_del_adapter(priv->adapter);
-- of_node_put(priv->adapter->dev.of_node);
--
-- return 0;
--}
--
--static const struct of_device_id aspeed_peci_of_table[] = {
-- { .compatible = "aspeed,ast2400-peci", },
-- { .compatible = "aspeed,ast2500-peci", },
-- { }
--};
--MODULE_DEVICE_TABLE(of, aspeed_peci_of_table);
--
--static struct platform_driver aspeed_peci_driver = {
-- .probe = aspeed_peci_probe,
-- .remove = aspeed_peci_remove,
-- .driver = {
-- .name = "peci-aspeed",
-- .of_match_table = of_match_ptr(aspeed_peci_of_table),
-- },
--};
--module_platform_driver(aspeed_peci_driver);
--
--MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>");
--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/peci-core.c b/drivers/peci/peci-core.c
-index 6f24146..2a6be04 100644
---- a/drivers/peci/peci-core.c
-+++ b/drivers/peci/peci-core.c
-@@ -1,38 +1,31 @@
- // SPDX-License-Identifier: GPL-2.0
--// Copyright (c) 2018 Intel Corporation
-+// Copyright (c) 2018-2019 Intel Corporation
-
- #include <linux/bitfield.h>
- #include <linux/crc8.h>
- #include <linux/delay.h>
--#include <linux/fs.h>
-+#include <linux/mm.h>
- #include <linux/module.h>
- #include <linux/of_device.h>
- #include <linux/peci.h>
- #include <linux/pm_domain.h>
- #include <linux/pm_runtime.h>
-+#include <linux/sched/task_stack.h>
- #include <linux/slab.h>
--#include <linux/uaccess.h>
-
- /* Mask for getting minor revision number from DIB */
- #define REVISION_NUM_MASK GENMASK(15, 8)
-
--/* CRC8 table for Assure Write Frame Check */
-+/* CRC8 table for Assured Write Frame Check */
- #define PECI_CRC8_POLYNOMIAL 0x07
- DECLARE_CRC8_TABLE(peci_crc8_table);
-
--static struct device_type peci_adapter_type;
--static struct device_type peci_client_type;
--
--/* Max number of peci cdev */
--#define PECI_CDEV_MAX 16
--
--static dev_t peci_devt;
- static bool is_registered;
-
- static DEFINE_MUTEX(core_lock);
- static DEFINE_IDR(peci_adapter_idr);
-
--static struct peci_adapter *peci_get_adapter(int nr)
-+struct peci_adapter *peci_get_adapter(int nr)
- {
- struct peci_adapter *adapter;
-
-@@ -48,10 +41,12 @@ static struct peci_adapter *peci_get_adapter(int nr)
-
- out_unlock:
- mutex_unlock(&core_lock);
-+
- return adapter;
- }
-+EXPORT_SYMBOL_GPL(peci_get_adapter);
-
--static void peci_put_adapter(struct peci_adapter *adapter)
-+void peci_put_adapter(struct peci_adapter *adapter)
- {
- if (!adapter)
- return;
-@@ -59,6 +54,7 @@ static void peci_put_adapter(struct peci_adapter *adapter)
- put_device(&adapter->dev);
- module_put(adapter->owner);
- }
-+EXPORT_SYMBOL_GPL(peci_put_adapter);
-
- static ssize_t name_show(struct device *dev,
- struct device_attribute *attr,
-@@ -84,10 +80,11 @@ static struct attribute *peci_device_attrs[] = {
- };
- ATTRIBUTE_GROUPS(peci_device);
-
--static struct device_type peci_client_type = {
-+struct device_type peci_client_type = {
- .groups = peci_device_groups,
- .release = peci_client_dev_release,
- };
-+EXPORT_SYMBOL_GPL(peci_client_type);
-
- /**
- * peci_verify_client - return parameter as peci_client, or NULL
-@@ -103,19 +100,120 @@ struct peci_client *peci_verify_client(struct device *dev)
- }
- EXPORT_SYMBOL_GPL(peci_verify_client);
-
--static u8 peci_aw_fcs(u8 *data, int len)
-+/**
-+ * peci_get_xfer_msg() - get a DMA safe peci_xfer_msg for the given tx and rx
-+ * length
-+ * @tx_len: the length of tx_buf. May be 0 if tx_buf isn't needed.
-+ * @rx_len: the length of rx_buf. May be 0 if rx_buf isn't needed.
-+ *
-+ * Return: NULL if a DMA safe buffer was not obtained.
-+ * Or a valid pointer to be used with DMA. After use, release it by
-+ * calling peci_put_xfer_msg().
-+ *
-+ * This function must only be called from process context!
-+ */
-+struct peci_xfer_msg *peci_get_xfer_msg(u8 tx_len, u8 rx_len)
-+{
-+ struct peci_xfer_msg *msg;
-+ u8 *tx_buf, *rx_buf;
-+
-+ if (tx_len) {
-+ tx_buf = kzalloc(tx_len, GFP_KERNEL);
-+ if (!tx_buf)
-+ return NULL;
-+ } else {
-+ tx_buf = NULL;
-+ }
-+
-+ if (rx_len) {
-+ rx_buf = kzalloc(rx_len, GFP_KERNEL);
-+ if (!rx_buf)
-+ goto err_free_tx_buf;
-+ } else {
-+ rx_buf = NULL;
-+ }
-+
-+ msg = kzalloc(sizeof(struct peci_xfer_msg), GFP_KERNEL);
-+ if (!msg)
-+ goto err_free_tx_rx_buf;
-+
-+ msg->tx_len = tx_len;
-+ msg->tx_buf = tx_buf;
-+ msg->rx_len = rx_len;
-+ msg->rx_buf = rx_buf;
-+
-+ return msg;
-+
-+err_free_tx_rx_buf:
-+ kfree(rx_buf);
-+err_free_tx_buf:
-+ kfree(tx_buf);
-+
-+ return NULL;
-+}
-+EXPORT_SYMBOL_GPL(peci_get_xfer_msg);
-+
-+/**
-+ * peci_put_xfer_msg - release a DMA safe peci_xfer_msg
-+ * @msg: the message obtained from peci_get_xfer_msg(). May be NULL.
-+ */
-+void peci_put_xfer_msg(struct peci_xfer_msg *msg)
-+{
-+ if (!msg)
-+ return;
-+
-+ kfree(msg->rx_buf);
-+ kfree(msg->tx_buf);
-+ kfree(msg);
-+}
-+EXPORT_SYMBOL_GPL(peci_put_xfer_msg);
-+
-+/* 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 */
-+ tmp_buf = kmalloc(len, GFP_KERNEL);
-+ if (!tmp_buf)
-+ return -ENOMEM;
-+
-+ tmp_buf[0] = msg->addr;
-+ tmp_buf[1] = msg->tx_len;
-+ tmp_buf[2] = msg->rx_len;
-+ memcpy(&tmp_buf[3], msg->tx_buf, len - 3);
-+
-+ *aw_fcs = crc8(peci_crc8_table, tmp_buf, (size_t)len, 0);
-+
-+ kfree(tmp_buf);
-+
-+ return 0;
- }
-
- static int __peci_xfer(struct peci_adapter *adapter, struct peci_xfer_msg *msg,
- bool do_retry, bool has_aw_fcs)
- {
-- ktime_t start, end;
-- s64 elapsed_ms;
-- int rc = 0;
-+ 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.
-+ */
-+ if (IS_ENABLED(CONFIG_HAS_DMA) && adapter->use_dma) {
-+ if (is_vmalloc_addr(msg->tx_buf) ||
-+ is_vmalloc_addr(msg->rx_buf)) {
-+ WARN_ONCE(1, "xfer msg is not dma capable\n");
-+ return -EAGAIN;
-+ } else if (object_is_on_stack(msg->tx_buf) ||
-+ object_is_on_stack(msg->rx_buf)) {
-+ WARN_ONCE(1, "xfer msg is on stack\n");
-+ 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,51 @@ static int __peci_xfer(struct peci_adapter *adapter, struct peci_xfer_msg *msg,
- */
-
- if (do_retry)
-- start = ktime_get();
-+ timeout += msecs_to_jiffies(PECI_DEV_RETRY_TIME_MS);
-
-- do {
-- rc = adapter->xfer(adapter, msg);
-+ for (;;) {
-+ ret = adapter->xfer(adapter, msg);
-
-- if (!do_retry || rc)
-- break;
--
-- if (msg->rx_buf[0] == DEV_PECI_CC_SUCCESS)
-+ if (!do_retry || ret || !msg->rx_buf)
- break;
-
- /* Retry is needed when completion code is 0x8x */
-- if ((msg->rx_buf[0] & DEV_PECI_CC_RETRY_CHECK_MASK) !=
-- DEV_PECI_CC_NEED_RETRY) {
-- rc = -EIO;
-+ if ((msg->rx_buf[0] & PECI_DEV_CC_RETRY_CHECK_MASK) !=
-+ PECI_DEV_CC_NEED_RETRY)
- break;
-- }
-
- /* Set the retry bit to indicate a retry attempt */
-- msg->tx_buf[1] |= DEV_PECI_RETRY_BIT;
-+ msg->tx_buf[1] |= PECI_DEV_RETRY_BIT;
-
- /* Recalculate the AW FCS if it has one */
-- if (has_aw_fcs)
-- msg->tx_buf[msg->tx_len - 1] = 0x80 ^
-- peci_aw_fcs((u8 *)msg,
-- 2 + msg->tx_len);
-+ if (has_aw_fcs) {
-+ 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:
- * No minimum < Retry Interval < No maximum
- * (recommend 10ms)
- */
-- end = ktime_get();
-- elapsed_ms = ktime_to_ms(ktime_sub(end, start));
-- if (elapsed_ms >= DEV_PECI_RETRY_TIME_MS) {
-+ if (time_after(jiffies, timeout)) {
- dev_dbg(&adapter->dev, "Timeout retrying xfer!\n");
-- rc = -ETIMEDOUT;
-+ ret = -ETIMEDOUT;
- break;
- }
-
-- usleep_range((DEV_PECI_RETRY_INTERVAL_USEC >> 2) + 1,
-- DEV_PECI_RETRY_INTERVAL_USEC);
-- } while (true);
-+ usleep_range((PECI_DEV_RETRY_INTERVAL_USEC >> 2) + 1,
-+ PECI_DEV_RETRY_INTERVAL_USEC);
-+ }
-
-- if (rc)
-- dev_dbg(&adapter->dev, "xfer error, rc: %d\n", rc);
-+ if (ret)
-+ dev_dbg(&adapter->dev, "xfer error: %d\n", ret);
-
-- return rc;
-+ return ret;
- }
-
- static int peci_xfer(struct peci_adapter *adapter, struct peci_xfer_msg *msg)
-@@ -190,34 +284,37 @@ static int peci_xfer_with_retries(struct peci_adapter *adapter,
-
- static int peci_scan_cmd_mask(struct peci_adapter *adapter)
- {
-- struct peci_xfer_msg msg;
-+ struct peci_xfer_msg *msg;
- u8 revision;
-- int rc = 0;
-+ int ret;
- u64 dib;
-
- /* Update command mask just once */
- if (adapter->cmd_mask & BIT(PECI_CMD_XFER))
- return 0;
-
-- msg.addr = PECI_BASE_ADDR;
-- msg.tx_len = GET_DIB_WR_LEN;
-- msg.rx_len = GET_DIB_RD_LEN;
-- msg.tx_buf[0] = GET_DIB_PECI_CMD;
-+ msg = peci_get_xfer_msg(PECI_GET_DIB_WR_LEN, PECI_GET_DIB_RD_LEN);
-+ if (!msg)
-+ return -ENOMEM;
-+
-+ msg->addr = PECI_BASE_ADDR;
-+ msg->tx_buf[0] = PECI_GET_DIB_CMD;
-
-- rc = peci_xfer(adapter, &msg);
-- if (rc)
-- return rc;
-+ ret = peci_xfer(adapter, msg);
-+ if (ret)
-+ return ret;
-
-- dib = le64_to_cpup((__le64 *)msg.rx_buf);
-+ dib = le64_to_cpup((__le64 *)msg->rx_buf);
-
- /* Check special case for Get DIB command */
- if (dib == 0) {
- dev_dbg(&adapter->dev, "DIB read as 0\n");
-- return -EIO;
-+ ret = -EIO;
-+ 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 +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);
-
-- return rc;
-+out:
-+ peci_put_xfer_msg(msg);
-+
-+ return ret;
- }
-
--static int peci_cmd_support(struct peci_adapter *adapter, enum peci_cmd cmd)
-+static int peci_check_cmd_support(struct peci_adapter *adapter,
-+ enum peci_cmd cmd)
- {
- if (!(adapter->cmd_mask & BIT(PECI_CMD_PING)) &&
- peci_scan_cmd_mask(adapter) < 0) {
-@@ -262,70 +363,130 @@ static int peci_cmd_support(struct peci_adapter *adapter, enum peci_cmd cmd)
- return 0;
- }
-
--static int peci_ioctl_xfer(struct peci_adapter *adapter, void *vmsg)
-+static int peci_cmd_xfer(struct peci_adapter *adapter, void *vmsg)
- {
- struct peci_xfer_msg *msg = vmsg;
-+ u8 aw_fcs;
-+ int ret;
-+
-+ if (!msg->tx_len) {
-+ ret = peci_xfer(adapter, msg);
-+ } else {
-+ switch (msg->tx_buf[0]) {
-+ case PECI_RDPKGCFG_CMD:
-+ case PECI_RDIAMSR_CMD:
-+ case PECI_RDPCICFG_CMD:
-+ case PECI_RDPCICFGLOCAL_CMD:
-+ ret = peci_xfer_with_retries(adapter, msg, false);
-+ break;
-+ case PECI_WRPKGCFG_CMD:
-+ case PECI_WRIAMSR_CMD:
-+ case PECI_WRPCICFG_CMD:
-+ case PECI_WRPCICFGLOCAL_CMD:
-+ /* Check if the AW FCS byte is already provided */
-+ ret = peci_aw_fcs(msg, 2 + msg->tx_len, &aw_fcs);
-+ if (ret)
-+ break;
-+
-+ if (msg->tx_buf[msg->tx_len - 1] != (0x80 ^ aw_fcs)) {
-+ /* Add an Assured Write Frame Check Sequence byte */
-+ /* Increment the tx_len to include the new byte */
-+ msg->tx_len++;
-+ ret = peci_aw_fcs(msg, 2 + msg->tx_len,
-+ &aw_fcs);
-+ if (ret)
-+ break;
-+
-+ msg->tx_buf[msg->tx_len - 1] = 0x80 ^ aw_fcs;
-+ }
-+
-+ ret = peci_xfer_with_retries(adapter, msg, true);
-+ break;
-+ case PECI_GET_DIB_CMD:
-+ case PECI_GET_TEMP_CMD:
-+ default:
-+ ret = peci_xfer(adapter, msg);
-+ break;
-+ }
-+ }
-
-- return peci_xfer(adapter, msg);
-+ return ret;
- }
-
--static int peci_ioctl_ping(struct peci_adapter *adapter, void *vmsg)
-+static int peci_cmd_ping(struct peci_adapter *adapter, void *vmsg)
- {
- struct peci_ping_msg *umsg = vmsg;
-- 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.tx_len = 0;
-- msg.rx_len = 0;
-+ msg->addr = umsg->addr;
-
-- return peci_xfer(adapter, &msg);
-+ ret = peci_xfer(adapter, msg);
-+
-+ peci_put_xfer_msg(msg);
-+
-+ return ret;
- }
-
--static int peci_ioctl_get_dib(struct peci_adapter *adapter, void *vmsg)
-+static int peci_cmd_get_dib(struct peci_adapter *adapter, void *vmsg)
- {
- struct peci_get_dib_msg *umsg = vmsg;
-- struct peci_xfer_msg msg;
-- int rc;
-+ struct peci_xfer_msg *msg;
-+ int ret;
-
-- msg.addr = umsg->addr;
-- msg.tx_len = GET_DIB_WR_LEN;
-- msg.rx_len = GET_DIB_RD_LEN;
-- msg.tx_buf[0] = GET_DIB_PECI_CMD;
-+ msg = peci_get_xfer_msg(PECI_GET_DIB_WR_LEN, PECI_GET_DIB_RD_LEN);
-+ if (!msg)
-+ return -ENOMEM;
-
-- rc = peci_xfer(adapter, &msg);
-- if (rc)
-- return rc;
-+ msg->addr = umsg->addr;
-+ msg->tx_buf[0] = PECI_GET_DIB_CMD;
-
-- umsg->dib = le64_to_cpup((__le64 *)msg.rx_buf);
-+ ret = peci_xfer(adapter, msg);
-+ if (ret)
-+ goto out;
-
-- return 0;
-+ umsg->dib = le64_to_cpup((__le64 *)msg->rx_buf);
-+
-+out:
-+ peci_put_xfer_msg(msg);
-+
-+ return ret;
- }
-
--static int peci_ioctl_get_temp(struct peci_adapter *adapter, void *vmsg)
-+static int peci_cmd_get_temp(struct peci_adapter *adapter, void *vmsg)
- {
- struct peci_get_temp_msg *umsg = vmsg;
-- struct peci_xfer_msg msg;
-- int rc;
-+ struct peci_xfer_msg *msg;
-+ int ret;
-
-- msg.addr = umsg->addr;
-- msg.tx_len = GET_TEMP_WR_LEN;
-- msg.rx_len = GET_TEMP_RD_LEN;
-- msg.tx_buf[0] = GET_TEMP_PECI_CMD;
-+ msg = peci_get_xfer_msg(PECI_GET_TEMP_WR_LEN, PECI_GET_TEMP_RD_LEN);
-+ if (!msg)
-+ return -ENOMEM;
-
-- rc = peci_xfer(adapter, &msg);
-- if (rc)
-- return rc;
-+ msg->addr = umsg->addr;
-+ msg->tx_buf[0] = PECI_GET_TEMP_CMD;
-
-- umsg->temp_raw = le16_to_cpup((__le16 *)msg.rx_buf);
-+ ret = peci_xfer(adapter, msg);
-+ if (ret)
-+ goto out;
-
-- return 0;
-+ umsg->temp_raw = le16_to_cpup((__le16 *)msg->rx_buf);
-+
-+out:
-+ peci_put_xfer_msg(msg);
-+
-+ return ret;
- }
-
--static int peci_ioctl_rd_pkg_cfg(struct peci_adapter *adapter, void *vmsg)
-+static int peci_cmd_rd_pkg_cfg(struct peci_adapter *adapter, void *vmsg)
- {
- struct peci_rd_pkg_cfg_msg *umsg = vmsg;
-- struct peci_xfer_msg msg;
-- int rc = 0;
-+ struct peci_xfer_msg *msg;
-+ int ret;
-
- /* 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 +495,35 @@ static int peci_ioctl_rd_pkg_cfg(struct peci_adapter *adapter, void *vmsg)
- return -EINVAL;
- }
-
-- msg.addr = umsg->addr;
-- msg.tx_len = RDPKGCFG_WRITE_LEN;
-- /* read lengths of 1 and 2 result in an error, so only use 4 for now */
-- msg.rx_len = RDPKGCFG_READ_LEN_BASE + umsg->rx_len;
-- msg.tx_buf[0] = RDPKGCFG_PECI_CMD;
-- msg.tx_buf[1] = 0; /* request byte for Host ID | Retry bit */
-- /* Host ID is 0 for PECI 3.0 */
-- 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 */
-+ msg = peci_get_xfer_msg(PECI_RDPKGCFG_WRITE_LEN,
-+ PECI_RDPKGCFG_READ_LEN_BASE + umsg->rx_len);
-+ if (!msg)
-+ return -ENOMEM;
-+
-+ msg->addr = umsg->addr;
-+ msg->tx_buf[0] = PECI_RDPKGCFG_CMD;
-+ msg->tx_buf[1] = 0; /* request byte for Host ID | Retry bit */
-+ /* Host ID is 0 for PECI 3.0 */
-+ 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);
-+ umsg->cc = msg->rx_buf[0];
-+ peci_put_xfer_msg(msg);
-
-- return rc;
-+ return ret;
- }
-
--static int peci_ioctl_wr_pkg_cfg(struct peci_adapter *adapter, void *vmsg)
-+static int peci_cmd_wr_pkg_cfg(struct peci_adapter *adapter, void *vmsg)
- {
- struct peci_wr_pkg_cfg_msg *umsg = vmsg;
-- struct peci_xfer_msg msg;
-- int rc = 0, i;
-+ struct peci_xfer_msg *msg;
-+ int ret, i;
-+ u8 aw_fcs;
-
- /* Per the PECI spec, the write length must be a dword */
- if (umsg->tx_len != 4) {
-@@ -365,86 +532,116 @@ static int peci_ioctl_wr_pkg_cfg(struct peci_adapter *adapter, void *vmsg)
- return -EINVAL;
- }
-
-- msg.addr = umsg->addr;
-- msg.tx_len = WRPKGCFG_WRITE_LEN_BASE + umsg->tx_len;
-- /* read lengths of 1 and 2 result in an error, so only use 4 for now */
-- msg.rx_len = WRPKGCFG_READ_LEN;
-- msg.tx_buf[0] = WRPKGCFG_PECI_CMD;
-- msg.tx_buf[1] = 0; /* request byte for Host ID | Retry bit */
-+ msg = peci_get_xfer_msg(PECI_WRPKGCFG_WRITE_LEN_BASE + umsg->tx_len,
-+ PECI_WRPKGCFG_READ_LEN);
-+ if (!msg)
-+ return -ENOMEM;
-+
-+ msg->addr = umsg->addr;
-+ msg->tx_buf[0] = PECI_WRPKGCFG_CMD;
-+ msg->tx_buf[1] = 0; /* request byte for Host ID | Retry bit */
- /* Host ID is 0 for PECI 3.0 */
-- 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 */
-+ 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 */
- for (i = 0; i < umsg->tx_len; i++)
-- msg.tx_buf[5 + i] = (u8)(umsg->value >> (i << 3));
-+ msg->tx_buf[5 + i] = (u8)(umsg->value >> (i << 3));
-+
-+ /* Add an Assured Write Frame Check Sequence byte */
-+ 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);
-
-- rc = peci_xfer_with_retries(adapter, &msg, true);
-+out:
-+ umsg->cc = msg->rx_buf[0];
-+ peci_put_xfer_msg(msg);
-
-- return rc;
-+ return ret;
- }
-
--static int peci_ioctl_rd_ia_msr(struct peci_adapter *adapter, void *vmsg)
-+static int peci_cmd_rd_ia_msr(struct peci_adapter *adapter, void *vmsg)
- {
- struct peci_rd_ia_msr_msg *umsg = vmsg;
-- struct peci_xfer_msg msg;
-- int rc = 0;
--
-- msg.addr = umsg->addr;
-- msg.tx_len = RDIAMSR_WRITE_LEN;
-- msg.rx_len = RDIAMSR_READ_LEN;
-- msg.tx_buf[0] = RDIAMSR_PECI_CMD;
-- msg.tx_buf[1] = 0;
-- msg.tx_buf[2] = umsg->thread_id;
-- msg.tx_buf[3] = (u8)umsg->address;
-- msg.tx_buf[4] = (u8)(umsg->address >> 8);
--
-- rc = peci_xfer_with_retries(adapter, &msg, false);
-- if (!rc)
-- memcpy(&umsg->value, &msg.rx_buf[1], sizeof(uint64_t));
--
-- return rc;
-+ struct peci_xfer_msg *msg;
-+ int ret;
-+
-+ msg = peci_get_xfer_msg(PECI_RDIAMSR_WRITE_LEN, PECI_RDIAMSR_READ_LEN);
-+ if (!msg)
-+ return -ENOMEM;
-+
-+ msg->addr = umsg->addr;
-+ msg->tx_buf[0] = PECI_RDIAMSR_CMD;
-+ msg->tx_buf[1] = 0;
-+ msg->tx_buf[2] = umsg->thread_id;
-+ msg->tx_buf[3] = (u8)umsg->address;
-+ msg->tx_buf[4] = (u8)(umsg->address >> 8);
-+
-+ ret = peci_xfer_with_retries(adapter, msg, false);
-+ 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_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;
-- struct peci_xfer_msg msg;
-+ struct peci_xfer_msg *msg;
- u32 address;
-- int rc = 0;
-+ int ret;
-+
-+ msg = peci_get_xfer_msg(PECI_RDPCICFG_WRITE_LEN,
-+ PECI_RDPCICFG_READ_LEN);
-+ if (!msg)
-+ return -ENOMEM;
-
- address = umsg->reg; /* [11:0] - Register */
- address |= (u32)umsg->function << 12; /* [14:12] - Function */
- address |= (u32)umsg->device << 15; /* [19:15] - Device */
- address |= (u32)umsg->bus << 20; /* [27:20] - Bus */
- /* [31:28] - Reserved */
-- msg.addr = umsg->addr;
-- msg.tx_len = RDPCICFG_WRITE_LEN;
-- msg.rx_len = RDPCICFG_READ_LEN;
-- msg.tx_buf[0] = RDPCICFG_PECI_CMD;
-- msg.tx_buf[1] = 0; /* request byte for Host ID | Retry bit */
-+ msg->addr = umsg->addr;
-+ msg->tx_buf[0] = PECI_RDPCICFG_CMD;
-+ msg->tx_buf[1] = 0; /* request byte for Host ID | Retry bit */
- /* Host ID is 0 for PECI 3.0 */
-- msg.tx_buf[2] = (u8)address; /* LSB - PCI Config Address */
-- msg.tx_buf[3] = (u8)(address >> 8); /* PCI Config Address */
-- msg.tx_buf[4] = (u8)(address >> 16); /* PCI Config Address */
-- msg.tx_buf[5] = (u8)(address >> 24); /* MSB - PCI Config Address */
-+ msg->tx_buf[2] = (u8)address; /* LSB - PCI Config Address */
-+ msg->tx_buf[3] = (u8)(address >> 8); /* PCI Config Address */
-+ msg->tx_buf[4] = (u8)(address >> 16); /* PCI Config Address */
-+ msg->tx_buf[5] = (u8)(address >> 24); /* MSB - PCI Config Address */
-+
-+ ret = peci_xfer_with_retries(adapter, msg, false);
-+ if (!ret)
-+ memcpy(umsg->pci_config, &msg->rx_buf[1], 4);
-+
-+ umsg->cc = msg->rx_buf[0];
-+ peci_put_xfer_msg(msg);
-
-- rc = peci_xfer_with_retries(adapter, &msg, false);
-- if (!rc)
-- memcpy(umsg->pci_config, &msg.rx_buf[1], 4);
-+ return ret;
-+}
-
-- return rc;
-+static int peci_cmd_wr_pci_cfg(struct peci_adapter *adapter, void *vmsg)
-+{
-+ return -ENOSYS; /* Not implemented yet */
- }
-
--static int peci_ioctl_rd_pci_cfg_local(struct peci_adapter *adapter, void *vmsg)
-+static int peci_cmd_rd_pci_cfg_local(struct peci_adapter *adapter, void *vmsg)
- {
- struct peci_rd_pci_cfg_local_msg *umsg = vmsg;
-- struct peci_xfer_msg msg;
-+ struct peci_xfer_msg *msg;
- u32 address;
-- int rc = 0;
-+ int ret;
-
- /* 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 +650,42 @@ static int peci_ioctl_rd_pci_cfg_local(struct peci_adapter *adapter, void *vmsg)
- return -EINVAL;
- }
-
-+ msg = peci_get_xfer_msg(PECI_RDPCICFGLOCAL_WRITE_LEN,
-+ PECI_RDPCICFGLOCAL_READ_LEN_BASE +
-+ umsg->rx_len);
-+ if (!msg)
-+ return -ENOMEM;
-+
- address = umsg->reg; /* [11:0] - Register */
- address |= (u32)umsg->function << 12; /* [14:12] - Function */
- address |= (u32)umsg->device << 15; /* [19:15] - Device */
- address |= (u32)umsg->bus << 20; /* [23:20] - Bus */
-
-- msg.addr = umsg->addr;
-- msg.tx_len = RDPCICFGLOCAL_WRITE_LEN;
-- msg.rx_len = RDPCICFGLOCAL_READ_LEN_BASE + umsg->rx_len;
-- msg.tx_buf[0] = RDPCICFGLOCAL_PECI_CMD;
-- msg.tx_buf[1] = 0; /* request byte for Host ID | Retry bit */
-- /* Host ID is 0 for PECI 3.0 */
-- msg.tx_buf[2] = (u8)address; /* LSB - PCI Configuration Address */
-- msg.tx_buf[3] = (u8)(address >> 8); /* PCI Configuration Address */
-- msg.tx_buf[4] = (u8)(address >> 16); /* PCI Configuration Address */
-+ msg->addr = umsg->addr;
-+ msg->tx_buf[0] = PECI_RDPCICFGLOCAL_CMD;
-+ msg->tx_buf[1] = 0; /* request byte for Host ID | Retry bit */
-+ /* Host ID is 0 for PECI 3.0 */
-+ msg->tx_buf[2] = (u8)address; /* LSB - PCI Configuration Address */
-+ msg->tx_buf[3] = (u8)(address >> 8); /* PCI Configuration Address */
-+ msg->tx_buf[4] = (u8)(address >> 16); /* PCI Configuration Address */
-+
-+ ret = peci_xfer_with_retries(adapter, msg, false);
-+ if (!ret)
-+ memcpy(umsg->pci_config, &msg->rx_buf[1], umsg->rx_len);
-
-- 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;
-+ return ret;
- }
-
--static int peci_ioctl_wr_pci_cfg_local(struct peci_adapter *adapter, void *vmsg)
-+static int peci_cmd_wr_pci_cfg_local(struct peci_adapter *adapter, void *vmsg)
- {
- struct peci_wr_pci_cfg_local_msg *umsg = vmsg;
-- struct peci_xfer_msg msg;
-- int rc = 0, i;
-+ struct peci_xfer_msg *msg;
- u32 address;
-+ int ret, i;
-+ u8 aw_fcs;
-
- /* 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 +694,57 @@ static int peci_ioctl_wr_pci_cfg_local(struct peci_adapter *adapter, void *vmsg)
- return -EINVAL;
- }
-
-+ msg = peci_get_xfer_msg(PECI_WRPCICFGLOCAL_WRITE_LEN_BASE +
-+ umsg->tx_len, PECI_WRPCICFGLOCAL_READ_LEN);
-+ if (!msg)
-+ return -ENOMEM;
-+
- address = umsg->reg; /* [11:0] - Register */
- address |= (u32)umsg->function << 12; /* [14:12] - Function */
- address |= (u32)umsg->device << 15; /* [19:15] - Device */
- address |= (u32)umsg->bus << 20; /* [23:20] - Bus */
-
-- msg.addr = umsg->addr;
-- msg.tx_len = WRPCICFGLOCAL_WRITE_LEN_BASE + umsg->tx_len;
-- msg.rx_len = WRPCICFGLOCAL_READ_LEN;
-- msg.tx_buf[0] = WRPCICFGLOCAL_PECI_CMD;
-- msg.tx_buf[1] = 0; /* request byte for Host ID | Retry bit */
-- /* Host ID is 0 for PECI 3.0 */
-- msg.tx_buf[2] = (u8)address; /* LSB - PCI Configuration Address */
-- msg.tx_buf[3] = (u8)(address >> 8); /* PCI Configuration Address */
-- msg.tx_buf[4] = (u8)(address >> 16); /* PCI Configuration Address */
-+ msg->addr = umsg->addr;
-+ msg->tx_buf[0] = PECI_WRPCICFGLOCAL_CMD;
-+ msg->tx_buf[1] = 0; /* request byte for Host ID | Retry bit */
-+ /* Host ID is 0 for PECI 3.0 */
-+ msg->tx_buf[2] = (u8)address; /* LSB - PCI Configuration Address */
-+ msg->tx_buf[3] = (u8)(address >> 8); /* PCI Configuration Address */
-+ msg->tx_buf[4] = (u8)(address >> 16); /* PCI Configuration Address */
- for (i = 0; i < umsg->tx_len; i++)
-- msg.tx_buf[5 + i] = (u8)(umsg->value >> (i << 3));
-+ msg->tx_buf[5 + i] = (u8)(umsg->value >> (i << 3));
-+
-+ /* Add an Assured Write Frame Check Sequence byte */
-+ ret = peci_aw_fcs(msg, 8 + umsg->tx_len, &aw_fcs);
-+ if (ret)
-+ goto out;
-
-- /* Add an Assure Write Frame Check Sequence byte */
-- msg.tx_buf[5 + i] = 0x80 ^
-- peci_aw_fcs((u8 *)&msg, 8 + umsg->tx_len);
-+ msg->tx_buf[5 + i] = 0x80 ^ aw_fcs;
-
-- rc = peci_xfer_with_retries(adapter, &msg, true);
-+ ret = peci_xfer_with_retries(adapter, msg, true);
-
-- return rc;
-+out:
-+ umsg->cc = msg->rx_buf[0];
-+ peci_put_xfer_msg(msg);
-+
-+ return ret;
- }
-
--typedef int (*peci_ioctl_fn_type)(struct peci_adapter *, void *);
--
--static const peci_ioctl_fn_type peci_ioctl_fn[PECI_CMD_MAX] = {
-- peci_ioctl_xfer,
-- peci_ioctl_ping,
-- peci_ioctl_get_dib,
-- peci_ioctl_get_temp,
-- peci_ioctl_rd_pkg_cfg,
-- peci_ioctl_wr_pkg_cfg,
-- peci_ioctl_rd_ia_msr,
-- NULL, /* Reserved */
-- peci_ioctl_rd_pci_cfg,
-- NULL, /* Reserved */
-- peci_ioctl_rd_pci_cfg_local,
-- peci_ioctl_wr_pci_cfg_local,
-+typedef int (*peci_cmd_fn_type)(struct peci_adapter *, void *);
-+
-+static const peci_cmd_fn_type peci_cmd_fn[PECI_CMD_MAX] = {
-+ peci_cmd_xfer,
-+ peci_cmd_ping,
-+ peci_cmd_get_dib,
-+ peci_cmd_get_temp,
-+ peci_cmd_rd_pkg_cfg,
-+ peci_cmd_wr_pkg_cfg,
-+ peci_cmd_rd_ia_msr,
-+ peci_cmd_wr_ia_msr,
-+ peci_cmd_rd_pci_cfg,
-+ peci_cmd_wr_pci_cfg,
-+ peci_cmd_rd_pci_cfg_local,
-+ peci_cmd_wr_pci_cfg_local,
- };
-
- /**
-@@ -545,109 +760,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)
- {
-- int rc = 0;
-+ int ret;
-
- if (cmd >= PECI_CMD_MAX || cmd < PECI_CMD_XFER)
-- return -EINVAL;
-+ return -ENOTTY;
-
- dev_dbg(&adapter->dev, "%s, cmd=0x%02x\n", __func__, cmd);
-
-- if (!peci_ioctl_fn[cmd])
-+ if (!peci_cmd_fn[cmd])
- return -EINVAL;
-
-- rt_mutex_lock(&adapter->bus_lock);
-+ mutex_lock(&adapter->bus_lock);
-
-- rc = peci_cmd_support(adapter, cmd);
-- if (!rc)
-- rc = peci_ioctl_fn[cmd](adapter, vmsg);
-+ ret = peci_check_cmd_support(adapter, cmd);
-+ if (!ret)
-+ ret = peci_cmd_fn[cmd](adapter, vmsg);
-
-- rt_mutex_unlock(&adapter->bus_lock);
-+ mutex_unlock(&adapter->bus_lock);
-
-- return rc;
-+ return ret;
- }
- EXPORT_SYMBOL_GPL(peci_command);
-
--static long peci_ioctl(struct file *file, unsigned int iocmd, unsigned long arg)
--{
-- struct peci_adapter *adapter = file->private_data;
-- void __user *argp = (void __user *)arg;
-- unsigned int msg_len;
-- enum peci_cmd cmd;
-- int rc = 0;
-- u8 *msg;
--
-- if (!capable(CAP_SYS_ADMIN))
-- return -EPERM;
--
-- dev_dbg(&adapter->dev, "ioctl, cmd=0x%x, arg=0x%lx\n", iocmd, arg);
--
-- switch (iocmd) {
-- case PECI_IOC_XFER:
-- case PECI_IOC_PING:
-- case PECI_IOC_GET_DIB:
-- case PECI_IOC_GET_TEMP:
-- case PECI_IOC_RD_PKG_CFG:
-- case PECI_IOC_WR_PKG_CFG:
-- case PECI_IOC_RD_IA_MSR:
-- case PECI_IOC_RD_PCI_CFG:
-- case PECI_IOC_RD_PCI_CFG_LOCAL:
-- case PECI_IOC_WR_PCI_CFG_LOCAL:
-- cmd = _IOC_NR(iocmd);
-- msg_len = _IOC_SIZE(iocmd);
-- break;
--
-- default:
-- dev_dbg(&adapter->dev, "Invalid ioctl cmd : 0x%x\n", iocmd);
-- return -ENOTTY;
-- }
--
-- if (!access_ok(argp, msg_len))
-- return -EFAULT;
--
-- msg = memdup_user(argp, msg_len);
-- if (IS_ERR(msg))
-- return PTR_ERR(msg);
--
-- rc = peci_command(adapter, cmd, msg);
--
-- if (!rc && copy_to_user(argp, msg, msg_len))
-- rc = -EFAULT;
--
-- kfree(msg);
-- return (long)rc;
--}
--
--static int peci_open(struct inode *inode, struct file *file)
--{
-- unsigned int minor = iminor(inode);
-- struct peci_adapter *adapter;
--
-- adapter = peci_get_adapter(minor);
-- if (!adapter)
-- return -ENODEV;
--
-- file->private_data = adapter;
--
-- return 0;
--}
--
--static int peci_release(struct inode *inode, struct file *file)
--{
-- struct peci_adapter *adapter = file->private_data;
--
-- peci_put_adapter(adapter);
-- file->private_data = NULL;
--
-- return 0;
--}
--
--static const struct file_operations peci_fops = {
-- .owner = THIS_MODULE,
-- .unlocked_ioctl = peci_ioctl,
-- .open = peci_open,
-- .release = peci_release,
--};
--
- static int peci_detect(struct peci_adapter *adapter, u8 addr)
- {
- struct peci_ping_msg msg;
-@@ -666,9 +800,9 @@ peci_of_match_device(const struct of_device_id *matches,
- return NULL;
-
- return of_match_device(matches, &client->dev);
--#else
-+#else /* CONFIG_OF */
- return NULL;
--#endif
-+#endif /* CONFIG_OF */
- }
-
- static const struct peci_device_id *
-@@ -737,6 +871,7 @@ static int peci_device_probe(struct device *dev)
-
- err_detach_pm_domain:
- dev_pm_domain_detach(&client->dev, true);
-+
- return status;
- }
-
-@@ -775,13 +910,14 @@ static void peci_device_shutdown(struct device *dev)
- driver->shutdown(client);
- }
-
--static struct bus_type peci_bus_type = {
-+struct bus_type peci_bus_type = {
- .name = "peci",
- .match = peci_device_match,
- .probe = peci_device_probe,
- .remove = peci_device_remove,
- .shutdown = peci_device_shutdown,
- };
-+EXPORT_SYMBOL_GPL(peci_bus_type);
-
- static int peci_check_addr_validity(u8 addr)
- {
-@@ -814,18 +950,22 @@ 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;
-- int rc;
-+ int ret;
-
- msg.addr = addr;
-- msg.index = MBX_INDEX_CPU_ID;
-- msg.param = PKG_ID_CPU_ID;
-+ msg.index = PECI_MBX_INDEX_CPU_ID;
-+ msg.param = PECI_PKG_ID_CPU_ID;
- msg.rx_len = 4;
-
-- 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 (msg.cc != PECI_DEV_CC_SUCCESS)
-+ ret = -EAGAIN;
-+ if (ret)
-+ return ret;
-+
-+ *cpu_id = le32_to_cpup((__le32 *)msg.pkg_config);
-
-- return rc;
-+ return 0;
- }
- EXPORT_SYMBOL_GPL(peci_get_cpu_id);
-
-@@ -833,7 +973,7 @@ static struct peci_client *peci_new_device(struct peci_adapter *adapter,
- struct peci_board_info const *info)
- {
- struct peci_client *client;
-- int rc;
-+ int ret;
-
- /* Increase reference count for the adapter assigned */
- if (!peci_get_adapter(adapter->nr))
-@@ -847,46 +987,49 @@ static struct peci_client *peci_new_device(struct peci_adapter *adapter,
- client->addr = info->addr;
- strlcpy(client->name, info->type, sizeof(client->name));
-
-- rc = peci_check_addr_validity(client->addr);
-- if (rc) {
-+ ret = peci_check_addr_validity(client->addr);
-+ if (ret) {
- dev_err(&adapter->dev, "Invalid PECI CPU address 0x%02hx\n",
- client->addr);
- goto err_free_client_silent;
- }
-
- /* Check online status of client */
-- rc = peci_detect(adapter, client->addr);
-- if (rc)
-+ ret = peci_detect(adapter, client->addr);
-+ if (ret)
- goto err_free_client;
-
-- rc = device_for_each_child(&adapter->dev, client,
-- peci_check_client_busy);
-- if (rc)
-+ ret = device_for_each_child(&adapter->dev, client,
-+ peci_check_client_busy);
-+ if (ret)
- goto err_free_client;
-
- client->dev.parent = &client->adapter->dev;
- client->dev.bus = &peci_bus_type;
- client->dev.type = &peci_client_type;
-- client->dev.of_node = info->of_node;
-+ client->dev.of_node = of_node_get(info->of_node);
- dev_set_name(&client->dev, "%d-%02x", adapter->nr, client->addr);
-
-- rc = device_register(&client->dev);
-- if (rc)
-- goto err_free_client;
-+ ret = device_register(&client->dev);
-+ if (ret)
-+ goto err_put_of_node;
-
- dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n",
- client->name, dev_name(&client->dev));
-
- return client;
-
-+err_put_of_node:
-+ of_node_put(info->of_node);
- err_free_client:
- dev_err(&adapter->dev,
- "Failed to register peci client %s at 0x%02x (%d)\n",
-- client->name, client->addr, rc);
-+ client->name, client->addr, ret);
- err_free_client_silent:
- kfree(client);
- err_put_adapter:
- peci_put_adapter(adapter);
-+
- return NULL;
- }
-
-@@ -895,8 +1038,10 @@ static void peci_unregister_device(struct peci_client *client)
- if (!client)
- return;
-
-- if (client->dev.of_node)
-+ if (client->dev.of_node) {
- of_node_clear_flag(client->dev.of_node, OF_POPULATED);
-+ of_node_put(client->dev.of_node);
-+ }
-
- device_unregister(&client->dev);
- }
-@@ -916,7 +1061,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);
-- rt_mutex_destroy(&adapter->bus_lock);
-+ mutex_destroy(&adapter->bus_lock);
- kfree(adapter);
- }
-
-@@ -928,7 +1073,8 @@ static ssize_t peci_sysfs_new_device(struct device *dev,
- struct peci_board_info info = {};
- struct peci_client *client;
- char *blank, end;
-- int rc;
-+ short addr;
-+ int ret;
-
- /* Parse device type */
- blank = strchr(buf, ' ');
-@@ -943,16 +1089,17 @@ static ssize_t peci_sysfs_new_device(struct device *dev,
- memcpy(info.type, buf, blank - buf);
-
- /* Parse remaining parameters, reject extra parameters */
-- rc = sscanf(++blank, "%hi%c", &info.addr, &end);
-- if (rc < 1) {
-+ ret = sscanf(++blank, "%hi%c", &addr, &end);
-+ if (ret < 1) {
- dev_err(dev, "%s: Can't parse client address\n", "new_device");
- return -EINVAL;
- }
-- if (rc > 1 && end != '\n') {
-+ if (ret > 1 && end != '\n') {
- dev_err(dev, "%s: Extra parameters\n", "new_device");
- return -EINVAL;
- }
-
-+ info.addr = (u8)addr;
- client = peci_new_device(adapter, &info);
- if (!client)
- return -EINVAL;
-@@ -961,8 +1108,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);
-- dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device",
-- info.type, info.addr);
-+ dev_dbg(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device",
-+ info.type, info.addr);
-
- return count;
- }
-@@ -975,9 +1122,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 = {};
-- struct peci_driver *driver;
- char *blank, end;
-- int rc;
-+ short addr;
-+ int ret;
-
- /* Parse device type */
- blank = strchr(buf, ' ');
-@@ -992,41 +1139,41 @@ static ssize_t peci_sysfs_delete_device(struct device *dev,
- memcpy(info.type, buf, blank - buf);
-
- /* Parse remaining parameters, reject extra parameters */
-- rc = sscanf(++blank, "%hi%c", &info.addr, &end);
-- if (rc < 1) {
-+ ret = sscanf(++blank, "%hi%c", &addr, &end);
-+ if (ret < 1) {
- dev_err(dev, "%s: Can't parse client address\n",
- "delete_device");
- return -EINVAL;
- }
-- if (rc > 1 && end != '\n') {
-+ if (ret > 1 && end != '\n') {
- dev_err(dev, "%s: Extra parameters\n", "delete_device");
- return -EINVAL;
- }
-
-+ info.addr = (u8)addr;
-+
- /* Make sure the device was added through sysfs */
-- rc = -ENOENT;
-+ ret = -ENOENT;
- mutex_lock(&adapter->userspace_clients_lock);
- list_for_each_entry_safe(client, next, &adapter->userspace_clients,
- detected) {
-- driver = to_peci_driver(client->dev.driver);
--
- if (client->addr == info.addr &&
- !strncmp(client->name, info.type, PECI_NAME_SIZE)) {
-- dev_info(dev, "%s: Deleting device %s at 0x%02hx\n",
-- "delete_device", client->name, client->addr);
-+ dev_dbg(dev, "%s: Deleting device %s at 0x%02hx\n",
-+ "delete_device", client->name, client->addr);
- list_del(&client->detected);
- peci_unregister_device(client);
-- rc = count;
-+ ret = count;
- break;
- }
- }
- mutex_unlock(&adapter->userspace_clients_lock);
-
-- if (rc < 0)
-- dev_err(dev, "%s: Can't find device in list\n",
-+ if (ret < 0)
-+ dev_dbg(dev, "%s: Can't find device in list\n",
- "delete_device");
-
-- return rc;
-+ return ret;
- }
- static DEVICE_ATTR_IGNORE_LOCKDEP(delete_device, 0200, NULL,
- peci_sysfs_delete_device);
-@@ -1039,10 +1186,11 @@ static struct attribute *peci_adapter_attrs[] = {
- };
- ATTRIBUTE_GROUPS(peci_adapter);
-
--static struct device_type peci_adapter_type = {
-+struct device_type peci_adapter_type = {
- .groups = peci_adapter_groups,
- .release = peci_adapter_dev_release,
- };
-+EXPORT_SYMBOL_GPL(peci_adapter_type);
-
- /**
- * peci_verify_adapter - return parameter as peci_adapter, or NULL
-@@ -1063,32 +1211,26 @@ static struct peci_client *peci_of_register_device(struct peci_adapter *adapter,
- struct device_node *node)
- {
- struct peci_board_info info = {};
-- struct peci_client *result;
-- const __be32 *addr_be;
-- int len;
-+ struct peci_client *client;
-+ u32 addr;
-+ int ret;
-
- dev_dbg(&adapter->dev, "register %pOF\n", node);
-
-- if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
-- dev_err(&adapter->dev, "modalias failure on %pOF\n", node);
-- return ERR_PTR(-EINVAL);
-- }
--
-- addr_be = of_get_property(node, "reg", &len);
-- if (!addr_be || len < sizeof(*addr_be)) {
-+ ret = of_property_read_u32(node, "reg", &addr);
-+ if (ret) {
- dev_err(&adapter->dev, "invalid reg on %pOF\n", node);
-- return ERR_PTR(-EINVAL);
-+ return ERR_PTR(ret);
- }
-
-- info.addr = be32_to_cpup(addr_be);
-- info.of_node = of_node_get(node);
-+ info.addr = addr;
-+ info.of_node = node;
-
-- result = peci_new_device(adapter, &info);
-- if (!result)
-- result = ERR_PTR(-EINVAL);
-+ client = peci_new_device(adapter, &info);
-+ if (!client)
-+ client = ERR_PTR(-EINVAL);
-
-- of_node_put(node);
-- return result;
-+ return client;
- }
-
- static void peci_of_register_devices(struct peci_adapter *adapter)
-@@ -1119,7 +1261,7 @@ static void peci_of_register_devices(struct peci_adapter *adapter)
-
- of_node_put(bus);
- }
--#else
-+#else /* CONFIG_OF */
- static void peci_of_register_devices(struct peci_adapter *adapter) { }
- #endif /* CONFIG_OF */
-
-@@ -1163,9 +1305,7 @@ static struct peci_adapter *peci_of_find_adapter(struct device_node *node)
- return adapter;
- }
-
--static int peci_of_notify(struct notifier_block *nb,
-- unsigned long action,
-- void *arg)
-+static int peci_of_notify(struct notifier_block *nb, ulong action, void *arg)
- {
- struct of_reconfig_data *rd = arg;
- struct peci_adapter *adapter;
-@@ -1216,7 +1356,7 @@ static int peci_of_notify(struct notifier_block *nb,
- static struct notifier_block peci_of_notifier = {
- .notifier_call = peci_of_notify,
- };
--#else
-+#else /* CONFIG_OF_DYNAMIC */
- extern struct notifier_block peci_of_notifier;
- #endif /* CONFIG_OF_DYNAMIC */
-
-@@ -1240,7 +1380,7 @@ extern struct notifier_block peci_of_notifier;
- *
- * Return: the peci_adapter structure on success, else NULL.
- */
--struct peci_adapter *peci_alloc_adapter(struct device *dev, unsigned int size)
-+struct peci_adapter *peci_alloc_adapter(struct device *dev, uint size)
- {
- struct peci_adapter *adapter;
-
-@@ -1263,7 +1403,7 @@ EXPORT_SYMBOL_GPL(peci_alloc_adapter);
-
- static int peci_register_adapter(struct peci_adapter *adapter)
- {
-- int rc = -EINVAL;
-+ int ret = -EINVAL;
-
- /* Can't register until after driver model init */
- if (WARN_ON(!is_registered))
-@@ -1275,27 +1415,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;
-
-- rt_mutex_init(&adapter->bus_lock);
-+ mutex_init(&adapter->bus_lock);
- mutex_init(&adapter->userspace_clients_lock);
- INIT_LIST_HEAD(&adapter->userspace_clients);
-
- dev_set_name(&adapter->dev, "peci-%d", adapter->nr);
-
-- /* cdev */
-- cdev_init(&adapter->cdev, &peci_fops);
-- adapter->cdev.owner = THIS_MODULE;
-- adapter->dev.devt = MKDEV(MAJOR(peci_devt), adapter->nr);
-- rc = cdev_add(&adapter->cdev, adapter->dev.devt, 1);
-- if (rc) {
-- pr_err("adapter '%s': can't add cdev (%d)\n",
-- adapter->name, rc);
-- goto err_free_idr;
-- }
-- rc = device_add(&adapter->dev);
-- if (rc) {
-+ ret = device_add(&adapter->dev);
-+ if (ret) {
- pr_err("adapter '%s': can't add device (%d)\n",
-- adapter->name, rc);
-- goto err_del_cdev;
-+ adapter->name, ret);
-+ goto err_free_idr;
- }
-
- dev_dbg(&adapter->dev, "adapter [%s] registered\n", adapter->name);
-@@ -1309,13 +1439,11 @@ static int peci_register_adapter(struct peci_adapter *adapter)
-
- return 0;
-
--err_del_cdev:
-- cdev_del(&adapter->cdev);
- err_free_idr:
- mutex_lock(&core_lock);
- idr_remove(&peci_adapter_idr, adapter->nr);
- mutex_unlock(&core_lock);
-- return rc;
-+ return ret;
- }
-
- static int peci_add_numbered_adapter(struct peci_adapter *adapter)
-@@ -1354,12 +1482,10 @@ int peci_add_adapter(struct peci_adapter *adapter)
- struct device *dev = &adapter->dev;
- int id;
-
-- if (dev->of_node) {
-- id = of_alias_get_id(dev->of_node, "peci");
-- if (id >= 0) {
-- adapter->nr = id;
-- return peci_add_numbered_adapter(adapter);
-- }
-+ id = of_alias_get_id(dev->of_node, "peci");
-+ if (id >= 0) {
-+ adapter->nr = id;
-+ return peci_add_numbered_adapter(adapter);
- }
-
- mutex_lock(&core_lock);
-@@ -1411,7 +1537,7 @@ void peci_del_adapter(struct peci_adapter *adapter)
- }
- mutex_unlock(&adapter->userspace_clients_lock);
-
-- /**
-+ /*
- * Detach any active clients. This can't fail, thus we do not
- * check the returned value.
- */
-@@ -1420,13 +1546,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);
-
-- /* free cdev */
-- cdev_del(&adapter->cdev);
--
- pm_runtime_disable(&adapter->dev);
--
- nr = adapter->nr;
--
- device_unregister(&adapter->dev);
-
- /* free bus id */
-@@ -1436,6 +1557,18 @@ void peci_del_adapter(struct peci_adapter *adapter)
- }
- EXPORT_SYMBOL_GPL(peci_del_adapter);
-
-+int peci_for_each_dev(void *data, int (*fn)(struct device *, void *))
-+{
-+ int ret;
-+
-+ mutex_lock(&core_lock);
-+ ret = bus_for_each_dev(&peci_bus_type, NULL, data, fn);
-+ mutex_unlock(&core_lock);
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(peci_for_each_dev);
-+
- /**
- * peci_register_driver - register a PECI driver
- * @owner: owner module of the driver being registered
-@@ -1446,7 +1579,7 @@ EXPORT_SYMBOL_GPL(peci_del_adapter);
- */
- int peci_register_driver(struct module *owner, struct peci_driver *driver)
- {
-- int rc;
-+ int ret;
-
- /* Can't register until after driver model init */
- if (WARN_ON(!is_registered))
-@@ -1456,13 +1589,13 @@ int peci_register_driver(struct module *owner, struct peci_driver *driver)
- driver->driver.owner = owner;
- driver->driver.bus = &peci_bus_type;
-
-- /**
-+ /*
- * When registration returns, the driver core
- * will have called probe() for all matching-but-unbound devices.
- */
-- rc = driver_register(&driver->driver);
-- if (rc)
-- return rc;
-+ ret = driver_register(&driver->driver);
-+ if (ret)
-+ return ret;
-
- pr_debug("driver [%s] registered\n", driver->driver.name);
-
-@@ -1492,13 +1625,6 @@ static int __init peci_init(void)
- return ret;
- }
-
-- ret = alloc_chrdev_region(&peci_devt, 0, PECI_CDEV_MAX, "peci");
-- if (ret < 0) {
-- pr_err("peci: Failed to allocate chr dev region!\n");
-- bus_unregister(&peci_bus_type);
-- return ret;
-- }
--
- crc8_populate_msb(peci_crc8_table, PECI_CRC8_POLYNOMIAL);
-
- if (IS_ENABLED(CONFIG_OF_DYNAMIC))
-@@ -1514,11 +1640,10 @@ static void __exit peci_exit(void)
- if (IS_ENABLED(CONFIG_OF_DYNAMIC))
- WARN_ON(of_reconfig_notifier_unregister(&peci_of_notifier));
-
-- unregister_chrdev_region(peci_devt, PECI_CDEV_MAX);
- bus_unregister(&peci_bus_type);
- }
-
--postcore_initcall(peci_init);
-+subsys_initcall(peci_init);
- module_exit(peci_exit);
-
- 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 0000000..ac9cba0
---- /dev/null
-+++ b/drivers/peci/peci-dev.c
-@@ -0,0 +1,346 @@
-+// SPDX-License-Identifier: GPL-2.0
-+// Copyright (c) 2018-2019 Intel Corporation
-+
-+#include <linux/cdev.h>
-+#include <linux/fs.h>
-+#include <linux/list.h>
-+#include <linux/module.h>
-+#include <linux/notifier.h>
-+#include <linux/peci.h>
-+#include <linux/slab.h>
-+#include <linux/uaccess.h>
-+
-+/*
-+ * A peci_dev represents an peci_adapter ... an PECI or SMBus master, not a
-+ * slave (peci_client) with which messages will be exchanged. It's coupled
-+ * with a character special file which is accessed by user mode drivers.
-+ *
-+ * The list of peci_dev structures is parallel to the peci_adapter lists
-+ * maintained by the driver model, and is updated using bus notifications.
-+ */
-+struct peci_dev {
-+ struct list_head list;
-+ struct peci_adapter *adapter;
-+ struct device *dev;
-+ struct cdev cdev;
-+};
-+
-+#define PECI_MINORS MINORMASK
-+
-+static dev_t peci_devt;
-+static LIST_HEAD(peci_dev_list);
-+static DEFINE_SPINLOCK(peci_dev_list_lock);
-+
-+static struct peci_dev *peci_dev_get_by_minor(uint index)
-+{
-+ struct peci_dev *peci_dev;
-+
-+ spin_lock(&peci_dev_list_lock);
-+ list_for_each_entry(peci_dev, &peci_dev_list, list) {
-+ if (peci_dev->adapter->nr == index)
-+ goto found;
-+ }
-+ peci_dev = NULL;
-+found:
-+ spin_unlock(&peci_dev_list_lock);
-+
-+ return peci_dev;
-+}
-+
-+static struct peci_dev *peci_dev_alloc(struct peci_adapter *adapter)
-+{
-+ struct peci_dev *peci_dev;
-+
-+ if (adapter->nr >= PECI_MINORS) {
-+ printk(KERN_ERR "peci-dev: Out of device minors (%d)\n",
-+ adapter->nr);
-+ return ERR_PTR(-ENODEV);
-+ }
-+
-+ peci_dev = kzalloc(sizeof(*peci_dev), GFP_KERNEL);
-+ if (!peci_dev)
-+ return ERR_PTR(-ENOMEM);
-+ peci_dev->adapter = adapter;
-+
-+ spin_lock(&peci_dev_list_lock);
-+ list_add_tail(&peci_dev->list, &peci_dev_list);
-+ spin_unlock(&peci_dev_list_lock);
-+
-+ return peci_dev;
-+}
-+
-+static void peci_dev_put(struct peci_dev *peci_dev)
-+{
-+ spin_lock(&peci_dev_list_lock);
-+ list_del(&peci_dev->list);
-+ spin_unlock(&peci_dev_list_lock);
-+ kfree(peci_dev);
-+}
-+
-+static ssize_t name_show(struct device *dev,
-+ struct device_attribute *attr, char *buf)
-+{
-+ struct peci_dev *peci_dev = peci_dev_get_by_minor(MINOR(dev->devt));
-+
-+ if (!peci_dev)
-+ return -ENODEV;
-+
-+ return sprintf(buf, "%s\n", peci_dev->adapter->name);
-+}
-+static DEVICE_ATTR_RO(name);
-+
-+static struct attribute *peci_dev_attrs[] = {
-+ &dev_attr_name.attr,
-+ NULL,
-+};
-+ATTRIBUTE_GROUPS(peci_dev);
-+
-+static long peci_dev_ioctl(struct file *file, uint iocmd, ulong arg)
-+{
-+ struct peci_dev *peci_dev = file->private_data;
-+ void __user *umsg = (void __user *)arg;
-+ struct peci_xfer_msg *xmsg = NULL;
-+ struct peci_xfer_msg uxmsg;
-+ enum peci_cmd cmd;
-+ u8 *msg = NULL;
-+ uint msg_len;
-+ int ret;
-+
-+ cmd = _IOC_NR(iocmd);
-+ msg_len = _IOC_SIZE(iocmd);
-+
-+ switch (cmd) {
-+ case PECI_CMD_XFER:
-+ if (msg_len != sizeof(struct peci_xfer_msg)) {
-+ ret = -EFAULT;
-+ break;
-+ }
-+
-+ 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(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 && xmsg->rx_len &&
-+ copy_to_user(uxmsg.rx_buf, xmsg->rx_buf, xmsg->rx_len))
-+ ret = -EFAULT;
-+
-+ break;
-+
-+ default:
-+ msg = memdup_user(umsg, msg_len);
-+ if (IS_ERR(msg)) {
-+ ret = PTR_ERR(msg);
-+ break;
-+ }
-+
-+ ret = peci_command(peci_dev->adapter, cmd, msg);
-+ if ((!ret || ret == -ETIMEDOUT) &&
-+ copy_to_user(umsg, msg, msg_len))
-+ ret = -EFAULT;
-+
-+ break;
-+ }
-+
-+ peci_put_xfer_msg(xmsg);
-+ kfree(msg);
-+
-+ return (long)ret;
-+}
-+
-+static int peci_dev_open(struct inode *inode, struct file *file)
-+{
-+ struct peci_adapter *adapter;
-+ struct peci_dev *peci_dev;
-+
-+ peci_dev = peci_dev_get_by_minor(iminor(inode));
-+ if (!peci_dev)
-+ return -ENODEV;
-+
-+ adapter = peci_get_adapter(peci_dev->adapter->nr);
-+ if (!adapter)
-+ return -ENODEV;
-+
-+ file->private_data = peci_dev;
-+
-+ return 0;
-+}
-+
-+static int peci_dev_release(struct inode *inode, struct file *file)
-+{
-+ struct peci_dev *peci_dev = file->private_data;
-+
-+ peci_put_adapter(peci_dev->adapter);
-+ file->private_data = NULL;
-+
-+ return 0;
-+}
-+
-+static const struct file_operations peci_dev_fops = {
-+ .owner = THIS_MODULE,
-+ .unlocked_ioctl = peci_dev_ioctl,
-+ .open = peci_dev_open,
-+ .release = peci_dev_release,
-+ .llseek = no_llseek,
-+};
-+
-+static struct class *peci_dev_class;
-+
-+static int peci_dev_attach_adapter(struct device *dev, void *dummy)
-+{
-+ struct peci_adapter *adapter;
-+ struct peci_dev *peci_dev;
-+ dev_t devt;
-+ int ret;
-+
-+ if (dev->type != &peci_adapter_type)
-+ return 0;
-+
-+ adapter = to_peci_adapter(dev);
-+ peci_dev = peci_dev_alloc(adapter);
-+ if (IS_ERR(peci_dev))
-+ return PTR_ERR(peci_dev);
-+
-+ cdev_init(&peci_dev->cdev, &peci_dev_fops);
-+ peci_dev->cdev.owner = THIS_MODULE;
-+ devt = MKDEV(MAJOR(peci_devt), adapter->nr);
-+
-+ ret = cdev_add(&peci_dev->cdev, devt, 1);
-+ if (ret)
-+ goto err_put_dev;
-+
-+ /* register this peci device with the driver core */
-+ peci_dev->dev = device_create(peci_dev_class, &adapter->dev, devt, NULL,
-+ "peci-%d", adapter->nr);
-+ if (IS_ERR(peci_dev->dev)) {
-+ ret = PTR_ERR(peci_dev->dev);
-+ goto err_del_cdev;
-+ }
-+
-+ pr_info("peci-dev: adapter [%s] registered as minor %d\n",
-+ adapter->name, adapter->nr);
-+
-+ return 0;
-+
-+err_del_cdev:
-+ cdev_del(&peci_dev->cdev);
-+err_put_dev:
-+ peci_dev_put(peci_dev);
-+
-+ return ret;
-+}
-+
-+static int peci_dev_detach_adapter(struct device *dev, void *dummy)
-+{
-+ struct peci_adapter *adapter;
-+ struct peci_dev *peci_dev;
-+ dev_t devt;
-+
-+ if (dev->type != &peci_adapter_type)
-+ return 0;
-+
-+ adapter = to_peci_adapter(dev);
-+ peci_dev = peci_dev_get_by_minor(adapter->nr);
-+ if (!peci_dev)
-+ return 0;
-+
-+ cdev_del(&peci_dev->cdev);
-+ devt = peci_dev->dev->devt;
-+ peci_dev_put(peci_dev);
-+ device_destroy(peci_dev_class, devt);
-+
-+ pr_info("peci-dev: adapter [%s] unregistered\n", adapter->name);
-+
-+ return 0;
-+}
-+
-+static int peci_dev_notifier_call(struct notifier_block *nb, ulong action,
-+ void *data)
-+{
-+ struct device *dev = data;
-+
-+ switch (action) {
-+ case BUS_NOTIFY_ADD_DEVICE:
-+ return peci_dev_attach_adapter(dev, NULL);
-+ case BUS_NOTIFY_DEL_DEVICE:
-+ return peci_dev_detach_adapter(dev, NULL);
-+ }
-+
-+ return 0;
-+}
-+
-+static struct notifier_block peci_dev_notifier = {
-+ .notifier_call = peci_dev_notifier_call,
-+};
-+
-+static int __init peci_dev_init(void)
-+{
-+ int ret;
-+
-+ printk(KERN_INFO "peci /dev entries driver\n");
-+
-+ ret = alloc_chrdev_region(&peci_devt, 0, PECI_MINORS, "peci");
-+ if (ret < 0) {
-+ pr_err("peci: Failed to allocate chr dev region!\n");
-+ bus_unregister(&peci_bus_type);
-+ goto err;
-+ }
-+
-+ peci_dev_class = class_create(THIS_MODULE, "peci-dev");
-+ if (IS_ERR(peci_dev_class)) {
-+ ret = PTR_ERR(peci_dev_class);
-+ goto err_unreg_chrdev;
-+ }
-+ peci_dev_class->dev_groups = peci_dev_groups;
-+
-+ /* Keep track of adapters which will be added or removed later */
-+ ret = bus_register_notifier(&peci_bus_type, &peci_dev_notifier);
-+ if (ret)
-+ goto err_destroy_class;
-+
-+ /* Bind to already existing adapters right away */
-+ peci_for_each_dev(NULL, peci_dev_attach_adapter);
-+
-+ return 0;
-+
-+err_destroy_class:
-+ class_destroy(peci_dev_class);
-+err_unreg_chrdev:
-+ unregister_chrdev_region(peci_devt, PECI_MINORS);
-+err:
-+ printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);
-+
-+ return ret;
-+}
-+
-+static void __exit peci_dev_exit(void)
-+{
-+ bus_unregister_notifier(&peci_bus_type, &peci_dev_notifier);
-+ peci_for_each_dev(NULL, peci_dev_detach_adapter);
-+ class_destroy(peci_dev_class);
-+ unregister_chrdev_region(peci_devt, PECI_MINORS);
-+}
-+
-+module_init(peci_dev_init);
-+module_exit(peci_dev_exit);
-+
-+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 f632365..0000000
---- 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 8f6d823..9854303 100644
---- a/include/linux/mfd/intel-peci-client.h
-+++ b/include/linux/mfd/intel-peci-client.h
-@@ -1,5 +1,5 @@
- /* SPDX-License-Identifier: GPL-2.0 */
--/* Copyright (c) 2018 Intel Corporation */
-+/* Copyright (c) 2018-2019 Intel Corporation */
-
- #ifndef __LINUX_MFD_INTEL_PECI_CLIENT_H
- #define __LINUX_MFD_INTEL_PECI_CLIENT_H
-@@ -9,14 +9,15 @@
- #if IS_ENABLED(CONFIG_X86)
- #include <asm/intel-family.h>
- #else
--/**
-+/*
- * 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.
- */
--#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_SKYLAKE_X 0x55
-+#define INTEL_FAM6_SKYLAKE_XD 0x56
- #endif
-
- #define CORE_MAX_ON_HSX 18 /* Max number of cores on Haswell */
-@@ -31,6 +32,10 @@
- #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 */
-
-+#define CORE_MAX_ON_SKXD 16 /* Max number of cores on Skylake D */
-+#define CHAN_RANK_MAX_ON_SKXD 2 /* Max number of channel ranks on Skylake D */
-+#define DIMM_IDX_MAX_ON_SKXD 2 /* Max DIMM index per channel on Skylake D */
-+
- #define CORE_NUMS_MAX CORE_MAX_ON_SKX
- #define CHAN_RANK_MAX CHAN_RANK_MAX_ON_HSX
- #define DIMM_IDX_MAX DIMM_IDX_MAX_ON_HSX
-@@ -58,7 +63,6 @@ struct cpu_gen_info {
- /**
- * struct peci_client_manager - PECI client manager information
- * @client; pointer to the PECI client
-- * @dev: pointer to the struct device
- * @name: PECI client manager name
- * @gen_info: CPU generation info of the detected CPU
- *
-@@ -67,7 +71,6 @@ struct cpu_gen_info {
- */
- struct peci_client_manager {
- struct peci_client *client;
-- struct device *dev;
- char name[PECI_NAME_SIZE];
- const struct cpu_gen_info *gen_info;
- };
-@@ -93,18 +96,22 @@ 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 (msg.cc != PECI_DEV_CC_SUCCESS)
-+ ret = -EAGAIN;
-+ if (ret)
-+ return ret;
-+
-+ 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 d0e47d4..6fc424d 100644
---- a/include/linux/peci.h
-+++ b/include/linux/peci.h
-@@ -1,19 +1,18 @@
- /* SPDX-License-Identifier: GPL-2.0 */
--/* Copyright (c) 2018 Intel Corporation */
-+/* Copyright (c) 2018-2019 Intel Corporation */
-
- #ifndef __LINUX_PECI_H
- #define __LINUX_PECI_H
-
--#include <linux/cdev.h>
- #include <linux/device.h>
-+#include <linux/mutex.h>
- #include <linux/peci-ioctl.h>
--#include <linux/rtmutex.h>
-
- #define PECI_NAME_SIZE 32
-
- struct peci_board_info {
- char type[PECI_NAME_SIZE];
-- unsigned short addr; /* CPU client address */
-+ u8 addr; /* CPU client address */
- struct device_node *of_node;
- };
-
-@@ -22,29 +21,29 @@ struct peci_board_info {
- * @owner: owner module of the PECI adpater
- * @bus_lock: mutex for exclusion of multiple callers
- * @dev: device interface to this driver
-- * @cdev: character device object to create character device
- * @nr: the bus number to map
- * @name: name of the adapter
- * @userspace_clients_lock: mutex for exclusion of clients handling
- * @userspace_clients: list of registered clients
- * @xfer: low-level transfer function pointer of the adapter
- * @cmd_mask: mask for supportable PECI commands
-+ * @use_dma: flag for indicating that adapter uses DMA
- *
- * Each PECI adapter can communicate with one or more PECI client children.
- * These make a small bus, sharing a single wired PECI connection.
- */
- struct peci_adapter {
- struct module *owner;
-- struct rt_mutex bus_lock;
-+ struct mutex bus_lock;
- struct device dev;
-- struct cdev cdev;
- int nr;
- char name[PECI_NAME_SIZE];
- struct mutex userspace_clients_lock; /* clients list mutex */
- struct list_head userspace_clients;
- int (*xfer)(struct peci_adapter *adapter,
- struct peci_xfer_msg *msg);
-- uint cmd_mask;
-+ u32 cmd_mask;
-+ bool use_dma;
- };
-
- static inline struct peci_adapter *to_peci_adapter(void *d)
-@@ -87,8 +86,8 @@ static inline struct peci_client *to_peci_client(void *d)
- }
-
- struct peci_device_id {
-- char name[PECI_NAME_SIZE];
-- unsigned long driver_data; /* Data private to the driver */
-+ char name[PECI_NAME_SIZE];
-+ ulong driver_data; /* Data private to the driver */
- };
-
- /**
-@@ -129,13 +128,22 @@ static inline struct peci_driver *to_peci_driver(void *d)
- /* use a define to avoid include chaining to get THIS_MODULE */
- #define peci_add_driver(driver) peci_register_driver(THIS_MODULE, driver)
-
-+extern struct bus_type peci_bus_type;
-+extern struct device_type peci_adapter_type;
-+extern struct device_type peci_client_type;
-+
- int peci_register_driver(struct module *owner, struct peci_driver *drv);
- void peci_del_driver(struct peci_driver *driver);
- struct peci_client *peci_verify_client(struct device *dev);
--struct peci_adapter *peci_alloc_adapter(struct device *dev, unsigned int size);
-+struct peci_adapter *peci_alloc_adapter(struct device *dev, uint size);
-+struct peci_adapter *peci_get_adapter(int nr);
-+void peci_put_adapter(struct peci_adapter *adapter);
- int peci_add_adapter(struct peci_adapter *adapter);
- void peci_del_adapter(struct peci_adapter *adapter);
- struct peci_adapter *peci_verify_adapter(struct device *dev);
-+int peci_for_each_dev(void *data, int (*fn)(struct device *, void *));
-+struct peci_xfer_msg *peci_get_xfer_msg(u8 tx_len, u8 rx_len);
-+void peci_put_xfer_msg(struct peci_xfer_msg *msg);
- int peci_command(struct peci_adapter *adpater, enum peci_cmd cmd, void *vmsg);
- 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 a6dae71..253fb42 100644
---- a/include/uapi/linux/peci-ioctl.h
-+++ b/include/uapi/linux/peci-ioctl.h
-@@ -1,5 +1,5 @@
- /* SPDX-License-Identifier: GPL-2.0 */
--/* Copyright (c) 2018 Intel Corporation */
-+/* Copyright (c) 2018-2019 Intel Corporation */
-
- #ifndef __PECI_IOCTL_H
- #define __PECI_IOCTL_H
-@@ -7,136 +7,35 @@
- #include <linux/ioctl.h>
- #include <linux/types.h>
-
--/* Base Address of 48d */
--#define PECI_BASE_ADDR 0x30 /* The PECI client's default address of 0x30 */
--#define PECI_OFFSET_MAX 8 /* Max numver of CPU clients */
--
--/* PCI Access */
--#define MAX_PCI_READ_LEN 24 /* Number of bytes of the PCI Space read */
--
--#define PCI_BUS0_CPU0 0x00
--#define PCI_BUS0_CPU1 0x80
--#define PCI_CPUBUSNO_BUS 0x00
--#define PCI_CPUBUSNO_DEV 0x08
--#define PCI_CPUBUSNO_FUNC 0x02
--#define PCI_CPUBUSNO 0xcc
--#define PCI_CPUBUSNO_1 0xd0
--#define PCI_CPUBUSNO_VALID 0xd4
--
--/* Package Identifier Read Parameter Value */
--#define PKG_ID_CPU_ID 0x0000 /* CPUID Info */
--#define PKG_ID_PLATFORM_ID 0x0001 /* Platform ID */
--#define PKG_ID_UNCORE_ID 0x0002 /* Uncore Device ID */
--#define PKG_ID_MAX_THREAD_ID 0x0003 /* Max Thread ID */
--#define PKG_ID_MICROCODE_REV 0x0004 /* CPU Microcode Update Revision */
--#define PKG_ID_MACHINE_CHECK_STATUS 0x0005 /* Machine Check Status */
--
--/* RdPkgConfig Index */
--#define MBX_INDEX_CPU_ID 0 /* Package Identifier Read */
--#define MBX_INDEX_VR_DEBUG 1 /* VR Debug */
--#define MBX_INDEX_PKG_TEMP_READ 2 /* Package Temperature Read */
--#define MBX_INDEX_ENERGY_COUNTER 3 /* Energy counter */
--#define MBX_INDEX_ENERGY_STATUS 4 /* DDR Energy Status */
--#define MBX_INDEX_WAKE_MODE_BIT 5 /* "Wake on PECI" Mode bit */
--#define MBX_INDEX_EPI 6 /* Efficient Performance Indication */
--#define MBX_INDEX_PKG_RAPL_PERF 8 /* Pkg RAPL Performance Status Read */
--#define MBX_INDEX_PER_CORE_DTS_TEMP 9 /* Per Core DTS Temperature Read */
--#define MBX_INDEX_DTS_MARGIN 10 /* DTS thermal margin */
--#define MBX_INDEX_SKT_PWR_THRTL_DUR 11 /* Socket Power Throttled Duration */
--#define MBX_INDEX_CFG_TDP_CONTROL 12 /* TDP Config Control */
--#define MBX_INDEX_CFG_TDP_LEVELS 13 /* TDP Config Levels */
--#define MBX_INDEX_DDR_DIMM_TEMP 14 /* DDR DIMM Temperature */
--#define MBX_INDEX_CFG_ICCMAX 15 /* Configurable ICCMAX */
--#define MBX_INDEX_TEMP_TARGET 16 /* Temperature Target Read */
--#define MBX_INDEX_CURR_CFG_LIMIT 17 /* Current Config Limit */
--#define MBX_INDEX_DIMM_TEMP_READ 20 /* Package Thermal Status Read */
--#define MBX_INDEX_DRAM_IMC_TMP_READ 22 /* DRAM IMC Temperature Read */
--#define MBX_INDEX_DDR_CH_THERM_STAT 23 /* DDR Channel Thermal Status */
--#define MBX_INDEX_PKG_POWER_LIMIT1 26 /* Package Power Limit1 */
--#define MBX_INDEX_PKG_POWER_LIMIT2 27 /* Package Power Limit2 */
--#define MBX_INDEX_TDP 28 /* Thermal design power minimum */
--#define MBX_INDEX_TDP_HIGH 29 /* Thermal design power maximum */
--#define MBX_INDEX_TDP_UNITS 30 /* Units for power/energy registers */
--#define MBX_INDEX_RUN_TIME 31 /* Accumulated Run Time */
--#define MBX_INDEX_CONSTRAINED_TIME 32 /* Thermally Constrained Time Read */
--#define MBX_INDEX_TURBO_RATIO 33 /* Turbo Activation Ratio */
--#define MBX_INDEX_DDR_RAPL_PL1 34 /* DDR RAPL PL1 */
--#define MBX_INDEX_DDR_PWR_INFO_HIGH 35 /* DRAM Power Info Read (high) */
--#define MBX_INDEX_DDR_PWR_INFO_LOW 36 /* DRAM Power Info Read (low) */
--#define MBX_INDEX_DDR_RAPL_PL2 37 /* DDR RAPL PL2 */
--#define MBX_INDEX_DDR_RAPL_STATUS 38 /* DDR RAPL Performance Status */
--#define MBX_INDEX_DDR_HOT_ABSOLUTE 43 /* DDR Hottest Dimm Absolute Temp */
--#define MBX_INDEX_DDR_HOT_RELATIVE 44 /* DDR Hottest Dimm Relative Temp */
--#define MBX_INDEX_DDR_THROTTLE_TIME 45 /* DDR Throttle Time */
--#define MBX_INDEX_DDR_THERM_STATUS 46 /* DDR Thermal Status */
--#define MBX_INDEX_TIME_AVG_TEMP 47 /* Package time-averaged temperature */
--#define MBX_INDEX_TURBO_RATIO_LIMIT 49 /* Turbo Ratio Limit Read */
--#define MBX_INDEX_HWP_AUTO_OOB 53 /* HWP Autonomous Out-of-band */
--#define MBX_INDEX_DDR_WARM_BUDGET 55 /* DDR Warm Power Budget */
--#define MBX_INDEX_DDR_HOT_BUDGET 56 /* DDR Hot Power Budget */
--#define MBX_INDEX_PKG_PSYS_PWR_LIM3 57 /* Package/Psys Power Limit3 */
--#define MBX_INDEX_PKG_PSYS_PWR_LIM1 58 /* Package/Psys Power Limit1 */
--#define MBX_INDEX_PKG_PSYS_PWR_LIM2 59 /* Package/Psys Power Limit2 */
--#define MBX_INDEX_PKG_PSYS_PWR_LIM4 60 /* Package/Psys Power Limit4 */
--#define MBX_INDEX_PERF_LIMIT_REASON 65 /* Performance Limit Reasons */
--
--/* WrPkgConfig Index */
--#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
-+
-+/* Max number of CPU clients */
-+#define PECI_OFFSET_MAX 8
-+
-+/* PECI read/write data buffer size max */
-+#define PECI_BUFFER_SIZE 255
-
- /* Device Specific Completion Code (CC) Definition */
--#define DEV_PECI_CC_SUCCESS 0x40
--#define DEV_PECI_CC_TIMEOUT 0x80
--#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_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
-
- /* Skylake EDS says to retry for 250ms */
--#define DEV_PECI_RETRY_TIME_MS 250
--#define DEV_PECI_RETRY_INTERVAL_USEC 10000
--#define DEV_PECI_RETRY_BIT 0x01
--
--#define GET_TEMP_WR_LEN 1
--#define GET_TEMP_RD_LEN 2
--#define GET_TEMP_PECI_CMD 0x01
--
--#define GET_DIB_WR_LEN 1
--#define GET_DIB_RD_LEN 8
--#define GET_DIB_PECI_CMD 0xf7
--
--#define RDPKGCFG_WRITE_LEN 5
--#define RDPKGCFG_READ_LEN_BASE 1
--#define RDPKGCFG_PECI_CMD 0xa1
--
--#define WRPKGCFG_WRITE_LEN_BASE 6
--#define WRPKGCFG_READ_LEN 1
--#define WRPKGCFG_PECI_CMD 0xa5
--
--#define RDIAMSR_WRITE_LEN 5
--#define RDIAMSR_READ_LEN 9
--#define RDIAMSR_PECI_CMD 0xb1
--
--#define WRIAMSR_PECI_CMD 0xb5
--
--#define RDPCICFG_WRITE_LEN 6
--#define RDPCICFG_READ_LEN 5
--#define RDPCICFG_PECI_CMD 0x61
--
--#define WRPCICFG_PECI_CMD 0x65
--
--#define RDPCICFGLOCAL_WRITE_LEN 5
--#define RDPCICFGLOCAL_READ_LEN_BASE 1
--#define RDPCICFGLOCAL_PECI_CMD 0xe1
--
--#define WRPCICFGLOCAL_WRITE_LEN_BASE 6
--#define WRPCICFGLOCAL_READ_LEN 1
--#define WRPCICFGLOCAL_PECI_CMD 0xe5
--
--#define PECI_BUFFER_SIZE 32
-+#define PECI_DEV_RETRY_TIME_MS 700
-+#define PECI_DEV_RETRY_INTERVAL_USEC 10000
-+#define PECI_DEV_RETRY_BIT 0x01
-
- /**
- * enum peci_cmd - PECI client commands
-@@ -186,11 +85,12 @@ enum peci_cmd {
- * raw PECI transfer
- */
- struct peci_xfer_msg {
-- __u8 addr;
-- __u8 tx_len;
-- __u8 rx_len;
-- __u8 tx_buf[PECI_BUFFER_SIZE];
-- __u8 rx_buf[PECI_BUFFER_SIZE];
-+ __u8 addr;
-+ __u8 tx_len;
-+ __u8 rx_len;
-+ __u8 padding;
-+ __u8 *tx_buf;
-+ __u8 *rx_buf;
- } __attribute__((__packed__));
-
- /**
-@@ -202,7 +102,8 @@ struct peci_xfer_msg {
- * powered-off, etc.
- */
- struct peci_ping_msg {
-- __u8 addr;
-+ __u8 addr;
-+ __u8 padding[3];
- } __attribute__((__packed__));
-
- /**
-@@ -216,8 +117,13 @@ struct peci_ping_msg {
- * command.
- */
- struct peci_get_dib_msg {
-- __u8 addr;
-- __u64 dib;
-+#define PECI_GET_DIB_WR_LEN 1
-+#define PECI_GET_DIB_RD_LEN 8
-+#define PECI_GET_DIB_CMD 0xf7
-+
-+ __u8 addr;
-+ __u8 padding[3];
-+ __u64 dib;
- } __attribute__((__packed__));
-
- /**
-@@ -232,8 +138,13 @@ struct peci_get_dib_msg {
- * below the maximum processor junction temperature.
- */
- struct peci_get_temp_msg {
-- __u8 addr;
-- __s16 temp_raw;
-+#define PECI_GET_TEMP_WR_LEN 1
-+#define PECI_GET_TEMP_RD_LEN 2
-+#define PECI_GET_TEMP_CMD 0x01
-+
-+ __u8 addr;
-+ __u8 padding;
-+ __s16 temp_raw;
- } __attribute__((__packed__));
-
- /**
-@@ -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 {
-- __u8 addr;
-- __u8 index;
-- __u16 param;
-- __u8 rx_len;
-- __u8 pkg_config[4];
-+#define PECI_RDPKGCFG_WRITE_LEN 5
-+#define PECI_RDPKGCFG_READ_LEN_BASE 1
-+#define PECI_RDPKGCFG_CMD 0xa1
-+
-+ __u8 addr;
-+ __u8 index;
-+#define PECI_MBX_INDEX_CPU_ID 0 /* Package Identifier Read */
-+#define PECI_MBX_INDEX_VR_DEBUG 1 /* VR Debug */
-+#define PECI_MBX_INDEX_PKG_TEMP_READ 2 /* Package Temperature Read */
-+#define PECI_MBX_INDEX_ENERGY_COUNTER 3 /* Energy counter */
-+#define PECI_MBX_INDEX_ENERGY_STATUS 4 /* DDR Energy Status */
-+#define PECI_MBX_INDEX_WAKE_MODE_BIT 5 /* "Wake on PECI" Mode bit */
-+#define PECI_MBX_INDEX_EPI 6 /* Efficient Performance Indication */
-+#define PECI_MBX_INDEX_PKG_RAPL_PERF 8 /* Pkg RAPL Performance Status Read */
-+#define PECI_MBX_INDEX_PER_CORE_DTS_TEMP 9 /* Per Core DTS Temperature Read */
-+#define PECI_MBX_INDEX_DTS_MARGIN 10 /* DTS thermal margin */
-+#define PECI_MBX_INDEX_SKT_PWR_THRTL_DUR 11 /* Socket Power Throttled Duration */
-+#define PECI_MBX_INDEX_CFG_TDP_CONTROL 12 /* TDP Config Control */
-+#define PECI_MBX_INDEX_CFG_TDP_LEVELS 13 /* TDP Config Levels */
-+#define PECI_MBX_INDEX_DDR_DIMM_TEMP 14 /* DDR DIMM Temperature */
-+#define PECI_MBX_INDEX_CFG_ICCMAX 15 /* Configurable ICCMAX */
-+#define PECI_MBX_INDEX_TEMP_TARGET 16 /* Temperature Target Read */
-+#define PECI_MBX_INDEX_CURR_CFG_LIMIT 17 /* Current Config Limit */
-+#define PECI_MBX_INDEX_DIMM_TEMP_READ 20 /* Package Thermal Status Read */
-+#define PECI_MBX_INDEX_DRAM_IMC_TMP_READ 22 /* DRAM IMC Temperature Read */
-+#define PECI_MBX_INDEX_DDR_CH_THERM_STAT 23 /* DDR Channel Thermal Status */
-+#define PECI_MBX_INDEX_PKG_POWER_LIMIT1 26 /* Package Power Limit1 */
-+#define PECI_MBX_INDEX_PKG_POWER_LIMIT2 27 /* Package Power Limit2 */
-+#define PECI_MBX_INDEX_TDP 28 /* Thermal design power minimum */
-+#define PECI_MBX_INDEX_TDP_HIGH 29 /* Thermal design power maximum */
-+#define PECI_MBX_INDEX_TDP_UNITS 30 /* Units for power/energy registers */
-+#define PECI_MBX_INDEX_RUN_TIME 31 /* Accumulated Run Time */
-+#define PECI_MBX_INDEX_CONSTRAINED_TIME 32 /* Thermally Constrained Time Read */
-+#define PECI_MBX_INDEX_TURBO_RATIO 33 /* Turbo Activation Ratio */
-+#define PECI_MBX_INDEX_DDR_RAPL_PL1 34 /* DDR RAPL PL1 */
-+#define PECI_MBX_INDEX_DDR_PWR_INFO_HIGH 35 /* DRAM Power Info Read (high) */
-+#define PECI_MBX_INDEX_DDR_PWR_INFO_LOW 36 /* DRAM Power Info Read (low) */
-+#define PECI_MBX_INDEX_DDR_RAPL_PL2 37 /* DDR RAPL PL2 */
-+#define PECI_MBX_INDEX_DDR_RAPL_STATUS 38 /* DDR RAPL Performance Status */
-+#define PECI_MBX_INDEX_DDR_HOT_ABSOLUTE 43 /* DDR Hottest Dimm Absolute Temp */
-+#define PECI_MBX_INDEX_DDR_HOT_RELATIVE 44 /* DDR Hottest Dimm Relative Temp */
-+#define PECI_MBX_INDEX_DDR_THROTTLE_TIME 45 /* DDR Throttle Time */
-+#define PECI_MBX_INDEX_DDR_THERM_STATUS 46 /* DDR Thermal Status */
-+#define PECI_MBX_INDEX_TIME_AVG_TEMP 47 /* Package time-averaged temperature */
-+#define PECI_MBX_INDEX_TURBO_RATIO_LIMIT 49 /* Turbo Ratio Limit Read */
-+#define PECI_MBX_INDEX_HWP_AUTO_OOB 53 /* HWP Autonomous Out-of-band */
-+#define PECI_MBX_INDEX_DDR_WARM_BUDGET 55 /* DDR Warm Power Budget */
-+#define PECI_MBX_INDEX_DDR_HOT_BUDGET 56 /* DDR Hot Power Budget */
-+#define PECI_MBX_INDEX_PKG_PSYS_PWR_LIM3 57 /* Package/Psys Power Limit3 */
-+#define PECI_MBX_INDEX_PKG_PSYS_PWR_LIM1 58 /* Package/Psys Power Limit1 */
-+#define PECI_MBX_INDEX_PKG_PSYS_PWR_LIM2 59 /* Package/Psys Power Limit2 */
-+#define PECI_MBX_INDEX_PKG_PSYS_PWR_LIM4 60 /* Package/Psys Power Limit4 */
-+#define PECI_MBX_INDEX_PERF_LIMIT_REASON 65 /* Performance Limit Reasons */
-+
-+ __u16 param;
-+/* When index is PECI_MBX_INDEX_CPU_ID */
-+#define PECI_PKG_ID_CPU_ID 0x0000 /* CPUID Info */
-+#define PECI_PKG_ID_PLATFORM_ID 0x0001 /* Platform ID */
-+#define PECI_PKG_ID_UNCORE_ID 0x0002 /* Uncore Device ID */
-+#define PECI_PKG_ID_MAX_THREAD_ID 0x0003 /* Max Thread ID */
-+#define PECI_PKG_ID_MICROCODE_REV 0x0004 /* CPU Microcode Update Revision */
-+#define PECI_PKG_ID_MACHINE_CHECK_STATUS 0x0005 /* Machine Check Status */
-+
-+ __u8 rx_len;
-+ __u8 cc;
-+ __u8 padding[2];
-+ __u8 pkg_config[4];
- } __attribute__((__packed__));
-
- /**
-@@ -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 {
-- __u8 addr;
-- __u8 index;
-- __u16 param;
-- __u8 tx_len;
-- __u32 value;
-+#define PECI_WRPKGCFG_WRITE_LEN_BASE 6
-+#define PECI_WRPKGCFG_READ_LEN 1
-+#define PECI_WRPKGCFG_CMD 0xa5
-+
-+ __u8 addr;
-+ __u8 index;
-+#define PECI_MBX_INDEX_DIMM_AMBIENT 19
-+#define PECI_MBX_INDEX_DIMM_TEMP 24
-+
-+ __u16 param;
-+ __u8 tx_len;
-+ __u8 cc;
-+ __u8 padding[2];
-+ __u32 value;
- } __attribute__((__packed__));
-
- /**
-@@ -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 {
-- __u8 addr;
-- __u8 thread_id;
-- __u16 address;
-- __u64 value;
-+#define PECI_RDIAMSR_WRITE_LEN 5
-+#define PECI_RDIAMSR_READ_LEN 9
-+#define PECI_RDIAMSR_CMD 0xb1
-+
-+ __u8 addr;
-+ __u8 thread_id;
-+ __u16 address;
-+ __u8 cc;
-+ __u8 padding[3];
-+ __u64 value;
-+} __attribute__((__packed__));
-+
-+/**
-+ * struct peci_wr_ia_msr_msg - WrIAMSR command
-+ * @addr: address of the client
-+ * @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 cc;
-+ __u8 padding[2];
-+ __u64 value;
- } __attribute__((__packed__));
-
- /**
-@@ -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 {
-- __u8 addr;
-- __u8 bus;
-- __u8 device;
-- __u8 function;
-- __u16 reg;
-- __u8 pci_config[4];
-+#define PECI_RDPCICFG_WRITE_LEN 6
-+#define PECI_RDPCICFG_READ_LEN 5
-+#define PECI_RDPCICFG_READ_LEN_MAX 24
-+#define PECI_RDPCICFG_CMD 0x61
-+
-+ __u8 addr;
-+ __u8 bus;
-+#define PECI_PCI_BUS0_CPU0 0x00
-+#define PECI_PCI_BUS0_CPU1 0x80
-+#define PECI_PCI_CPUBUSNO_BUS 0x00
-+#define PECI_PCI_CPUBUSNO_DEV 0x08
-+#define PECI_PCI_CPUBUSNO_FUNC 0x02
-+#define PECI_PCI_CPUBUSNO 0xcc
-+#define PECI_PCI_CPUBUSNO_1 0xd0
-+#define PECI_PCI_CPUBUSNO_VALID 0xd4
-+
-+ __u8 device;
-+ __u8 function;
-+ __u16 reg;
-+ __u8 cc;
-+ __u8 padding[1];
-+ __u8 pci_config[4];
-+} __attribute__((__packed__));
-+
-+/**
-+ * struct peci_wr_pci_cfg_msg - WrPCIConfig command
-+ * @addr: address of the client
-+ * @bus: PCI bus number
-+ * @device: PCI device number
-+ * @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
-+ * configuration space maintained in downstream devices external to the
-+ * 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 cc;
-+ __u8 pci_config[4];
- } __attribute__((__packed__));
-
- /**
-@@ -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 {
-- __u8 addr;
-- __u8 bus;
-- __u8 device;
-- __u8 function;
-- __u16 reg;
-- __u8 rx_len;
-- __u8 pci_config[4];
-+#define PECI_RDPCICFGLOCAL_WRITE_LEN 5
-+#define PECI_RDPCICFGLOCAL_READ_LEN_BASE 1
-+#define PECI_RDPCICFGLOCAL_CMD 0xe1
-+
-+ __u8 addr;
-+ __u8 bus;
-+ __u8 device;
-+ __u8 function;
-+ __u16 reg;
-+ __u8 rx_len;
-+ __u8 cc;
-+ __u8 pci_config[4];
- } __attribute__((__packed__));
-
- /**
-@@ -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 {
-- __u8 addr;
-- __u8 bus;
-- __u8 device;
-- __u8 function;
-- __u16 reg;
-- __u8 tx_len;
-- __u32 value;
-+#define PECI_WRPCICFGLOCAL_WRITE_LEN_BASE 6
-+#define PECI_WRPCICFGLOCAL_READ_LEN 1
-+#define PECI_WRPCICFGLOCAL_CMD 0xe5
-+
-+ __u8 addr;
-+ __u8 bus;
-+ __u8 device;
-+ __u8 function;
-+ __u16 reg;
-+ __u8 tx_len;
-+ __u8 cc;
-+ __u32 value;
- } __attribute__((__packed__));
-
- #define PECI_IOC_BASE 0xb7
-@@ -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)
-
-+#define PECI_IOC_WR_IA_MSR \
-+ _IOWR(PECI_IOC_BASE, PECI_CMD_WR_IA_MSR, struct peci_wr_ia_msr_msg)
-+
- #define PECI_IOC_RD_PCI_CFG \
- _IOWR(PECI_IOC_BASE, PECI_CMD_RD_PCI_CFG, struct peci_rd_pci_cfg_msg)
-
-+#define PECI_IOC_WR_PCI_CFG \
-+ _IOWR(PECI_IOC_BASE, PECI_CMD_WR_PCI_CFG, struct peci_wr_pci_cfg_msg)
-+
- #define PECI_IOC_RD_PCI_CFG_LOCAL \
- _IOWR(PECI_IOC_BASE, PECI_CMD_RD_PCI_CFG_LOCAL, \
- struct peci_rd_pci_cfg_local_msg)
---
-2.7.4
-