1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright (c) 2018-2021 Intel Corporation 3 4 #include <linux/peci.h> 5 #include <linux/slab.h> 6 7 #include "internal.h" 8 9 /* 10 * PECI device can be removed using sysfs, but the removal can also happen as 11 * a result of controller being removed. 12 * Mutex is used to protect PECI device from being double-deleted. 13 */ 14 static DEFINE_MUTEX(peci_device_del_lock); 15 16 static int peci_detect(struct peci_controller *controller, u8 addr) 17 { 18 /* 19 * PECI Ping is a command encoded by tx_len = 0, rx_len = 0. 20 * We expect correct Write FCS if the device at the target address 21 * is able to respond. 22 */ 23 struct peci_request req = { 0 }; 24 int ret; 25 26 mutex_lock(&controller->bus_lock); 27 ret = controller->ops->xfer(controller, addr, &req); 28 mutex_unlock(&controller->bus_lock); 29 30 return ret; 31 } 32 33 static bool peci_addr_valid(u8 addr) 34 { 35 return addr >= PECI_BASE_ADDR && addr < PECI_BASE_ADDR + PECI_DEVICE_NUM_MAX; 36 } 37 38 static int peci_dev_exists(struct device *dev, void *data) 39 { 40 struct peci_device *device = to_peci_device(dev); 41 u8 *addr = data; 42 43 if (device->addr == *addr) 44 return -EBUSY; 45 46 return 0; 47 } 48 49 int peci_device_create(struct peci_controller *controller, u8 addr) 50 { 51 struct peci_device *device; 52 int ret; 53 54 if (!peci_addr_valid(addr)) 55 return -EINVAL; 56 57 /* Check if we have already detected this device before. */ 58 ret = device_for_each_child(&controller->dev, &addr, peci_dev_exists); 59 if (ret) 60 return 0; 61 62 ret = peci_detect(controller, addr); 63 if (ret) { 64 /* 65 * Device not present or host state doesn't allow successful 66 * detection at this time. 67 */ 68 if (ret == -EIO || ret == -ETIMEDOUT) 69 return 0; 70 71 return ret; 72 } 73 74 device = kzalloc(sizeof(*device), GFP_KERNEL); 75 if (!device) 76 return -ENOMEM; 77 78 device_initialize(&device->dev); 79 80 device->addr = addr; 81 device->dev.parent = &controller->dev; 82 device->dev.bus = &peci_bus_type; 83 device->dev.type = &peci_device_type; 84 85 ret = dev_set_name(&device->dev, "%d-%02x", controller->id, device->addr); 86 if (ret) 87 goto err_put; 88 89 ret = device_add(&device->dev); 90 if (ret) 91 goto err_put; 92 93 return 0; 94 95 err_put: 96 put_device(&device->dev); 97 98 return ret; 99 } 100 101 void peci_device_destroy(struct peci_device *device) 102 { 103 mutex_lock(&peci_device_del_lock); 104 if (!device->deleted) { 105 device_unregister(&device->dev); 106 device->deleted = true; 107 } 108 mutex_unlock(&peci_device_del_lock); 109 } 110 111 static void peci_device_release(struct device *dev) 112 { 113 struct peci_device *device = to_peci_device(dev); 114 115 kfree(device); 116 } 117 118 struct device_type peci_device_type = { 119 .release = peci_device_release, 120 }; 121