Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 // Copyright (c) 2018-2021 Intel Corporation
0003 
0004 #include <linux/bitfield.h>
0005 #include <linux/peci.h>
0006 #include <linux/peci-cpu.h>
0007 #include <linux/slab.h>
0008 
0009 #include "internal.h"
0010 
0011 /*
0012  * PECI device can be removed using sysfs, but the removal can also happen as
0013  * a result of controller being removed.
0014  * Mutex is used to protect PECI device from being double-deleted.
0015  */
0016 static DEFINE_MUTEX(peci_device_del_lock);
0017 
0018 #define REVISION_NUM_MASK GENMASK(15, 8)
0019 static int peci_get_revision(struct peci_device *device, u8 *revision)
0020 {
0021     struct peci_request *req;
0022     u64 dib;
0023 
0024     req = peci_xfer_get_dib(device);
0025     if (IS_ERR(req))
0026         return PTR_ERR(req);
0027 
0028     /*
0029      * PECI device may be in a state where it is unable to return a proper
0030      * DIB, in which case it returns 0 as DIB value.
0031      * Let's treat this as an error to avoid carrying on with the detection
0032      * using invalid revision.
0033      */
0034     dib = peci_request_dib_read(req);
0035     if (dib == 0) {
0036         peci_request_free(req);
0037         return -EIO;
0038     }
0039 
0040     *revision = FIELD_GET(REVISION_NUM_MASK, dib);
0041 
0042     peci_request_free(req);
0043 
0044     return 0;
0045 }
0046 
0047 static int peci_get_cpu_id(struct peci_device *device, u32 *cpu_id)
0048 {
0049     struct peci_request *req;
0050     int ret;
0051 
0052     req = peci_xfer_pkg_cfg_readl(device, PECI_PCS_PKG_ID, PECI_PKG_ID_CPU_ID);
0053     if (IS_ERR(req))
0054         return PTR_ERR(req);
0055 
0056     ret = peci_request_status(req);
0057     if (ret)
0058         goto out_req_free;
0059 
0060     *cpu_id = peci_request_data_readl(req);
0061 out_req_free:
0062     peci_request_free(req);
0063 
0064     return ret;
0065 }
0066 
0067 static unsigned int peci_x86_cpu_family(unsigned int sig)
0068 {
0069     unsigned int x86;
0070 
0071     x86 = (sig >> 8) & 0xf;
0072 
0073     if (x86 == 0xf)
0074         x86 += (sig >> 20) & 0xff;
0075 
0076     return x86;
0077 }
0078 
0079 static unsigned int peci_x86_cpu_model(unsigned int sig)
0080 {
0081     unsigned int fam, model;
0082 
0083     fam = peci_x86_cpu_family(sig);
0084 
0085     model = (sig >> 4) & 0xf;
0086 
0087     if (fam >= 0x6)
0088         model += ((sig >> 16) & 0xf) << 4;
0089 
0090     return model;
0091 }
0092 
0093 static int peci_device_info_init(struct peci_device *device)
0094 {
0095     u8 revision;
0096     u32 cpu_id;
0097     int ret;
0098 
0099     ret = peci_get_cpu_id(device, &cpu_id);
0100     if (ret)
0101         return ret;
0102 
0103     device->info.family = peci_x86_cpu_family(cpu_id);
0104     device->info.model = peci_x86_cpu_model(cpu_id);
0105 
0106     ret = peci_get_revision(device, &revision);
0107     if (ret)
0108         return ret;
0109     device->info.peci_revision = revision;
0110 
0111     device->info.socket_id = device->addr - PECI_BASE_ADDR;
0112 
0113     return 0;
0114 }
0115 
0116 static int peci_detect(struct peci_controller *controller, u8 addr)
0117 {
0118     /*
0119      * PECI Ping is a command encoded by tx_len = 0, rx_len = 0.
0120      * We expect correct Write FCS if the device at the target address
0121      * is able to respond.
0122      */
0123     struct peci_request req = { 0 };
0124     int ret;
0125 
0126     mutex_lock(&controller->bus_lock);
0127     ret = controller->ops->xfer(controller, addr, &req);
0128     mutex_unlock(&controller->bus_lock);
0129 
0130     return ret;
0131 }
0132 
0133 static bool peci_addr_valid(u8 addr)
0134 {
0135     return addr >= PECI_BASE_ADDR && addr < PECI_BASE_ADDR + PECI_DEVICE_NUM_MAX;
0136 }
0137 
0138 static int peci_dev_exists(struct device *dev, void *data)
0139 {
0140     struct peci_device *device = to_peci_device(dev);
0141     u8 *addr = data;
0142 
0143     if (device->addr == *addr)
0144         return -EBUSY;
0145 
0146     return 0;
0147 }
0148 
0149 int peci_device_create(struct peci_controller *controller, u8 addr)
0150 {
0151     struct peci_device *device;
0152     int ret;
0153 
0154     if (!peci_addr_valid(addr))
0155         return -EINVAL;
0156 
0157     /* Check if we have already detected this device before. */
0158     ret = device_for_each_child(&controller->dev, &addr, peci_dev_exists);
0159     if (ret)
0160         return 0;
0161 
0162     ret = peci_detect(controller, addr);
0163     if (ret) {
0164         /*
0165          * Device not present or host state doesn't allow successful
0166          * detection at this time.
0167          */
0168         if (ret == -EIO || ret == -ETIMEDOUT)
0169             return 0;
0170 
0171         return ret;
0172     }
0173 
0174     device = kzalloc(sizeof(*device), GFP_KERNEL);
0175     if (!device)
0176         return -ENOMEM;
0177 
0178     device_initialize(&device->dev);
0179 
0180     device->addr = addr;
0181     device->dev.parent = &controller->dev;
0182     device->dev.bus = &peci_bus_type;
0183     device->dev.type = &peci_device_type;
0184 
0185     ret = peci_device_info_init(device);
0186     if (ret)
0187         goto err_put;
0188 
0189     ret = dev_set_name(&device->dev, "%d-%02x", controller->id, device->addr);
0190     if (ret)
0191         goto err_put;
0192 
0193     ret = device_add(&device->dev);
0194     if (ret)
0195         goto err_put;
0196 
0197     return 0;
0198 
0199 err_put:
0200     put_device(&device->dev);
0201 
0202     return ret;
0203 }
0204 
0205 void peci_device_destroy(struct peci_device *device)
0206 {
0207     mutex_lock(&peci_device_del_lock);
0208     if (!device->deleted) {
0209         device_unregister(&device->dev);
0210         device->deleted = true;
0211     }
0212     mutex_unlock(&peci_device_del_lock);
0213 }
0214 
0215 int __peci_driver_register(struct peci_driver *driver, struct module *owner,
0216                const char *mod_name)
0217 {
0218     driver->driver.bus = &peci_bus_type;
0219     driver->driver.owner = owner;
0220     driver->driver.mod_name = mod_name;
0221 
0222     if (!driver->probe) {
0223         pr_err("peci: trying to register driver without probe callback\n");
0224         return -EINVAL;
0225     }
0226 
0227     if (!driver->id_table) {
0228         pr_err("peci: trying to register driver without device id table\n");
0229         return -EINVAL;
0230     }
0231 
0232     return driver_register(&driver->driver);
0233 }
0234 EXPORT_SYMBOL_NS_GPL(__peci_driver_register, PECI);
0235 
0236 void peci_driver_unregister(struct peci_driver *driver)
0237 {
0238     driver_unregister(&driver->driver);
0239 }
0240 EXPORT_SYMBOL_NS_GPL(peci_driver_unregister, PECI);
0241 
0242 static void peci_device_release(struct device *dev)
0243 {
0244     struct peci_device *device = to_peci_device(dev);
0245 
0246     kfree(device);
0247 }
0248 
0249 struct device_type peci_device_type = {
0250     .groups     = peci_device_groups,
0251     .release    = peci_device_release,
0252 };