From b0f89c7de8f3cac4952acc5f09539c0b879e58d9 Mon Sep 17 00:00:00 2001 From: Iwona Winiarska Date: Mon, 9 May 2022 20:05:59 +0200 Subject: 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 --- drivers/mfd/intel-peci-client.c | 7 +++-- drivers/peci/peci-core.c | 51 ++++++++++++++++++++++++++--------- include/linux/mfd/intel-peci-client.h | 4 +-- include/linux/peci.h | 4 ++- 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 */ -- cgit v1.2.3