summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIwona Winiarska <iwona.winiarska@intel.com>2022-05-09 21:05:59 +0300
committerIwona Winiarska <iwona.winiarska@intel.com>2022-05-23 15:06:36 +0300
commitb0f89c7de8f3cac4952acc5f09539c0b879e58d9 (patch)
tree87bcb1dee4b10adebe8836bfc27296e291c3472b
parent5a478efbb1201546d179b51c2b3f12122647b3d5 (diff)
downloadlinux-b0f89c7de8f3cac4952acc5f09539c0b879e58d9.tar.xz
peci: Extend peci client with Domain ID information
Since PECI Target addressing has been changed to use Domain ID information, each peci_client instance should correspond with both CPU ID and Domain ID. Let's extend peci_client structure, sysfs API and intel-peci-client to use Domain ID. Make MFD device ID as a combination of peci adapter number, CPU ID and Domain ID. Signed-off-by: Iwona Winiarska <iwona.winiarska@intel.com>
-rw-r--r--drivers/mfd/intel-peci-client.c7
-rw-r--r--drivers/peci/peci-core.c51
-rw-r--r--include/linux/mfd/intel-peci-client.h4
-rw-r--r--include/linux/peci.h4
4 files changed, 48 insertions, 18 deletions
diff --git a/drivers/mfd/intel-peci-client.c b/drivers/mfd/intel-peci-client.c
index 3eb2c59a2424..69834a230998 100644
--- a/drivers/mfd/intel-peci-client.c
+++ b/drivers/mfd/intel-peci-client.c
@@ -74,7 +74,7 @@ static int peci_client_get_cpu_gen_info(struct peci_client_manager *priv)
int i;
ret = peci_get_cpu_id(priv->client->adapter, priv->client->addr,
- &cpu_id);
+ priv->client->domain_id, &cpu_id);
if (ret)
return ret;
@@ -107,6 +107,9 @@ static int peci_client_get_cpu_gen_info(struct peci_client_manager *priv)
static int peci_client_probe(struct peci_client *client)
{
struct device *dev = &client->dev;
+ u8 cpu_id = client->addr - PECI_BASE_ADDR;
+ u8 domain_id = client->domain_id;
+ u8 adapter_nr = client->adapter->nr;
struct peci_client_manager *priv;
int device_id;
int ret;
@@ -122,7 +125,7 @@ static int peci_client_probe(struct peci_client *client)
if (ret)
return ret;
- device_id = (client->adapter->nr << 4) | (client->addr - PECI_BASE_ADDR);
+ device_id = (adapter_nr << 8) | (cpu_id << 4) | domain_id;
ret = devm_mfd_add_devices(dev, device_id, peci_functions,
ARRAY_SIZE(peci_functions), NULL, 0, NULL);
diff --git a/drivers/peci/peci-core.c b/drivers/peci/peci-core.c
index 90820b75ae37..08bf1a759324 100644
--- a/drivers/peci/peci-core.c
+++ b/drivers/peci/peci-core.c
@@ -1425,6 +1425,13 @@ struct bus_type peci_bus_type = {
};
EXPORT_SYMBOL_GPL(peci_bus_type);
+static int peci_check_domain_validity(u8 domain_id)
+{
+ if (domain_id >= DOMAIN_OFFSET_MAX)
+ return -EINVAL;
+ return 0;
+}
+
static int peci_check_addr_validity(u8 addr)
{
if (addr < PECI_BASE_ADDR && addr > PECI_BASE_ADDR + PECI_OFFSET_MAX)
@@ -1438,7 +1445,8 @@ static int peci_check_client_busy(struct device *dev, void *client_new_p)
struct peci_client *client = peci_verify_client(dev);
struct peci_client *client_new = client_new_p;
- if (client && client->addr == client_new->addr)
+ if (client && client->addr == client_new->addr &&
+ client->domain_id == client_new->domain_id)
return -EBUSY;
return 0;
@@ -1453,12 +1461,13 @@ static int peci_check_client_busy(struct device *dev, void *client_new_p)
*
* Return: zero on success, else a negative error code.
*/
-int peci_get_cpu_id(struct peci_adapter *adapter, u8 addr, u32 *cpu_id)
+int peci_get_cpu_id(struct peci_adapter *adapter, u8 addr, u8 domain_id, u32 *cpu_id)
{
struct peci_rd_pkg_cfg_msg msg;
int ret;
msg.addr = addr;
+ msg.domain_id = domain_id;
msg.index = PECI_MBX_INDEX_CPU_ID;
msg.param = PECI_PKG_ID_CPU_ID;
msg.rx_len = 4;
@@ -1479,6 +1488,7 @@ static struct peci_client *peci_new_device(struct peci_adapter *adapter,
struct peci_board_info const *info)
{
struct peci_client *client;
+ char name[16];
int ret;
/* Increase reference count for the adapter assigned */
@@ -1491,6 +1501,7 @@ static struct peci_client *peci_new_device(struct peci_adapter *adapter,
client->adapter = adapter;
client->addr = info->addr;
+ client->domain_id = info->domain_id;
strlcpy(client->name, info->type, sizeof(client->name));
/* Check online status of client */
@@ -1503,11 +1514,16 @@ static struct peci_client *peci_new_device(struct peci_adapter *adapter,
if (ret)
goto err_free_client;
+ if (client->domain_id)
+ snprintf(name, 16, "%d-%02x-%02x", adapter->nr, client->addr, client->domain_id);
+ else
+ snprintf(name, 16, "%d-%02x", adapter->nr, client->addr);
+
client->dev.parent = &client->adapter->dev;
client->dev.bus = &peci_bus_type;
client->dev.type = &peci_client_type;
client->dev.of_node = of_node_get(info->of_node);
- dev_set_name(&client->dev, "%d-%02x", adapter->nr, client->addr);
+ dev_set_name(&client->dev, name);
ret = device_register(&client->dev);
if (ret)
@@ -1522,8 +1538,8 @@ 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, ret);
+ "Failed to register peci client %s, addr: %#02x, domain id: %#02x, ret: %d\n",
+ client->name, client->addr, client->domain_id, ret);
kfree(client);
err_put_adapter:
peci_put_adapter(adapter);
@@ -1570,8 +1586,8 @@ static ssize_t peci_sysfs_new_device(struct device *dev,
struct peci_adapter *adapter = to_peci_adapter(dev);
struct peci_board_info info = {};
struct peci_client *client;
+ u8 addr, domain_id;
char *blank, end;
- u8 addr;
int ret;
/* Parse device type */
@@ -1587,9 +1603,9 @@ static ssize_t peci_sysfs_new_device(struct device *dev,
memcpy(info.type, buf, blank - buf);
/* Parse remaining parameters, reject extra parameters */
- ret = sscanf(++blank, "%hhi%c", &addr, &end);
+ ret = sscanf(++blank, "%hhi %hhi%c", &addr, &domain_id, &end);
if (ret < 1) {
- dev_err(dev, "%s: Can't parse client address\n", "new_device");
+ dev_err(dev, "%s: Can't parse parameters\n", "new_device");
return -EINVAL;
}
if (ret > 1 && end != '\n') {
@@ -1601,7 +1617,12 @@ static ssize_t peci_sysfs_new_device(struct device *dev,
if (ret)
return ret;
+ ret = peci_check_domain_validity(domain_id);
+ if (ret)
+ domain_id = 0;
+
info.addr = addr;
+ info.domain_id = domain_id;
client = peci_new_device(adapter, &info);
if (!client)
return -EINVAL;
@@ -1624,8 +1645,8 @@ 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 = {};
+ u8 addr, domain_id;
char *blank, end;
- u8 addr;
int ret;
/* Parse device type */
@@ -1641,10 +1662,9 @@ static ssize_t peci_sysfs_delete_device(struct device *dev,
memcpy(info.type, buf, blank - buf);
/* Parse remaining parameters, reject extra parameters */
- ret = sscanf(++blank, "%hhi%c", &addr, &end);
+ ret = sscanf(++blank, "%hhi %hhi%c", &addr, &domain_id, &end);
if (ret < 1) {
- dev_err(dev, "%s: Can't parse client address\n",
- "delete_device");
+ dev_err(dev, "%s: Can't parse parameters\n", "delete_device");
return -EINVAL;
}
if (ret > 1 && end != '\n') {
@@ -1656,14 +1676,19 @@ static ssize_t peci_sysfs_delete_device(struct device *dev,
if (ret)
return ret;
+ ret = peci_check_domain_validity(domain_id);
+ if (ret)
+ domain_id = 0;
+
info.addr = addr;
+ info.domain_id = domain_id;
/* Make sure the device was added through sysfs */
ret = -ENOENT;
mutex_lock(&adapter->userspace_clients_lock);
list_for_each_entry_safe(client, next, &adapter->userspace_clients,
detected) {
- if (client->addr == info.addr &&
+ if (client->addr == info.addr && client->domain_id == info.domain_id &&
!strncmp(client->name, info.type, PECI_NAME_SIZE)) {
dev_dbg(dev, "%s: Deleting device %s at 0x%02hx\n",
"delete_device", client->name, client->addr);
diff --git a/include/linux/mfd/intel-peci-client.h b/include/linux/mfd/intel-peci-client.h
index 84b5882bcf31..0a069b87f733 100644
--- a/include/linux/mfd/intel-peci-client.h
+++ b/include/linux/mfd/intel-peci-client.h
@@ -114,7 +114,7 @@ peci_client_read_package_config(struct peci_client_manager *priv,
msg.index = index;
msg.param = param;
msg.rx_len = 4;
- msg.domain_id = 0;
+ msg.domain_id = priv->client->domain_id;
ret = peci_command(priv->client->adapter, PECI_CMD_RD_PKG_CFG, sizeof(msg), &msg);
if (msg.cc != PECI_DEV_CC_SUCCESS)
@@ -149,7 +149,7 @@ peci_client_write_package_config(struct peci_client_manager *priv,
msg.param = param;
msg.tx_len = 4u;
msg.value = data;
- msg.domain_id = 0;
+ msg.domain_id = priv->client->domain_id;
ret = peci_command(priv->client->adapter, PECI_CMD_WR_PKG_CFG, sizeof(msg), &msg);
if (!ret) {
diff --git a/include/linux/peci.h b/include/linux/peci.h
index 5a707bbeb66d..d9e77c5773be 100644
--- a/include/linux/peci.h
+++ b/include/linux/peci.h
@@ -13,6 +13,7 @@
struct peci_board_info {
char type[PECI_NAME_SIZE];
u8 addr; /* CPU client address */
+ u8 domain_id;
struct device_node *of_node;
};
@@ -77,6 +78,7 @@ struct peci_client {
struct device dev;
struct peci_adapter *adapter;
u8 addr;
+ u8 domain_id;
char name[PECI_NAME_SIZE];
struct list_head detected;
};
@@ -146,6 +148,6 @@ 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, uint msg_len, void *vmsg);
-int peci_get_cpu_id(struct peci_adapter *adapter, u8 addr, u32 *cpu_id);
+int peci_get_cpu_id(struct peci_adapter *adapter, u8 addr, u8 domain_id, u32 *cpu_id);
#endif /* __LINUX_PECI_H */