Merge tag 'rtc-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux
[linux-2.6-microblaze.git] / drivers / peci / device.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright (c) 2018-2021 Intel Corporation
3
4 #include <linux/bitfield.h>
5 #include <linux/peci.h>
6 #include <linux/peci-cpu.h>
7 #include <linux/slab.h>
8
9 #include "internal.h"
10
11 /*
12  * PECI device can be removed using sysfs, but the removal can also happen as
13  * a result of controller being removed.
14  * Mutex is used to protect PECI device from being double-deleted.
15  */
16 static DEFINE_MUTEX(peci_device_del_lock);
17
18 #define REVISION_NUM_MASK GENMASK(15, 8)
19 static int peci_get_revision(struct peci_device *device, u8 *revision)
20 {
21         struct peci_request *req;
22         u64 dib;
23
24         req = peci_xfer_get_dib(device);
25         if (IS_ERR(req))
26                 return PTR_ERR(req);
27
28         /*
29          * PECI device may be in a state where it is unable to return a proper
30          * DIB, in which case it returns 0 as DIB value.
31          * Let's treat this as an error to avoid carrying on with the detection
32          * using invalid revision.
33          */
34         dib = peci_request_dib_read(req);
35         if (dib == 0) {
36                 peci_request_free(req);
37                 return -EIO;
38         }
39
40         *revision = FIELD_GET(REVISION_NUM_MASK, dib);
41
42         peci_request_free(req);
43
44         return 0;
45 }
46
47 static int peci_get_cpu_id(struct peci_device *device, u32 *cpu_id)
48 {
49         struct peci_request *req;
50         int ret;
51
52         req = peci_xfer_pkg_cfg_readl(device, PECI_PCS_PKG_ID, PECI_PKG_ID_CPU_ID);
53         if (IS_ERR(req))
54                 return PTR_ERR(req);
55
56         ret = peci_request_status(req);
57         if (ret)
58                 goto out_req_free;
59
60         *cpu_id = peci_request_data_readl(req);
61 out_req_free:
62         peci_request_free(req);
63
64         return ret;
65 }
66
67 static unsigned int peci_x86_cpu_family(unsigned int sig)
68 {
69         unsigned int x86;
70
71         x86 = (sig >> 8) & 0xf;
72
73         if (x86 == 0xf)
74                 x86 += (sig >> 20) & 0xff;
75
76         return x86;
77 }
78
79 static unsigned int peci_x86_cpu_model(unsigned int sig)
80 {
81         unsigned int fam, model;
82
83         fam = peci_x86_cpu_family(sig);
84
85         model = (sig >> 4) & 0xf;
86
87         if (fam >= 0x6)
88                 model += ((sig >> 16) & 0xf) << 4;
89
90         return model;
91 }
92
93 static int peci_device_info_init(struct peci_device *device)
94 {
95         u8 revision;
96         u32 cpu_id;
97         int ret;
98
99         ret = peci_get_cpu_id(device, &cpu_id);
100         if (ret)
101                 return ret;
102
103         device->info.family = peci_x86_cpu_family(cpu_id);
104         device->info.model = peci_x86_cpu_model(cpu_id);
105
106         ret = peci_get_revision(device, &revision);
107         if (ret)
108                 return ret;
109         device->info.peci_revision = revision;
110
111         device->info.socket_id = device->addr - PECI_BASE_ADDR;
112
113         return 0;
114 }
115
116 static int peci_detect(struct peci_controller *controller, u8 addr)
117 {
118         /*
119          * PECI Ping is a command encoded by tx_len = 0, rx_len = 0.
120          * We expect correct Write FCS if the device at the target address
121          * is able to respond.
122          */
123         struct peci_request req = { 0 };
124         int ret;
125
126         mutex_lock(&controller->bus_lock);
127         ret = controller->ops->xfer(controller, addr, &req);
128         mutex_unlock(&controller->bus_lock);
129
130         return ret;
131 }
132
133 static bool peci_addr_valid(u8 addr)
134 {
135         return addr >= PECI_BASE_ADDR && addr < PECI_BASE_ADDR + PECI_DEVICE_NUM_MAX;
136 }
137
138 static int peci_dev_exists(struct device *dev, void *data)
139 {
140         struct peci_device *device = to_peci_device(dev);
141         u8 *addr = data;
142
143         if (device->addr == *addr)
144                 return -EBUSY;
145
146         return 0;
147 }
148
149 int peci_device_create(struct peci_controller *controller, u8 addr)
150 {
151         struct peci_device *device;
152         int ret;
153
154         if (!peci_addr_valid(addr))
155                 return -EINVAL;
156
157         /* Check if we have already detected this device before. */
158         ret = device_for_each_child(&controller->dev, &addr, peci_dev_exists);
159         if (ret)
160                 return 0;
161
162         ret = peci_detect(controller, addr);
163         if (ret) {
164                 /*
165                  * Device not present or host state doesn't allow successful
166                  * detection at this time.
167                  */
168                 if (ret == -EIO || ret == -ETIMEDOUT)
169                         return 0;
170
171                 return ret;
172         }
173
174         device = kzalloc(sizeof(*device), GFP_KERNEL);
175         if (!device)
176                 return -ENOMEM;
177
178         device_initialize(&device->dev);
179
180         device->addr = addr;
181         device->dev.parent = &controller->dev;
182         device->dev.bus = &peci_bus_type;
183         device->dev.type = &peci_device_type;
184
185         ret = peci_device_info_init(device);
186         if (ret)
187                 goto err_put;
188
189         ret = dev_set_name(&device->dev, "%d-%02x", controller->id, device->addr);
190         if (ret)
191                 goto err_put;
192
193         ret = device_add(&device->dev);
194         if (ret)
195                 goto err_put;
196
197         return 0;
198
199 err_put:
200         put_device(&device->dev);
201
202         return ret;
203 }
204
205 void peci_device_destroy(struct peci_device *device)
206 {
207         mutex_lock(&peci_device_del_lock);
208         if (!device->deleted) {
209                 device_unregister(&device->dev);
210                 device->deleted = true;
211         }
212         mutex_unlock(&peci_device_del_lock);
213 }
214
215 int __peci_driver_register(struct peci_driver *driver, struct module *owner,
216                            const char *mod_name)
217 {
218         driver->driver.bus = &peci_bus_type;
219         driver->driver.owner = owner;
220         driver->driver.mod_name = mod_name;
221
222         if (!driver->probe) {
223                 pr_err("peci: trying to register driver without probe callback\n");
224                 return -EINVAL;
225         }
226
227         if (!driver->id_table) {
228                 pr_err("peci: trying to register driver without device id table\n");
229                 return -EINVAL;
230         }
231
232         return driver_register(&driver->driver);
233 }
234 EXPORT_SYMBOL_NS_GPL(__peci_driver_register, PECI);
235
236 void peci_driver_unregister(struct peci_driver *driver)
237 {
238         driver_unregister(&driver->driver);
239 }
240 EXPORT_SYMBOL_NS_GPL(peci_driver_unregister, PECI);
241
242 static void peci_device_release(struct device *dev)
243 {
244         struct peci_device *device = to_peci_device(dev);
245
246         kfree(device);
247 }
248
249 struct device_type peci_device_type = {
250         .groups         = peci_device_groups,
251         .release        = peci_device_release,
252 };