acpi.c (c1691730d9ffb8e813018235ad1b9754104cf67b) acpi.c (1349dd7dc21c63c9bad0e91fd1bf5f1ada34b0e2)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * AMD HSMP Platform Driver
4 * Copyright (c) 2024, AMD.
5 * All Rights Reserved.
6 *
7 * This file provides an ACPI based driver implementation for HSMP interface.
8 */

--- 21 unchanged lines hidden (view full) ---

30#define DRIVER_VERSION "2.3"
31#define ACPI_HSMP_DEVICE_HID "AMDI0097"
32
33/* These are the strings specified in ACPI table */
34#define MSG_IDOFF_STR "MsgIdOffset"
35#define MSG_ARGOFF_STR "MsgArgOffset"
36#define MSG_RESPOFF_STR "MsgRspOffset"
37
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * AMD HSMP Platform Driver
4 * Copyright (c) 2024, AMD.
5 * All Rights Reserved.
6 *
7 * This file provides an ACPI based driver implementation for HSMP interface.
8 */

--- 21 unchanged lines hidden (view full) ---

30#define DRIVER_VERSION "2.3"
31#define ACPI_HSMP_DEVICE_HID "AMDI0097"
32
33/* These are the strings specified in ACPI table */
34#define MSG_IDOFF_STR "MsgIdOffset"
35#define MSG_ARGOFF_STR "MsgArgOffset"
36#define MSG_RESPOFF_STR "MsgRspOffset"
37
38static struct hsmp_plat_device *hsmp_pdev;
39
38static int amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
39 u32 *value, bool write)
40{
41 if (write)
42 iowrite32(*value, sock->virt_base_addr + offset);
43 else
44 *value = ioread32(sock->virt_base_addr + offset);
45

--- 152 unchanged lines hidden (view full) ---

198 }
199
200 return 0;
201}
202
203/* Parse the ACPI table to read the data */
204static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
205{
40static int amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
41 u32 *value, bool write)
42{
43 if (write)
44 iowrite32(*value, sock->virt_base_addr + offset);
45 else
46 *value = ioread32(sock->virt_base_addr + offset);
47

--- 152 unchanged lines hidden (view full) ---

200 }
201
202 return 0;
203}
204
205/* Parse the ACPI table to read the data */
206static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
207{
206 struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
208 struct hsmp_socket *sock = &hsmp_pdev->sock[sock_ind];
207 int ret;
208
209 sock->sock_ind = sock_ind;
210 sock->dev = dev;
211 sock->amd_hsmp_rdwr = amd_hsmp_acpi_rdwr;
212
213 sema_init(&sock->hsmp_sem, 1);
214

--- 16 unchanged lines hidden (view full) ---

231 struct hsmp_socket *sock = dev_get_drvdata(dev);
232
233 return hsmp_metric_tbl_read(sock, buf, count);
234}
235
236static umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
237 struct bin_attribute *battr, int id)
238{
209 int ret;
210
211 sock->sock_ind = sock_ind;
212 sock->dev = dev;
213 sock->amd_hsmp_rdwr = amd_hsmp_acpi_rdwr;
214
215 sema_init(&sock->hsmp_sem, 1);
216

--- 16 unchanged lines hidden (view full) ---

233 struct hsmp_socket *sock = dev_get_drvdata(dev);
234
235 return hsmp_metric_tbl_read(sock, buf, count);
236}
237
238static umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
239 struct bin_attribute *battr, int id)
240{
239 if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6)
241 if (hsmp_pdev->proto_ver == HSMP_PROTO_VER6)
240 return battr->attr.mode;
241
242 return 0;
243}
244
245static int init_acpi(struct device *dev)
246{
247 u16 sock_ind;
248 int ret;
249
250 ret = hsmp_get_uid(dev, &sock_ind);
251 if (ret)
252 return ret;
242 return battr->attr.mode;
243
244 return 0;
245}
246
247static int init_acpi(struct device *dev)
248{
249 u16 sock_ind;
250 int ret;
251
252 ret = hsmp_get_uid(dev, &sock_ind);
253 if (ret)
254 return ret;
253 if (sock_ind >= hsmp_pdev.num_sockets)
255 if (sock_ind >= hsmp_pdev->num_sockets)
254 return -EINVAL;
255
256 ret = hsmp_parse_acpi_table(dev, sock_ind);
257 if (ret) {
258 dev_err(dev, "Failed to parse ACPI table\n");
259 return ret;
260 }
261

--- 7 unchanged lines hidden (view full) ---

269 }
270
271 ret = hsmp_cache_proto_ver(sock_ind);
272 if (ret) {
273 dev_err(dev, "Failed to read HSMP protocol version\n");
274 return ret;
275 }
276
256 return -EINVAL;
257
258 ret = hsmp_parse_acpi_table(dev, sock_ind);
259 if (ret) {
260 dev_err(dev, "Failed to parse ACPI table\n");
261 return ret;
262 }
263

--- 7 unchanged lines hidden (view full) ---

271 }
272
273 ret = hsmp_cache_proto_ver(sock_ind);
274 if (ret) {
275 dev_err(dev, "Failed to read HSMP protocol version\n");
276 return ret;
277 }
278
277 if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6) {
279 if (hsmp_pdev->proto_ver == HSMP_PROTO_VER6) {
278 ret = hsmp_get_tbl_dram_base(sock_ind);
279 if (ret)
280 dev_err(dev, "Failed to init metric table\n");
281 }
282
283 return ret;
284}
285

--- 23 unchanged lines hidden (view full) ---

309 {}
310};
311MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
312
313static int hsmp_acpi_probe(struct platform_device *pdev)
314{
315 int ret;
316
280 ret = hsmp_get_tbl_dram_base(sock_ind);
281 if (ret)
282 dev_err(dev, "Failed to init metric table\n");
283 }
284
285 return ret;
286}
287

--- 23 unchanged lines hidden (view full) ---

311 {}
312};
313MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
314
315static int hsmp_acpi_probe(struct platform_device *pdev)
316{
317 int ret;
318
317 if (!hsmp_pdev.is_probed) {
318 hsmp_pdev.num_sockets = amd_nb_num();
319 if (hsmp_pdev.num_sockets == 0 || hsmp_pdev.num_sockets > MAX_AMD_SOCKETS)
319 hsmp_pdev = get_hsmp_pdev();
320 if (!hsmp_pdev)
321 return -ENOMEM;
322
323 if (!hsmp_pdev->is_probed) {
324 hsmp_pdev->num_sockets = amd_nb_num();
325 if (hsmp_pdev->num_sockets == 0 || hsmp_pdev->num_sockets > MAX_AMD_SOCKETS)
320 return -ENODEV;
321
326 return -ENODEV;
327
322 hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
323 sizeof(*hsmp_pdev.sock),
324 GFP_KERNEL);
325 if (!hsmp_pdev.sock)
328 hsmp_pdev->sock = devm_kcalloc(&pdev->dev, hsmp_pdev->num_sockets,
329 sizeof(*hsmp_pdev->sock),
330 GFP_KERNEL);
331 if (!hsmp_pdev->sock)
326 return -ENOMEM;
327 }
328
329 ret = init_acpi(&pdev->dev);
330 if (ret) {
331 dev_err(&pdev->dev, "Failed to initialize HSMP interface.\n");
332 return ret;
333 }
334
332 return -ENOMEM;
333 }
334
335 ret = init_acpi(&pdev->dev);
336 if (ret) {
337 dev_err(&pdev->dev, "Failed to initialize HSMP interface.\n");
338 return ret;
339 }
340
335 if (!hsmp_pdev.is_probed) {
341 if (!hsmp_pdev->is_probed) {
336 ret = hsmp_misc_register(&pdev->dev);
337 if (ret)
338 return ret;
342 ret = hsmp_misc_register(&pdev->dev);
343 if (ret)
344 return ret;
339 hsmp_pdev.is_probed = true;
345 hsmp_pdev->is_probed = true;
340 }
341
342 return 0;
343}
344
345static void hsmp_acpi_remove(struct platform_device *pdev)
346{
347 /*
348 * We register only one misc_device even on multi-socket system.
349 * So, deregister should happen only once.
350 */
346 }
347
348 return 0;
349}
350
351static void hsmp_acpi_remove(struct platform_device *pdev)
352{
353 /*
354 * We register only one misc_device even on multi-socket system.
355 * So, deregister should happen only once.
356 */
351 if (hsmp_pdev.is_probed) {
357 if (hsmp_pdev->is_probed) {
352 hsmp_misc_deregister();
358 hsmp_misc_deregister();
353 hsmp_pdev.is_probed = false;
359 hsmp_pdev->is_probed = false;
354 }
355}
356
357static struct platform_driver amd_hsmp_driver = {
358 .probe = hsmp_acpi_probe,
359 .remove = hsmp_acpi_remove,
360 .driver = {
361 .name = DRIVER_NAME,
362 .acpi_match_table = amd_hsmp_acpi_ids,
363 .dev_groups = hsmp_groups,
364 },
365};
366
367module_platform_driver(amd_hsmp_driver);
368
369MODULE_IMPORT_NS(AMD_HSMP);
370MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver");
371MODULE_VERSION(DRIVER_VERSION);
372MODULE_LICENSE("GPL");
360 }
361}
362
363static struct platform_driver amd_hsmp_driver = {
364 .probe = hsmp_acpi_probe,
365 .remove = hsmp_acpi_remove,
366 .driver = {
367 .name = DRIVER_NAME,
368 .acpi_match_table = amd_hsmp_acpi_ids,
369 .dev_groups = hsmp_groups,
370 },
371};
372
373module_platform_driver(amd_hsmp_driver);
374
375MODULE_IMPORT_NS(AMD_HSMP);
376MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver");
377MODULE_VERSION(DRIVER_VERSION);
378MODULE_LICENSE("GPL");