All of lore.kernel.org
 help / color / mirror / Atom feed
* [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory
@ 2024-07-20 17:45 Suma Hegde
  2024-07-20 17:45 ` [v3 02/11] platform/x86/amd/hsmp: Create wrapper function init_acpi() Suma Hegde
                   ` (10 more replies)
  0 siblings, 11 replies; 21+ messages in thread
From: Suma Hegde @ 2024-07-20 17:45 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, hdegoede, Suma Hegde, Naveen Krishna Chatradhi

This is in preparation to splitting ACPI and platform device drivers.
Create and move hsmp specific code into its own directory,
no logical changes.

Signed-off-by: Suma Hegde <suma.hegde@amd.com>
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
---
Changes since v2:
None
Changes since v1:
None

 MAINTAINERS                                |  2 +-
 drivers/platform/x86/amd/Kconfig           | 14 +-------------
 drivers/platform/x86/amd/Makefile          |  3 +--
 drivers/platform/x86/amd/hsmp/Kconfig      | 17 +++++++++++++++++
 drivers/platform/x86/amd/hsmp/Makefile     |  8 ++++++++
 drivers/platform/x86/amd/{ => hsmp}/hsmp.c |  0
 6 files changed, 28 insertions(+), 16 deletions(-)
 create mode 100644 drivers/platform/x86/amd/hsmp/Kconfig
 create mode 100644 drivers/platform/x86/amd/hsmp/Makefile
 rename drivers/platform/x86/amd/{ => hsmp}/hsmp.c (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index d6c90161c7bf..a7d79d1f7ec1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1037,7 +1037,7 @@ S:	Maintained
 F:	Documentation/arch/x86/amd_hsmp.rst
 F:	arch/x86/include/asm/amd_hsmp.h
 F:	arch/x86/include/uapi/asm/amd_hsmp.h
-F:	drivers/platform/x86/amd/hsmp.c
+F:	drivers/platform/x86/amd/hsmp/
 
 AMD IOMMU (AMD-VI)
 M:	Joerg Roedel <joro@8bytes.org>
diff --git a/drivers/platform/x86/amd/Kconfig b/drivers/platform/x86/amd/Kconfig
index f88682d36447..2c671cc17d63 100644
--- a/drivers/platform/x86/amd/Kconfig
+++ b/drivers/platform/x86/amd/Kconfig
@@ -3,22 +3,10 @@
 # AMD x86 Platform Specific Drivers
 #
 
+source "drivers/platform/x86/amd/hsmp/Kconfig"
 source "drivers/platform/x86/amd/pmf/Kconfig"
 source "drivers/platform/x86/amd/pmc/Kconfig"
 
-config AMD_HSMP
-	tristate "AMD HSMP Driver"
-	depends on AMD_NB && X86_64 && ACPI
-	help
-	  The driver provides a way for user space tools to monitor and manage
-	  system management functionality on EPYC server CPUs from AMD.
-
-	  Host System Management Port (HSMP) interface is a mailbox interface
-	  between the x86 core and the System Management Unit (SMU) firmware.
-
-	  If you choose to compile this driver as a module the module will be
-	  called amd_hsmp.
-
 config AMD_WBRF
 	bool "AMD Wifi RF Band mitigations (WBRF)"
 	depends on ACPI
diff --git a/drivers/platform/x86/amd/Makefile b/drivers/platform/x86/amd/Makefile
index dcec0a46f8af..96ec24c8701b 100644
--- a/drivers/platform/x86/amd/Makefile
+++ b/drivers/platform/x86/amd/Makefile
@@ -5,7 +5,6 @@
 #
 
 obj-$(CONFIG_AMD_PMC)		+= pmc/
-amd_hsmp-y			:= hsmp.o
-obj-$(CONFIG_AMD_HSMP)		+= amd_hsmp.o
+obj-y				+= hsmp/
 obj-$(CONFIG_AMD_PMF)		+= pmf/
 obj-$(CONFIG_AMD_WBRF)		+= wbrf.o
diff --git a/drivers/platform/x86/amd/hsmp/Kconfig b/drivers/platform/x86/amd/hsmp/Kconfig
new file mode 100644
index 000000000000..b55d4ed9bceb
--- /dev/null
+++ b/drivers/platform/x86/amd/hsmp/Kconfig
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# AMD HSMP Driver
+#
+
+config AMD_HSMP
+	tristate "AMD HSMP Driver"
+	depends on AMD_NB && X86_64 && ACPI
+	help
+	  The driver provides a way for user space tools to monitor and manage
+	  system management functionality on EPYC server CPUs from AMD.
+
+	  Host System Management Port (HSMP) interface is a mailbox interface
+	  between the x86 core and the System Management Unit (SMU) firmware.
+
+	  If you choose to compile this driver as a module the module will be
+	  called amd_hsmp.
diff --git a/drivers/platform/x86/amd/hsmp/Makefile b/drivers/platform/x86/amd/hsmp/Makefile
new file mode 100644
index 000000000000..fda64906a5e8
--- /dev/null
+++ b/drivers/platform/x86/amd/hsmp/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for drivers/platform/x86/amd/hsmp
+# AMD HSMP Driver
+#
+
+obj-$(CONFIG_AMD_HSMP)		+= amd_hsmp.o
+amd_hsmp-objs			:= hsmp.o
diff --git a/drivers/platform/x86/amd/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
similarity index 100%
rename from drivers/platform/x86/amd/hsmp.c
rename to drivers/platform/x86/amd/hsmp/hsmp.c
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [v3 02/11] platform/x86/amd/hsmp: Create wrapper function init_acpi()
  2024-07-20 17:45 [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Suma Hegde
@ 2024-07-20 17:45 ` Suma Hegde
  2024-07-20 17:45 ` [v3 03/11] platform/x86/amd/hsmp: Move structure and macros to header file Suma Hegde
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Suma Hegde @ 2024-07-20 17:45 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, hdegoede, Suma Hegde, Naveen Krishna Chatradhi

This is in preparation to splitting ACPI and platform device drivers.
Having init_acpi() helps in smooth code movement.

Signed-off-by: Suma Hegde <suma.hegde@amd.com>
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
Changes since v2:
None
Changes since v1:
Add "Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>"

 drivers/platform/x86/amd/hsmp/hsmp.c | 91 ++++++++++++++++++----------
 1 file changed, 59 insertions(+), 32 deletions(-)

diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
index 8fcf38eed7f0..10ab9b2437f1 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.c
+++ b/drivers/platform/x86/amd/hsmp/hsmp.c
@@ -778,6 +778,11 @@ static int init_platform_device(struct device *dev)
 			dev_err(dev, "Is HSMP disabled in BIOS ?\n");
 			return ret;
 		}
+		ret = hsmp_cache_proto_ver(i);
+		if (ret) {
+			dev_err(dev, "Failed to read HSMP protocol version\n");
+			return ret;
+		}
 	}
 
 	return 0;
@@ -789,10 +794,53 @@ static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
 
+static bool check_acpi_support(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
+		return true;
+
+	return false;
+}
+
+static int init_acpi(struct device *dev)
+{
+	u16 sock_ind;
+	int ret;
+
+	ret = hsmp_get_uid(dev, &sock_ind);
+	if (ret)
+		return ret;
+	if (sock_ind >= plat_dev.num_sockets)
+		return -EINVAL;
+
+	ret = hsmp_parse_acpi_table(dev, sock_ind);
+	if (ret) {
+		dev_err(dev, "Failed to parse ACPI table\n");
+		return ret;
+	}
+
+	/* Test the hsmp interface */
+	ret = hsmp_test(sock_ind, 0xDEADBEEF);
+	if (ret) {
+		dev_err(dev, "HSMP test message failed on Fam:%x model:%x\n",
+			boot_cpu_data.x86, boot_cpu_data.x86_model);
+		dev_err(dev, "Is HSMP disabled in BIOS ?\n");
+		return ret;
+	}
+
+	ret = hsmp_cache_proto_ver(sock_ind);
+	if (ret) {
+		dev_err(dev, "Failed to read HSMP protocol version\n");
+		return ret;
+	}
+
+	return ret;
+}
+
 static int hsmp_pltdrv_probe(struct platform_device *pdev)
 {
-	struct acpi_device *adev;
-	u16 sock_ind = 0;
 	int ret;
 
 	/*
@@ -809,46 +857,25 @@ static int hsmp_pltdrv_probe(struct platform_device *pdev)
 		if (!plat_dev.sock)
 			return -ENOMEM;
 	}
-	adev = ACPI_COMPANION(&pdev->dev);
-	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids)) {
-		ret = hsmp_get_uid(&pdev->dev, &sock_ind);
-		if (ret)
-			return ret;
-		if (sock_ind >= plat_dev.num_sockets)
-			return -EINVAL;
-		ret = hsmp_parse_acpi_table(&pdev->dev, sock_ind);
-		if (ret) {
-			dev_err(&pdev->dev, "Failed to parse ACPI table\n");
-			return ret;
-		}
-		/* Test the hsmp interface */
-		ret = hsmp_test(sock_ind, 0xDEADBEEF);
+	if (check_acpi_support(&pdev->dev)) {
+		ret = init_acpi(&pdev->dev);
 		if (ret) {
-			dev_err(&pdev->dev, "HSMP test message failed on Fam:%x model:%x\n",
-				boot_cpu_data.x86, boot_cpu_data.x86_model);
-			dev_err(&pdev->dev, "Is HSMP disabled in BIOS ?\n");
+			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
 			return ret;
 		}
+		ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
+		if (ret)
+			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
 	} else {
 		ret = init_platform_device(&pdev->dev);
 		if (ret) {
 			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
 			return ret;
 		}
-	}
-
-	ret = hsmp_cache_proto_ver(sock_ind);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to read HSMP protocol version\n");
-		return ret;
-	}
-
-	if (plat_dev.is_acpi_device)
-		ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
-	else
 		ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
-	if (ret)
-		dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
+		if (ret)
+			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
+	}
 
 	if (!plat_dev.is_probed) {
 		plat_dev.hsmp_device.name	= HSMP_CDEV_NAME;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [v3 03/11] platform/x86/amd/hsmp: Move structure and macros to header file
  2024-07-20 17:45 [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Suma Hegde
  2024-07-20 17:45 ` [v3 02/11] platform/x86/amd/hsmp: Create wrapper function init_acpi() Suma Hegde
@ 2024-07-20 17:45 ` Suma Hegde
  2024-08-07 11:39   ` Ilpo Järvinen
  2024-07-20 17:45 ` [v3 04/11] platform/x86/amd/hsmp: Move platform device specific code to plat.c Suma Hegde
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Suma Hegde @ 2024-07-20 17:45 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, hdegoede, Suma Hegde, Naveen Krishna Chatradhi

This is in preparation to splitting ACPI and platform device drivers.
No logical change, move common structures and macros to hsmp.h

Signed-off-by: Suma Hegde <suma.hegde@amd.com>
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
Changes since v2:
None
Changes since v1:
1. Correct typo mistake in commit message
2. Add "Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>"
3. Arrange header files in alphabetical order for hsmp.h

 drivers/platform/x86/amd/hsmp/hsmp.c | 42 ++--------------------
 drivers/platform/x86/amd/hsmp/hsmp.h | 54 ++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 40 deletions(-)
 create mode 100644 drivers/platform/x86/amd/hsmp/hsmp.h

diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
index 10ab9b2437f1..2c9ba51b9614 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.c
+++ b/drivers/platform/x86/amd/hsmp/hsmp.c
@@ -9,15 +9,14 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include "hsmp.h"
+
 #include <asm/amd_hsmp.h>
 #include <asm/amd_nb.h>
 #include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
-#include <linux/semaphore.h>
 #include <linux/acpi.h>
 
 #define DRIVER_NAME		"amd_hsmp"
@@ -51,48 +50,11 @@
 #define HSMP_INDEX_REG		0xc4
 #define HSMP_DATA_REG		0xc8
 
-#define HSMP_CDEV_NAME		"hsmp_cdev"
-#define HSMP_DEVNODE_NAME	"hsmp"
-#define HSMP_METRICS_TABLE_NAME	"metrics_bin"
-
-#define HSMP_ATTR_GRP_NAME_SIZE	10
-
 /* These are the strings specified in ACPI table */
 #define MSG_IDOFF_STR		"MsgIdOffset"
 #define MSG_ARGOFF_STR		"MsgArgOffset"
 #define MSG_RESPOFF_STR		"MsgRspOffset"
 
-#define MAX_AMD_SOCKETS 8
-
-struct hsmp_mbaddr_info {
-	u32 base_addr;
-	u32 msg_id_off;
-	u32 msg_resp_off;
-	u32 msg_arg_off;
-	u32 size;
-};
-
-struct hsmp_socket {
-	struct bin_attribute hsmp_attr;
-	struct hsmp_mbaddr_info mbinfo;
-	void __iomem *metric_tbl_addr;
-	void __iomem *virt_base_addr;
-	struct semaphore hsmp_sem;
-	char name[HSMP_ATTR_GRP_NAME_SIZE];
-	struct pci_dev *root;
-	struct device *dev;
-	u16 sock_ind;
-};
-
-struct hsmp_plat_device {
-	struct miscdevice hsmp_device;
-	struct hsmp_socket *sock;
-	u32 proto_ver;
-	u16 num_sockets;
-	bool is_acpi_device;
-	bool is_probed;
-};
-
 static struct hsmp_plat_device plat_dev;
 
 static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
new file mode 100644
index 000000000000..5afc7167fac1
--- /dev/null
+++ b/drivers/platform/x86/amd/hsmp/hsmp.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * AMD HSMP Platform Driver
+ * Copyright (c) 2024, AMD.
+ * All Rights Reserved.
+ *
+ * Header file for HSMP driver
+ */
+
+#ifndef HSMP_H
+#define HSMP_H
+
+#include <linux/io.h>
+#include <linux/miscdevice.h>
+#include <linux/semaphore.h>
+
+#define HSMP_METRICS_TABLE_NAME	"metrics_bin"
+
+#define HSMP_ATTR_GRP_NAME_SIZE	10
+
+#define MAX_AMD_SOCKETS 8
+
+#define HSMP_CDEV_NAME		"hsmp_cdev"
+#define HSMP_DEVNODE_NAME	"hsmp"
+
+struct hsmp_mbaddr_info {
+	u32 base_addr;
+	u32 msg_id_off;
+	u32 msg_resp_off;
+	u32 msg_arg_off;
+	u32 size;
+};
+
+struct hsmp_socket {
+	struct bin_attribute hsmp_attr;
+	struct hsmp_mbaddr_info mbinfo;
+	void __iomem *metric_tbl_addr;
+	void __iomem *virt_base_addr;
+	struct semaphore hsmp_sem;
+	char name[HSMP_ATTR_GRP_NAME_SIZE];
+	struct pci_dev *root;
+	struct device *dev;
+	u16 sock_ind;
+};
+
+struct hsmp_plat_device {
+	struct miscdevice hsmp_device;
+	struct hsmp_socket *sock;
+	u32 proto_ver;
+	u16 num_sockets;
+	bool is_acpi_device;
+	bool is_probed;
+};
+#endif /* HSMP_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [v3 04/11] platform/x86/amd/hsmp: Move platform device specific code to plat.c
  2024-07-20 17:45 [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Suma Hegde
  2024-07-20 17:45 ` [v3 02/11] platform/x86/amd/hsmp: Create wrapper function init_acpi() Suma Hegde
  2024-07-20 17:45 ` [v3 03/11] platform/x86/amd/hsmp: Move structure and macros to header file Suma Hegde
@ 2024-07-20 17:45 ` Suma Hegde
  2024-08-07 12:50   ` Ilpo Järvinen
  2024-07-20 17:45 ` [v3 05/11] platform/x86/amd/hsmp: Move ACPI code to acpi.c Suma Hegde
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Suma Hegde @ 2024-07-20 17:45 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, hdegoede, Suma Hegde, Naveen Krishna Chatradhi

Move platform device part to plat.c.

No functinality/logical changes.
Common code which can be used by ACPI and platform device
remains in hsmp.c.
ACPI code in hsmp.c will be moved to acpi.c in next patch.

Signed-off-by: Suma Hegde <suma.hegde@amd.com>
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
---
Changes since v2:
None
Changes since v1:
1. Include new header file device.h in plat.c
2. Arrange headers in alphabetical order
3. Add an empty line between asm/ and linux/ headers
 
 drivers/platform/x86/amd/hsmp/Makefile |   2 +-
 drivers/platform/x86/amd/hsmp/hsmp.c   | 350 ++-----------------------
 drivers/platform/x86/amd/hsmp/hsmp.h   |  17 ++
 drivers/platform/x86/amd/hsmp/plat.c   | 338 ++++++++++++++++++++++++
 4 files changed, 371 insertions(+), 336 deletions(-)
 create mode 100644 drivers/platform/x86/amd/hsmp/plat.c

diff --git a/drivers/platform/x86/amd/hsmp/Makefile b/drivers/platform/x86/amd/hsmp/Makefile
index fda64906a5e8..fb8ba04b2f0d 100644
--- a/drivers/platform/x86/amd/hsmp/Makefile
+++ b/drivers/platform/x86/amd/hsmp/Makefile
@@ -5,4 +5,4 @@
 #
 
 obj-$(CONFIG_AMD_HSMP)		+= amd_hsmp.o
-amd_hsmp-objs			:= hsmp.o
+amd_hsmp-objs			:= hsmp.o plat.o
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
index 2c9ba51b9614..d15a978ff71e 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.c
+++ b/drivers/platform/x86/amd/hsmp/hsmp.c
@@ -12,16 +12,9 @@
 #include "hsmp.h"
 
 #include <asm/amd_hsmp.h>
-#include <asm/amd_nb.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/platform_device.h>
-#include <linux/acpi.h>
 
-#define DRIVER_NAME		"amd_hsmp"
-#define DRIVER_VERSION		"2.2"
-#define ACPI_HSMP_DEVICE_HID	"AMDI0097"
+#include <linux/acpi.h>
+#include <linux/delay.h>
 
 /* HSMP Status / Error codes */
 #define HSMP_STATUS_NOT_READY	0x00
@@ -36,45 +29,12 @@
 #define HSMP_WR			true
 #define HSMP_RD			false
 
-/*
- * To access specific HSMP mailbox register, s/w writes the SMN address of HSMP mailbox
- * register into the SMN_INDEX register, and reads/writes the SMN_DATA reg.
- * Below are required SMN address for HSMP Mailbox register offsets in SMU address space
- */
-#define SMN_HSMP_BASE		0x3B00000
-#define SMN_HSMP_MSG_ID		0x0010534
-#define SMN_HSMP_MSG_ID_F1A_M0H	0x0010934
-#define SMN_HSMP_MSG_RESP	0x0010980
-#define SMN_HSMP_MSG_DATA	0x00109E0
-
-#define HSMP_INDEX_REG		0xc4
-#define HSMP_DATA_REG		0xc8
-
 /* These are the strings specified in ACPI table */
 #define MSG_IDOFF_STR		"MsgIdOffset"
 #define MSG_ARGOFF_STR		"MsgArgOffset"
 #define MSG_RESPOFF_STR		"MsgRspOffset"
 
-static struct hsmp_plat_device plat_dev;
-
-static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
-			     u32 *value, bool write)
-{
-	int ret;
-
-	if (!sock->root)
-		return -ENODEV;
-
-	ret = pci_write_config_dword(sock->root, HSMP_INDEX_REG,
-				     sock->mbinfo.base_addr + offset);
-	if (ret)
-		return ret;
-
-	ret = (write ? pci_write_config_dword(sock->root, HSMP_DATA_REG, *value)
-		     : pci_read_config_dword(sock->root, HSMP_DATA_REG, value));
-
-	return ret;
-}
+struct hsmp_plat_device plat_dev;
 
 static void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
 			       u32 *value, bool write)
@@ -253,7 +213,7 @@ int hsmp_send_message(struct hsmp_message *msg)
 }
 EXPORT_SYMBOL_GPL(hsmp_send_message);
 
-static int hsmp_test(u16 sock_ind, u32 value)
+int hsmp_test(u16 sock_ind, u32 value)
 {
 	struct hsmp_message msg = { 0 };
 	int ret;
@@ -283,7 +243,7 @@ static int hsmp_test(u16 sock_ind, u32 value)
 	return ret;
 }
 
-static long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
+long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 {
 	int __user *arguser = (int  __user *)arg;
 	struct hsmp_message msg = { 0 };
@@ -339,12 +299,6 @@ static long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 	return 0;
 }
 
-static const struct file_operations hsmp_fops = {
-	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= hsmp_ioctl,
-	.compat_ioctl	= hsmp_ioctl,
-};
-
 /* This is the UUID used for HSMP */
 static const guid_t acpi_hsmp_uuid = GUID_INIT(0xb74d619d, 0x5707, 0x48bd,
 						0xa6, 0x9f, 0x4e, 0xa2,
@@ -520,9 +474,9 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
 	return hsmp_read_acpi_dsd(sock);
 }
 
-static ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
-				    struct bin_attribute *bin_attr, char *buf,
-				    loff_t off, size_t count)
+ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
+			     struct bin_attribute *bin_attr, char *buf,
+			     loff_t off, size_t count)
 {
 	struct hsmp_socket *sock = bin_attr->private;
 	struct hsmp_message msg = { 0 };
@@ -581,8 +535,8 @@ static int hsmp_get_tbl_dram_base(u16 sock_ind)
 	return 0;
 }
 
-static umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
-					 struct bin_attribute *battr, int id)
+umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
+				  struct bin_attribute *battr, int id)
 {
 	if (plat_dev.proto_ver == HSMP_PROTO_VER6)
 		return battr->attr.mode;
@@ -611,8 +565,8 @@ static int hsmp_init_metric_tbl_bin_attr(struct bin_attribute **hattrs, u16 sock
 /* One bin sysfs for metrics table */
 #define NUM_HSMP_ATTRS		1
 
-static int hsmp_create_attr_list(struct attribute_group *attr_grp,
-				 struct device *dev, u16 sock_ind)
+int hsmp_create_attr_list(struct attribute_group *attr_grp,
+			  struct device *dev, u16 sock_ind)
 {
 	struct bin_attribute **hsmp_bin_attrs;
 
@@ -628,37 +582,7 @@ static int hsmp_create_attr_list(struct attribute_group *attr_grp,
 	return hsmp_init_metric_tbl_bin_attr(hsmp_bin_attrs, sock_ind);
 }
 
-static int hsmp_create_non_acpi_sysfs_if(struct device *dev)
-{
-	const struct attribute_group **hsmp_attr_grps;
-	struct attribute_group *attr_grp;
-	u16 i;
-
-	hsmp_attr_grps = devm_kcalloc(dev, plat_dev.num_sockets + 1,
-				      sizeof(*hsmp_attr_grps),
-				      GFP_KERNEL);
-	if (!hsmp_attr_grps)
-		return -ENOMEM;
-
-	/* Create a sysfs directory for each socket */
-	for (i = 0; i < plat_dev.num_sockets; i++) {
-		attr_grp = devm_kzalloc(dev, sizeof(struct attribute_group),
-					GFP_KERNEL);
-		if (!attr_grp)
-			return -ENOMEM;
-
-		snprintf(plat_dev.sock[i].name, HSMP_ATTR_GRP_NAME_SIZE, "socket%u", (u8)i);
-		attr_grp->name			= plat_dev.sock[i].name;
-		attr_grp->is_bin_visible	= hsmp_is_sock_attr_visible;
-		hsmp_attr_grps[i]		= attr_grp;
-
-		hsmp_create_attr_list(attr_grp, dev, i);
-	}
-
-	return device_add_groups(dev, hsmp_attr_grps);
-}
-
-static int hsmp_create_acpi_sysfs_if(struct device *dev)
+int hsmp_create_acpi_sysfs_if(struct device *dev)
 {
 	struct attribute_group *attr_grp;
 	u16 sock_ind;
@@ -681,7 +605,7 @@ static int hsmp_create_acpi_sysfs_if(struct device *dev)
 	return devm_device_add_group(dev, attr_grp);
 }
 
-static int hsmp_cache_proto_ver(u16 sock_ind)
+int hsmp_cache_proto_ver(u16 sock_ind)
 {
 	struct hsmp_message msg = { 0 };
 	int ret;
@@ -697,76 +621,7 @@ static int hsmp_cache_proto_ver(u16 sock_ind)
 	return ret;
 }
 
-static inline bool is_f1a_m0h(void)
-{
-	if (boot_cpu_data.x86 == 0x1A && boot_cpu_data.x86_model <= 0x0F)
-		return true;
-
-	return false;
-}
-
-static int init_platform_device(struct device *dev)
-{
-	struct hsmp_socket *sock;
-	int ret, i;
-
-	for (i = 0; i < plat_dev.num_sockets; i++) {
-		if (!node_to_amd_nb(i))
-			return -ENODEV;
-		sock = &plat_dev.sock[i];
-		sock->root			= node_to_amd_nb(i)->root;
-		sock->sock_ind			= i;
-		sock->dev			= dev;
-		sock->mbinfo.base_addr		= SMN_HSMP_BASE;
-
-		/*
-		 * This is a transitional change from non-ACPI to ACPI, only
-		 * family 0x1A, model 0x00 platform is supported for both ACPI and non-ACPI.
-		 */
-		if (is_f1a_m0h())
-			sock->mbinfo.msg_id_off	= SMN_HSMP_MSG_ID_F1A_M0H;
-		else
-			sock->mbinfo.msg_id_off	= SMN_HSMP_MSG_ID;
-
-		sock->mbinfo.msg_resp_off	= SMN_HSMP_MSG_RESP;
-		sock->mbinfo.msg_arg_off	= SMN_HSMP_MSG_DATA;
-		sema_init(&sock->hsmp_sem, 1);
-
-		/* Test the hsmp interface on each socket */
-		ret = hsmp_test(i, 0xDEADBEEF);
-		if (ret) {
-			dev_err(dev, "HSMP test message failed on Fam:%x model:%x\n",
-				boot_cpu_data.x86, boot_cpu_data.x86_model);
-			dev_err(dev, "Is HSMP disabled in BIOS ?\n");
-			return ret;
-		}
-		ret = hsmp_cache_proto_ver(i);
-		if (ret) {
-			dev_err(dev, "Failed to read HSMP protocol version\n");
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
-static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
-	{ACPI_HSMP_DEVICE_HID, 0},
-	{}
-};
-MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
-
-static bool check_acpi_support(struct device *dev)
-{
-	struct acpi_device *adev = ACPI_COMPANION(dev);
-
-	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
-		return true;
-
-	return false;
-}
-
-static int init_acpi(struct device *dev)
+int init_acpi(struct device *dev)
 {
 	u16 sock_ind;
 	int ret;
@@ -800,178 +655,3 @@ static int init_acpi(struct device *dev)
 
 	return ret;
 }
-
-static int hsmp_pltdrv_probe(struct platform_device *pdev)
-{
-	int ret;
-
-	/*
-	 * On ACPI supported BIOS, there is an ACPI HSMP device added for
-	 * each socket, so the per socket probing, but the memory allocated for
-	 * sockets should be contiguous to access it as an array,
-	 * Hence allocate memory for all the sockets at once instead of allocating
-	 * on each probe.
-	 */
-	if (!plat_dev.is_probed) {
-		plat_dev.sock = devm_kcalloc(&pdev->dev, plat_dev.num_sockets,
-					     sizeof(*plat_dev.sock),
-					     GFP_KERNEL);
-		if (!plat_dev.sock)
-			return -ENOMEM;
-	}
-	if (check_acpi_support(&pdev->dev)) {
-		ret = init_acpi(&pdev->dev);
-		if (ret) {
-			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
-			return ret;
-		}
-		ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
-		if (ret)
-			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
-	} else {
-		ret = init_platform_device(&pdev->dev);
-		if (ret) {
-			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
-			return ret;
-		}
-		ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
-		if (ret)
-			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
-	}
-
-	if (!plat_dev.is_probed) {
-		plat_dev.hsmp_device.name	= HSMP_CDEV_NAME;
-		plat_dev.hsmp_device.minor	= MISC_DYNAMIC_MINOR;
-		plat_dev.hsmp_device.fops	= &hsmp_fops;
-		plat_dev.hsmp_device.parent	= &pdev->dev;
-		plat_dev.hsmp_device.nodename	= HSMP_DEVNODE_NAME;
-		plat_dev.hsmp_device.mode	= 0644;
-
-		ret = misc_register(&plat_dev.hsmp_device);
-		if (ret)
-			return ret;
-
-		plat_dev.is_probed = true;
-	}
-
-	return 0;
-
-}
-
-static void hsmp_pltdrv_remove(struct platform_device *pdev)
-{
-	/*
-	 * We register only one misc_device even on multi socket system.
-	 * So, deregister should happen only once.
-	 */
-	if (plat_dev.is_probed) {
-		misc_deregister(&plat_dev.hsmp_device);
-		plat_dev.is_probed = false;
-	}
-}
-
-static struct platform_driver amd_hsmp_driver = {
-	.probe		= hsmp_pltdrv_probe,
-	.remove_new	= hsmp_pltdrv_remove,
-	.driver		= {
-		.name	= DRIVER_NAME,
-		.acpi_match_table = amd_hsmp_acpi_ids,
-	},
-};
-
-static struct platform_device *amd_hsmp_platdev;
-
-static int hsmp_plat_dev_register(void)
-{
-	int ret;
-
-	amd_hsmp_platdev = platform_device_alloc(DRIVER_NAME, PLATFORM_DEVID_NONE);
-	if (!amd_hsmp_platdev)
-		return -ENOMEM;
-
-	ret = platform_device_add(amd_hsmp_platdev);
-	if (ret)
-		platform_device_put(amd_hsmp_platdev);
-
-	return ret;
-}
-
-/*
- * This check is only needed for backward compatibility of previous platforms.
- * All new platforms are expected to support ACPI based probing.
- */
-static bool legacy_hsmp_support(void)
-{
-	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
-		return false;
-
-	switch (boot_cpu_data.x86) {
-	case 0x19:
-		switch (boot_cpu_data.x86_model) {
-		case 0x00 ... 0x1F:
-		case 0x30 ... 0x3F:
-		case 0x90 ... 0x9F:
-		case 0xA0 ... 0xAF:
-			return true;
-		default:
-			return false;
-		}
-	case 0x1A:
-		switch (boot_cpu_data.x86_model) {
-		case 0x00 ... 0x1F:
-			return true;
-		default:
-			return false;
-		}
-	default:
-		return false;
-	}
-
-	return false;
-}
-
-static int __init hsmp_plt_init(void)
-{
-	int ret = -ENODEV;
-
-	/*
-	 * amd_nb_num() returns number of SMN/DF interfaces present in the system
-	 * if we have N SMN/DF interfaces that ideally means N sockets
-	 */
-	plat_dev.num_sockets = amd_nb_num();
-	if (plat_dev.num_sockets == 0 || plat_dev.num_sockets > MAX_AMD_SOCKETS)
-		return ret;
-
-	ret = platform_driver_register(&amd_hsmp_driver);
-	if (ret)
-		return ret;
-
-	if (!plat_dev.is_acpi_device) {
-		if (legacy_hsmp_support()) {
-			/* Not ACPI device, but supports HSMP, register a plat_dev */
-			ret = hsmp_plat_dev_register();
-		} else {
-			/* Not ACPI, Does not support HSMP */
-			pr_info("HSMP is not supported on Family:%x model:%x\n",
-				boot_cpu_data.x86, boot_cpu_data.x86_model);
-			ret = -ENODEV;
-		}
-		if (ret)
-			platform_driver_unregister(&amd_hsmp_driver);
-	}
-
-	return ret;
-}
-
-static void __exit hsmp_plt_exit(void)
-{
-	platform_device_unregister(amd_hsmp_platdev);
-	platform_driver_unregister(&amd_hsmp_driver);
-}
-
-device_initcall(hsmp_plt_init);
-module_exit(hsmp_plt_exit);
-
-MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver");
-MODULE_VERSION(DRIVER_VERSION);
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
index 5afc7167fac1..1aa33c5633d0 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.h
+++ b/drivers/platform/x86/amd/hsmp/hsmp.h
@@ -51,4 +51,21 @@ struct hsmp_plat_device {
 	bool is_acpi_device;
 	bool is_probed;
 };
+
+extern struct hsmp_plat_device plat_dev;
+
+int init_acpi(struct device *dev);
+ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
+			     struct bin_attribute *bin_attr, char *buf,
+			     loff_t off, size_t count);
+int hsmp_create_acpi_sysfs_if(struct device *dev);
+int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
+		      u32 *value, bool write);
+int hsmp_cache_proto_ver(u16 sock_ind);
+long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
+umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
+				  struct bin_attribute *battr, int id);
+int hsmp_create_attr_list(struct attribute_group *attr_grp,
+			  struct device *dev, u16 sock_ind);
+int hsmp_test(u16 sock_ind, u32 value);
 #endif /* HSMP_H */
diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
new file mode 100644
index 000000000000..2ed5a9452244
--- /dev/null
+++ b/drivers/platform/x86/amd/hsmp/plat.c
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD HSMP Platform Driver
+ * Copyright (c) 2024, AMD.
+ * All Rights Reserved.
+ *
+ * This file provides platform device implementations.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include "hsmp.h"
+
+#include <asm/amd_nb.h>
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+
+#define DRIVER_NAME		"amd_hsmp"
+#define DRIVER_VERSION		"2.2"
+#define ACPI_HSMP_DEVICE_HID	"AMDI0097"
+
+/*
+ * To access specific HSMP mailbox register, s/w writes the SMN address of HSMP mailbox
+ * register into the SMN_INDEX register, and reads/writes the SMN_DATA reg.
+ * Below are required SMN address for HSMP Mailbox register offsets in SMU address space
+ */
+#define SMN_HSMP_BASE		0x3B00000
+#define SMN_HSMP_MSG_ID		0x0010534
+#define SMN_HSMP_MSG_ID_F1A_M0H	0x0010934
+#define SMN_HSMP_MSG_RESP	0x0010980
+#define SMN_HSMP_MSG_DATA	0x00109E0
+
+#define HSMP_INDEX_REG		0xc4
+#define HSMP_DATA_REG		0xc8
+
+int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
+		      u32 *value, bool write)
+{
+	int ret;
+
+	if (!sock->root)
+		return -ENODEV;
+
+	ret = pci_write_config_dword(sock->root, HSMP_INDEX_REG,
+				     sock->mbinfo.base_addr + offset);
+	if (ret)
+		return ret;
+
+	ret = (write ? pci_write_config_dword(sock->root, HSMP_DATA_REG, *value)
+		     : pci_read_config_dword(sock->root, HSMP_DATA_REG, value));
+
+	return ret;
+}
+
+static const struct file_operations hsmp_fops = {
+	.owner		= THIS_MODULE,
+	.unlocked_ioctl	= hsmp_ioctl,
+	.compat_ioctl	= hsmp_ioctl,
+};
+
+static int hsmp_create_non_acpi_sysfs_if(struct device *dev)
+{
+	const struct attribute_group **hsmp_attr_grps;
+	struct attribute_group *attr_grp;
+	u16 i;
+
+	hsmp_attr_grps = devm_kcalloc(dev, plat_dev.num_sockets + 1,
+				      sizeof(*hsmp_attr_grps),
+				      GFP_KERNEL);
+	if (!hsmp_attr_grps)
+		return -ENOMEM;
+
+	/* Create a sysfs directory for each socket */
+	for (i = 0; i < plat_dev.num_sockets; i++) {
+		attr_grp = devm_kzalloc(dev, sizeof(struct attribute_group),
+					GFP_KERNEL);
+		if (!attr_grp)
+			return -ENOMEM;
+
+		snprintf(plat_dev.sock[i].name, HSMP_ATTR_GRP_NAME_SIZE, "socket%u", (u8)i);
+		attr_grp->name			= plat_dev.sock[i].name;
+		attr_grp->is_bin_visible	= hsmp_is_sock_attr_visible;
+		hsmp_attr_grps[i]		= attr_grp;
+
+		hsmp_create_attr_list(attr_grp, dev, i);
+	}
+
+	return device_add_groups(dev, hsmp_attr_grps);
+}
+
+static inline bool is_f1a_m0h(void)
+{
+	if (boot_cpu_data.x86 == 0x1A && boot_cpu_data.x86_model <= 0x0F)
+		return true;
+
+	return false;
+}
+
+static int init_platform_device(struct device *dev)
+{
+	struct hsmp_socket *sock;
+	int ret, i;
+
+	for (i = 0; i < plat_dev.num_sockets; i++) {
+		if (!node_to_amd_nb(i))
+			return -ENODEV;
+		sock = &plat_dev.sock[i];
+		sock->root			= node_to_amd_nb(i)->root;
+		sock->sock_ind			= i;
+		sock->dev			= dev;
+		sock->mbinfo.base_addr		= SMN_HSMP_BASE;
+
+		/*
+		 * This is a transitional change from non-ACPI to ACPI, only
+		 * family 0x1A, model 0x00 platform is supported for both ACPI and non-ACPI.
+		 */
+		if (is_f1a_m0h())
+			sock->mbinfo.msg_id_off	= SMN_HSMP_MSG_ID_F1A_M0H;
+		else
+			sock->mbinfo.msg_id_off	= SMN_HSMP_MSG_ID;
+
+		sock->mbinfo.msg_resp_off	= SMN_HSMP_MSG_RESP;
+		sock->mbinfo.msg_arg_off	= SMN_HSMP_MSG_DATA;
+		sema_init(&sock->hsmp_sem, 1);
+
+		/* Test the hsmp interface on each socket */
+		ret = hsmp_test(i, 0xDEADBEEF);
+		if (ret) {
+			dev_err(dev, "HSMP test message failed on Fam:%x model:%x\n",
+				boot_cpu_data.x86, boot_cpu_data.x86_model);
+			dev_err(dev, "Is HSMP disabled in BIOS ?\n");
+			return ret;
+		}
+
+		ret = hsmp_cache_proto_ver(i);
+		if (ret) {
+			dev_err(dev, "Failed to read HSMP protocol version\n");
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
+	{ACPI_HSMP_DEVICE_HID, 0},
+	{}
+};
+MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
+
+static bool check_acpi_support(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
+		return true;
+
+	return false;
+}
+
+static int hsmp_pltdrv_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	/*
+	 * On ACPI supported BIOS, there is an ACPI HSMP device added for
+	 * each socket, so the per socket probing, but the memory allocated for
+	 * sockets should be contiguous to access it as an array,
+	 * Hence allocate memory for all the sockets at once instead of allocating
+	 * on each probe.
+	 */
+	if (!plat_dev.is_probed) {
+		plat_dev.sock = devm_kcalloc(&pdev->dev, plat_dev.num_sockets,
+					     sizeof(*plat_dev.sock),
+					     GFP_KERNEL);
+		if (!plat_dev.sock)
+			return -ENOMEM;
+	}
+
+	if (check_acpi_support(&pdev->dev)) {
+		ret = init_acpi(&pdev->dev);
+		if (ret) {
+			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
+			return ret;
+		}
+		ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
+		if (ret)
+			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
+	} else {
+		ret = init_platform_device(&pdev->dev);
+		if (ret) {
+			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
+			return ret;
+		}
+		ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
+		if (ret)
+			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
+	}
+
+	if (!plat_dev.is_probed) {
+		plat_dev.hsmp_device.name	= HSMP_CDEV_NAME;
+		plat_dev.hsmp_device.minor	= MISC_DYNAMIC_MINOR;
+		plat_dev.hsmp_device.fops	= &hsmp_fops;
+		plat_dev.hsmp_device.parent	= &pdev->dev;
+		plat_dev.hsmp_device.nodename	= HSMP_DEVNODE_NAME;
+		plat_dev.hsmp_device.mode	= 0644;
+
+		ret = misc_register(&plat_dev.hsmp_device);
+		if (ret)
+			return ret;
+
+		plat_dev.is_probed = true;
+	}
+
+	return 0;
+}
+
+static void hsmp_pltdrv_remove(struct platform_device *pdev)
+{
+	/*
+	 * We register only one misc_device even on multi socket system.
+	 * So, deregister should happen only once.
+	 */
+	if (plat_dev.is_probed) {
+		misc_deregister(&plat_dev.hsmp_device);
+		plat_dev.is_probed = false;
+	}
+}
+
+static struct platform_driver amd_hsmp_driver = {
+	.probe		= hsmp_pltdrv_probe,
+	.remove_new	= hsmp_pltdrv_remove,
+	.driver		= {
+		.name	= DRIVER_NAME,
+		.acpi_match_table = amd_hsmp_acpi_ids,
+	},
+};
+
+static struct platform_device *amd_hsmp_platdev;
+
+static int hsmp_plat_dev_register(void)
+{
+	int ret;
+
+	amd_hsmp_platdev = platform_device_alloc(DRIVER_NAME, PLATFORM_DEVID_NONE);
+	if (!amd_hsmp_platdev)
+		return -ENOMEM;
+
+	ret = platform_device_add(amd_hsmp_platdev);
+	if (ret)
+		platform_device_put(amd_hsmp_platdev);
+
+	return ret;
+}
+
+/*
+ * This check is only needed for backward compatibility of previous platforms.
+ * All new platforms are expected to support ACPI based probing.
+ */
+static bool legacy_hsmp_support(void)
+{
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+		return false;
+
+	switch (boot_cpu_data.x86) {
+	case 0x19:
+		switch (boot_cpu_data.x86_model) {
+		case 0x00 ... 0x1F:
+		case 0x30 ... 0x3F:
+		case 0x90 ... 0x9F:
+		case 0xA0 ... 0xAF:
+			return true;
+		default:
+			return false;
+		}
+	case 0x1A:
+		switch (boot_cpu_data.x86_model) {
+		case 0x00 ... 0x1F:
+			return true;
+		default:
+			return false;
+		}
+	default:
+		return false;
+	}
+
+	return false;
+}
+
+static int __init hsmp_plt_init(void)
+{
+	int ret = -ENODEV;
+
+	/*
+	 * amd_nb_num() returns number of SMN/DF interfaces present in the system
+	 * if we have N SMN/DF interfaces that ideally means N sockets
+	 */
+	plat_dev.num_sockets = amd_nb_num();
+	if (plat_dev.num_sockets == 0 || plat_dev.num_sockets > MAX_AMD_SOCKETS)
+		return ret;
+
+	ret = platform_driver_register(&amd_hsmp_driver);
+	if (ret)
+		return ret;
+
+	if (!plat_dev.is_acpi_device) {
+		if (legacy_hsmp_support()) {
+			/* Not ACPI device, but supports HSMP, register a plat_dev */
+			ret = hsmp_plat_dev_register();
+		} else {
+			/* Not ACPI, Does not support HSMP */
+			pr_info("HSMP is not supported on Family:%x model:%x\n",
+				boot_cpu_data.x86, boot_cpu_data.x86_model);
+			ret = -ENODEV;
+		}
+		if (ret)
+			platform_driver_unregister(&amd_hsmp_driver);
+	}
+
+	return ret;
+}
+
+static void __exit hsmp_plt_exit(void)
+{
+	platform_device_unregister(amd_hsmp_platdev);
+	platform_driver_unregister(&amd_hsmp_driver);
+}
+
+device_initcall(hsmp_plt_init);
+module_exit(hsmp_plt_exit);
+
+MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver");
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL v2");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [v3 05/11] platform/x86/amd/hsmp: Move ACPI code to acpi.c
  2024-07-20 17:45 [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Suma Hegde
                   ` (2 preceding siblings ...)
  2024-07-20 17:45 ` [v3 04/11] platform/x86/amd/hsmp: Move platform device specific code to plat.c Suma Hegde
@ 2024-07-20 17:45 ` Suma Hegde
  2024-07-20 17:45 ` [v3 06/11] platform/x86/amd/hsmp: Change generic plat_dev name to hsmp_pdev Suma Hegde
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Suma Hegde @ 2024-07-20 17:45 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, hdegoede, Suma Hegde, Naveen Krishna Chatradhi

Move ACPI related code to acpi.c from hsmp.c.
We still have one driver, the driver probe will be split in the next patch.

Signed-off-by: Suma Hegde <suma.hegde@amd.com>
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
---
Changes since v2:
None
Changes since v1:
1. Add following headers in acpi.c
	#include <linux/device.h>
	#include <linux/dev_printk.h>
	#include <linux/ioport.h>
	#include <linux/kstrtox.h>
	#include <linux/uuid.h>
	#include <uapi/asm-generic/errno-base.h>

 drivers/platform/x86/amd/hsmp/Makefile |   2 +-
 drivers/platform/x86/amd/hsmp/acpi.c   | 268 +++++++++++++++++++++++++
 drivers/platform/x86/amd/hsmp/hsmp.c   | 247 -----------------------
 drivers/platform/x86/amd/hsmp/hsmp.h   |   2 +
 4 files changed, 271 insertions(+), 248 deletions(-)
 create mode 100644 drivers/platform/x86/amd/hsmp/acpi.c

diff --git a/drivers/platform/x86/amd/hsmp/Makefile b/drivers/platform/x86/amd/hsmp/Makefile
index fb8ba04b2f0d..0cc92865c0a2 100644
--- a/drivers/platform/x86/amd/hsmp/Makefile
+++ b/drivers/platform/x86/amd/hsmp/Makefile
@@ -5,4 +5,4 @@
 #
 
 obj-$(CONFIG_AMD_HSMP)		+= amd_hsmp.o
-amd_hsmp-objs			:= hsmp.o plat.o
+amd_hsmp-objs			:= hsmp.o plat.o acpi.o
diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c
new file mode 100644
index 000000000000..eca324774141
--- /dev/null
+++ b/drivers/platform/x86/amd/hsmp/acpi.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD HSMP Platform Driver
+ * Copyright (c) 2024, AMD.
+ * All Rights Reserved.
+ *
+ * This file provides a device implementation for HSMP interface
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include "hsmp.h"
+
+#include <linux/acpi.h>
+#include <linux/device.h>
+#include <linux/dev_printk.h>
+#include <linux/ioport.h>
+#include <linux/kstrtox.h>
+#include <linux/uuid.h>
+
+#include <uapi/asm-generic/errno-base.h>
+
+/* These are the strings specified in ACPI table */
+#define MSG_IDOFF_STR		"MsgIdOffset"
+#define MSG_ARGOFF_STR		"MsgArgOffset"
+#define MSG_RESPOFF_STR		"MsgRspOffset"
+
+void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
+			u32 *value, bool write)
+{
+	if (write)
+		iowrite32(*value, sock->virt_base_addr + offset);
+	else
+		*value = ioread32(sock->virt_base_addr + offset);
+}
+
+/* This is the UUID used for HSMP */
+static const guid_t acpi_hsmp_uuid = GUID_INIT(0xb74d619d, 0x5707, 0x48bd,
+						0xa6, 0x9f, 0x4e, 0xa2,
+						0x87, 0x1f, 0xc2, 0xf6);
+
+static inline bool is_acpi_hsmp_uuid(union acpi_object *obj)
+{
+	if (obj->type == ACPI_TYPE_BUFFER && obj->buffer.length == UUID_SIZE)
+		return guid_equal((guid_t *)obj->buffer.pointer, &acpi_hsmp_uuid);
+
+	return false;
+}
+
+static inline int hsmp_get_uid(struct device *dev, u16 *sock_ind)
+{
+	char *uid;
+
+	/*
+	 * UID (ID00, ID01..IDXX) is used for differentiating sockets,
+	 * read it and strip the "ID" part of it and convert the remaining
+	 * bytes to integer.
+	 */
+	uid = acpi_device_uid(ACPI_COMPANION(dev));
+
+	return kstrtou16(uid + 2, 10, sock_ind);
+}
+
+static acpi_status hsmp_resource(struct acpi_resource *res, void *data)
+{
+	struct hsmp_socket *sock = data;
+	struct resource r;
+
+	switch (res->type) {
+	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+		if (!acpi_dev_resource_memory(res, &r))
+			return AE_ERROR;
+		if (!r.start || r.end < r.start || !(r.flags & IORESOURCE_MEM_WRITEABLE))
+			return AE_ERROR;
+		sock->mbinfo.base_addr = r.start;
+		sock->mbinfo.size = resource_size(&r);
+		break;
+	case ACPI_RESOURCE_TYPE_END_TAG:
+		break;
+	default:
+		return AE_ERROR;
+	}
+
+	return AE_OK;
+}
+
+static int hsmp_read_acpi_dsd(struct hsmp_socket *sock)
+{
+	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *guid, *mailbox_package;
+	union acpi_object *dsd;
+	acpi_status status;
+	int ret = 0;
+	int j;
+
+	status = acpi_evaluate_object_typed(ACPI_HANDLE(sock->dev), "_DSD", NULL,
+					    &buf, ACPI_TYPE_PACKAGE);
+	if (ACPI_FAILURE(status)) {
+		dev_err(sock->dev, "Failed to read mailbox reg offsets from DSD table, err: %s\n",
+			acpi_format_exception(status));
+		return -ENODEV;
+	}
+
+	dsd = buf.pointer;
+
+	/* HSMP _DSD property should contain 2 objects.
+	 * 1. guid which is an acpi object of type ACPI_TYPE_BUFFER
+	 * 2. mailbox which is an acpi object of type ACPI_TYPE_PACKAGE
+	 *    This mailbox object contains 3 more acpi objects of type
+	 *    ACPI_TYPE_PACKAGE for holding msgid, msgresp, msgarg offsets
+	 *    these packages inturn contain 2 acpi objects of type
+	 *    ACPI_TYPE_STRING and ACPI_TYPE_INTEGER
+	 */
+	if (!dsd || dsd->type != ACPI_TYPE_PACKAGE || dsd->package.count != 2) {
+		ret = -EINVAL;
+		goto free_buf;
+	}
+
+	guid = &dsd->package.elements[0];
+	mailbox_package = &dsd->package.elements[1];
+	if (!is_acpi_hsmp_uuid(guid) || mailbox_package->type != ACPI_TYPE_PACKAGE) {
+		dev_err(sock->dev, "Invalid hsmp _DSD table data\n");
+		ret = -EINVAL;
+		goto free_buf;
+	}
+
+	for (j = 0; j < mailbox_package->package.count; j++) {
+		union acpi_object *msgobj, *msgstr, *msgint;
+
+		msgobj	= &mailbox_package->package.elements[j];
+		msgstr	= &msgobj->package.elements[0];
+		msgint	= &msgobj->package.elements[1];
+
+		/* package should have 1 string and 1 integer object */
+		if (msgobj->type != ACPI_TYPE_PACKAGE ||
+		    msgstr->type != ACPI_TYPE_STRING ||
+		    msgint->type != ACPI_TYPE_INTEGER) {
+			ret = -EINVAL;
+			goto free_buf;
+		}
+
+		if (!strncmp(msgstr->string.pointer, MSG_IDOFF_STR,
+			     msgstr->string.length)) {
+			sock->mbinfo.msg_id_off = msgint->integer.value;
+		} else if (!strncmp(msgstr->string.pointer, MSG_RESPOFF_STR,
+				    msgstr->string.length)) {
+			sock->mbinfo.msg_resp_off =  msgint->integer.value;
+		} else if (!strncmp(msgstr->string.pointer, MSG_ARGOFF_STR,
+				    msgstr->string.length)) {
+			sock->mbinfo.msg_arg_off = msgint->integer.value;
+		} else {
+			ret = -ENOENT;
+			goto free_buf;
+		}
+	}
+
+	if (!sock->mbinfo.msg_id_off || !sock->mbinfo.msg_resp_off ||
+	    !sock->mbinfo.msg_arg_off)
+		ret = -EINVAL;
+
+free_buf:
+	ACPI_FREE(buf.pointer);
+	return ret;
+}
+
+static int hsmp_read_acpi_crs(struct hsmp_socket *sock)
+{
+	acpi_status status;
+
+	status = acpi_walk_resources(ACPI_HANDLE(sock->dev), METHOD_NAME__CRS,
+				     hsmp_resource, sock);
+	if (ACPI_FAILURE(status)) {
+		dev_err(sock->dev, "Failed to look up MP1 base address from CRS method, err: %s\n",
+			acpi_format_exception(status));
+		return -EINVAL;
+	}
+	if (!sock->mbinfo.base_addr || !sock->mbinfo.size)
+		return -EINVAL;
+
+	/* The mapped region should be un-cached */
+	sock->virt_base_addr = devm_ioremap_uc(sock->dev, sock->mbinfo.base_addr,
+					       sock->mbinfo.size);
+	if (!sock->virt_base_addr) {
+		dev_err(sock->dev, "Failed to ioremap MP1 base address\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/* Parse the ACPI table to read the data */
+static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
+{
+	struct hsmp_socket *sock = &plat_dev.sock[sock_ind];
+	int ret;
+
+	sock->sock_ind		= sock_ind;
+	sock->dev		= dev;
+	plat_dev.is_acpi_device	= true;
+
+	sema_init(&sock->hsmp_sem, 1);
+
+	/* Read MP1 base address from CRS method */
+	ret = hsmp_read_acpi_crs(sock);
+	if (ret)
+		return ret;
+
+	/* Read mailbox offsets from DSD table */
+	return hsmp_read_acpi_dsd(sock);
+}
+
+int hsmp_create_acpi_sysfs_if(struct device *dev)
+{
+	struct attribute_group *attr_grp;
+	u16 sock_ind;
+	int ret;
+
+	attr_grp = devm_kzalloc(dev, sizeof(struct attribute_group), GFP_KERNEL);
+	if (!attr_grp)
+		return -ENOMEM;
+
+	attr_grp->is_bin_visible = hsmp_is_sock_attr_visible;
+
+	ret = hsmp_get_uid(dev, &sock_ind);
+	if (ret)
+		return ret;
+
+	ret = hsmp_create_attr_list(attr_grp, dev, sock_ind);
+	if (ret)
+		return ret;
+
+	return devm_device_add_group(dev, attr_grp);
+}
+
+int init_acpi(struct device *dev)
+{
+	u16 sock_ind;
+	int ret;
+
+	ret = hsmp_get_uid(dev, &sock_ind);
+	if (ret)
+		return ret;
+	if (sock_ind >= plat_dev.num_sockets)
+		return -EINVAL;
+
+	ret = hsmp_parse_acpi_table(dev, sock_ind);
+	if (ret) {
+		dev_err(dev, "Failed to parse ACPI table\n");
+		return ret;
+	}
+
+	/* Test the hsmp interface */
+	ret = hsmp_test(sock_ind, 0xDEADBEEF);
+	if (ret) {
+		dev_err(dev, "HSMP test message failed on Fam:%x model:%x\n",
+			boot_cpu_data.x86, boot_cpu_data.x86_model);
+		dev_err(dev, "Is HSMP disabled in BIOS ?\n");
+		return ret;
+	}
+
+	ret = hsmp_cache_proto_ver(sock_ind);
+	if (ret) {
+		dev_err(dev, "Failed to read HSMP protocol version\n");
+		return ret;
+	}
+
+	return ret;
+}
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
index d15a978ff71e..8473c2d1258b 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.c
+++ b/drivers/platform/x86/amd/hsmp/hsmp.c
@@ -29,22 +29,8 @@
 #define HSMP_WR			true
 #define HSMP_RD			false
 
-/* These are the strings specified in ACPI table */
-#define MSG_IDOFF_STR		"MsgIdOffset"
-#define MSG_ARGOFF_STR		"MsgArgOffset"
-#define MSG_RESPOFF_STR		"MsgRspOffset"
-
 struct hsmp_plat_device plat_dev;
 
-static void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
-			       u32 *value, bool write)
-{
-	if (write)
-		iowrite32(*value, sock->virt_base_addr + offset);
-	else
-		*value = ioread32(sock->virt_base_addr + offset);
-}
-
 static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 offset,
 			 u32 *value, bool write)
 {
@@ -299,181 +285,6 @@ long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 	return 0;
 }
 
-/* This is the UUID used for HSMP */
-static const guid_t acpi_hsmp_uuid = GUID_INIT(0xb74d619d, 0x5707, 0x48bd,
-						0xa6, 0x9f, 0x4e, 0xa2,
-						0x87, 0x1f, 0xc2, 0xf6);
-
-static inline bool is_acpi_hsmp_uuid(union acpi_object *obj)
-{
-	if (obj->type == ACPI_TYPE_BUFFER && obj->buffer.length == UUID_SIZE)
-		return guid_equal((guid_t *)obj->buffer.pointer, &acpi_hsmp_uuid);
-
-	return false;
-}
-
-static inline int hsmp_get_uid(struct device *dev, u16 *sock_ind)
-{
-	char *uid;
-
-	/*
-	 * UID (ID00, ID01..IDXX) is used for differentiating sockets,
-	 * read it and strip the "ID" part of it and convert the remaining
-	 * bytes to integer.
-	 */
-	uid = acpi_device_uid(ACPI_COMPANION(dev));
-
-	return kstrtou16(uid + 2, 10, sock_ind);
-}
-
-static acpi_status hsmp_resource(struct acpi_resource *res, void *data)
-{
-	struct hsmp_socket *sock = data;
-	struct resource r;
-
-	switch (res->type) {
-	case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
-		if (!acpi_dev_resource_memory(res, &r))
-			return AE_ERROR;
-		if (!r.start || r.end < r.start || !(r.flags & IORESOURCE_MEM_WRITEABLE))
-			return AE_ERROR;
-		sock->mbinfo.base_addr = r.start;
-		sock->mbinfo.size = resource_size(&r);
-		break;
-	case ACPI_RESOURCE_TYPE_END_TAG:
-		break;
-	default:
-		return AE_ERROR;
-	}
-
-	return AE_OK;
-}
-
-static int hsmp_read_acpi_dsd(struct hsmp_socket *sock)
-{
-	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL };
-	union acpi_object *guid, *mailbox_package;
-	union acpi_object *dsd;
-	acpi_status status;
-	int ret = 0;
-	int j;
-
-	status = acpi_evaluate_object_typed(ACPI_HANDLE(sock->dev), "_DSD", NULL,
-					    &buf, ACPI_TYPE_PACKAGE);
-	if (ACPI_FAILURE(status)) {
-		dev_err(sock->dev, "Failed to read mailbox reg offsets from DSD table, err: %s\n",
-			acpi_format_exception(status));
-		return -ENODEV;
-	}
-
-	dsd = buf.pointer;
-
-	/* HSMP _DSD property should contain 2 objects.
-	 * 1. guid which is an acpi object of type ACPI_TYPE_BUFFER
-	 * 2. mailbox which is an acpi object of type ACPI_TYPE_PACKAGE
-	 *    This mailbox object contains 3 more acpi objects of type
-	 *    ACPI_TYPE_PACKAGE for holding msgid, msgresp, msgarg offsets
-	 *    these packages inturn contain 2 acpi objects of type
-	 *    ACPI_TYPE_STRING and ACPI_TYPE_INTEGER
-	 */
-	if (!dsd || dsd->type != ACPI_TYPE_PACKAGE || dsd->package.count != 2) {
-		ret = -EINVAL;
-		goto free_buf;
-	}
-
-	guid = &dsd->package.elements[0];
-	mailbox_package = &dsd->package.elements[1];
-	if (!is_acpi_hsmp_uuid(guid) || mailbox_package->type != ACPI_TYPE_PACKAGE) {
-		dev_err(sock->dev, "Invalid hsmp _DSD table data\n");
-		ret = -EINVAL;
-		goto free_buf;
-	}
-
-	for (j = 0; j < mailbox_package->package.count; j++) {
-		union acpi_object *msgobj, *msgstr, *msgint;
-
-		msgobj	= &mailbox_package->package.elements[j];
-		msgstr	= &msgobj->package.elements[0];
-		msgint	= &msgobj->package.elements[1];
-
-		/* package should have 1 string and 1 integer object */
-		if (msgobj->type != ACPI_TYPE_PACKAGE ||
-		    msgstr->type != ACPI_TYPE_STRING ||
-		    msgint->type != ACPI_TYPE_INTEGER) {
-			ret = -EINVAL;
-			goto free_buf;
-		}
-
-		if (!strncmp(msgstr->string.pointer, MSG_IDOFF_STR,
-			     msgstr->string.length)) {
-			sock->mbinfo.msg_id_off = msgint->integer.value;
-		} else if (!strncmp(msgstr->string.pointer, MSG_RESPOFF_STR,
-				    msgstr->string.length)) {
-			sock->mbinfo.msg_resp_off =  msgint->integer.value;
-		} else if (!strncmp(msgstr->string.pointer, MSG_ARGOFF_STR,
-				    msgstr->string.length)) {
-			sock->mbinfo.msg_arg_off = msgint->integer.value;
-		} else {
-			ret = -ENOENT;
-			goto free_buf;
-		}
-	}
-
-	if (!sock->mbinfo.msg_id_off || !sock->mbinfo.msg_resp_off ||
-	    !sock->mbinfo.msg_arg_off)
-		ret = -EINVAL;
-
-free_buf:
-	ACPI_FREE(buf.pointer);
-	return ret;
-}
-
-static int hsmp_read_acpi_crs(struct hsmp_socket *sock)
-{
-	acpi_status status;
-
-	status = acpi_walk_resources(ACPI_HANDLE(sock->dev), METHOD_NAME__CRS,
-				     hsmp_resource, sock);
-	if (ACPI_FAILURE(status)) {
-		dev_err(sock->dev, "Failed to look up MP1 base address from CRS method, err: %s\n",
-			acpi_format_exception(status));
-		return -EINVAL;
-	}
-	if (!sock->mbinfo.base_addr || !sock->mbinfo.size)
-		return -EINVAL;
-
-	/* The mapped region should be un cached */
-	sock->virt_base_addr = devm_ioremap_uc(sock->dev, sock->mbinfo.base_addr,
-					       sock->mbinfo.size);
-	if (!sock->virt_base_addr) {
-		dev_err(sock->dev, "Failed to ioremap MP1 base address\n");
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
-/* Parse the ACPI table to read the data */
-static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
-{
-	struct hsmp_socket *sock = &plat_dev.sock[sock_ind];
-	int ret;
-
-	sock->sock_ind		= sock_ind;
-	sock->dev		= dev;
-	plat_dev.is_acpi_device	= true;
-
-	sema_init(&sock->hsmp_sem, 1);
-
-	/* Read MP1 base address from CRS method */
-	ret = hsmp_read_acpi_crs(sock);
-	if (ret)
-		return ret;
-
-	/* Read mailbox offsets from DSD table */
-	return hsmp_read_acpi_dsd(sock);
-}
-
 ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
 			     struct bin_attribute *bin_attr, char *buf,
 			     loff_t off, size_t count)
@@ -582,29 +393,6 @@ int hsmp_create_attr_list(struct attribute_group *attr_grp,
 	return hsmp_init_metric_tbl_bin_attr(hsmp_bin_attrs, sock_ind);
 }
 
-int hsmp_create_acpi_sysfs_if(struct device *dev)
-{
-	struct attribute_group *attr_grp;
-	u16 sock_ind;
-	int ret;
-
-	attr_grp = devm_kzalloc(dev, sizeof(struct attribute_group), GFP_KERNEL);
-	if (!attr_grp)
-		return -ENOMEM;
-
-	attr_grp->is_bin_visible = hsmp_is_sock_attr_visible;
-
-	ret = hsmp_get_uid(dev, &sock_ind);
-	if (ret)
-		return ret;
-
-	ret = hsmp_create_attr_list(attr_grp, dev, sock_ind);
-	if (ret)
-		return ret;
-
-	return devm_device_add_group(dev, attr_grp);
-}
-
 int hsmp_cache_proto_ver(u16 sock_ind)
 {
 	struct hsmp_message msg = { 0 };
@@ -620,38 +408,3 @@ int hsmp_cache_proto_ver(u16 sock_ind)
 
 	return ret;
 }
-
-int init_acpi(struct device *dev)
-{
-	u16 sock_ind;
-	int ret;
-
-	ret = hsmp_get_uid(dev, &sock_ind);
-	if (ret)
-		return ret;
-	if (sock_ind >= plat_dev.num_sockets)
-		return -EINVAL;
-
-	ret = hsmp_parse_acpi_table(dev, sock_ind);
-	if (ret) {
-		dev_err(dev, "Failed to parse ACPI table\n");
-		return ret;
-	}
-
-	/* Test the hsmp interface */
-	ret = hsmp_test(sock_ind, 0xDEADBEEF);
-	if (ret) {
-		dev_err(dev, "HSMP test message failed on Fam:%x model:%x\n",
-			boot_cpu_data.x86, boot_cpu_data.x86_model);
-		dev_err(dev, "Is HSMP disabled in BIOS ?\n");
-		return ret;
-	}
-
-	ret = hsmp_cache_proto_ver(sock_ind);
-	if (ret) {
-		dev_err(dev, "Failed to read HSMP protocol version\n");
-		return ret;
-	}
-
-	return ret;
-}
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
index 1aa33c5633d0..1ff652dc0ef0 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.h
+++ b/drivers/platform/x86/amd/hsmp/hsmp.h
@@ -68,4 +68,6 @@ umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
 int hsmp_create_attr_list(struct attribute_group *attr_grp,
 			  struct device *dev, u16 sock_ind);
 int hsmp_test(u16 sock_ind, u32 value);
+void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
+			u32 *value, bool write);
 #endif /* HSMP_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [v3 06/11] platform/x86/amd/hsmp: Change generic plat_dev name to hsmp_pdev
  2024-07-20 17:45 [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Suma Hegde
                   ` (3 preceding siblings ...)
  2024-07-20 17:45 ` [v3 05/11] platform/x86/amd/hsmp: Move ACPI code to acpi.c Suma Hegde
@ 2024-07-20 17:45 ` Suma Hegde
  2024-08-07 12:31   ` Ilpo Järvinen
  2024-07-20 17:45 ` [v3 07/11] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers Suma Hegde
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Suma Hegde @ 2024-07-20 17:45 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, hdegoede, Suma Hegde, Naveen Krishna Chatradhi

plat_dev is a commonly used variable name, since its made as extern now,
change it to more specific name.
Also change miscdevice hsmp_device to mdev.

Signed-off-by: Suma Hegde <suma.hegde@amd.com>
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
---
Changes since v2:
None
Changes since v1:
1. This is a new patch to rename generic name "plat_dev"
   in hsmp.h, hsmp.c, plat.c and acpi.c to more specific name "hsmp_pdev"
2. Rename miscdevice hsmp_device to mdev.

 drivers/platform/x86/amd/hsmp/acpi.c | 10 +++---
 drivers/platform/x86/amd/hsmp/hsmp.c | 22 ++++++------
 drivers/platform/x86/amd/hsmp/hsmp.h |  4 +--
 drivers/platform/x86/amd/hsmp/plat.c | 52 ++++++++++++++--------------
 4 files changed, 44 insertions(+), 44 deletions(-)

diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c
index eca324774141..46cb86d5d550 100644
--- a/drivers/platform/x86/amd/hsmp/acpi.c
+++ b/drivers/platform/x86/amd/hsmp/acpi.c
@@ -191,12 +191,12 @@ static int hsmp_read_acpi_crs(struct hsmp_socket *sock)
 /* Parse the ACPI table to read the data */
 static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
 {
-	struct hsmp_socket *sock = &plat_dev.sock[sock_ind];
+	struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
 	int ret;
 
-	sock->sock_ind		= sock_ind;
-	sock->dev		= dev;
-	plat_dev.is_acpi_device	= true;
+	sock->sock_ind			= sock_ind;
+	sock->dev			= dev;
+	hsmp_pdev.is_acpi_device	= true;
 
 	sema_init(&sock->hsmp_sem, 1);
 
@@ -240,7 +240,7 @@ int init_acpi(struct device *dev)
 	ret = hsmp_get_uid(dev, &sock_ind);
 	if (ret)
 		return ret;
-	if (sock_ind >= plat_dev.num_sockets)
+	if (sock_ind >= hsmp_pdev.num_sockets)
 		return -EINVAL;
 
 	ret = hsmp_parse_acpi_table(dev, sock_ind);
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
index 8473c2d1258b..14edaace4379 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.c
+++ b/drivers/platform/x86/amd/hsmp/hsmp.c
@@ -29,12 +29,12 @@
 #define HSMP_WR			true
 #define HSMP_RD			false
 
-struct hsmp_plat_device plat_dev;
+struct hsmp_plat_device hsmp_pdev;
 
 static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 offset,
 			 u32 *value, bool write)
 {
-	if (plat_dev.is_acpi_device)
+	if (hsmp_pdev.is_acpi_device)
 		amd_hsmp_acpi_rdwr(sock, offset, value, write);
 	else
 		return amd_hsmp_pci_rdwr(sock, offset, value, write);
@@ -177,9 +177,9 @@ int hsmp_send_message(struct hsmp_message *msg)
 	if (ret)
 		return ret;
 
-	if (!plat_dev.sock || msg->sock_ind >= plat_dev.num_sockets)
+	if (!hsmp_pdev.sock || msg->sock_ind >= hsmp_pdev.num_sockets)
 		return -ENODEV;
-	sock = &plat_dev.sock[msg->sock_ind];
+	sock = &hsmp_pdev.sock[msg->sock_ind];
 
 	/*
 	 * The time taken by smu operation to complete is between
@@ -220,7 +220,7 @@ int hsmp_test(u16 sock_ind, u32 value)
 
 	/* Check the response value */
 	if (msg.args[0] != (value + 1)) {
-		dev_err(plat_dev.sock[sock_ind].dev,
+		dev_err(hsmp_pdev.sock[sock_ind].dev,
 			"Socket %d test message failed, Expected 0x%08X, received 0x%08X\n",
 			sock_ind, (value + 1), msg.args[0]);
 		return -EBADE;
@@ -315,7 +315,7 @@ ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
 
 static int hsmp_get_tbl_dram_base(u16 sock_ind)
 {
-	struct hsmp_socket *sock = &plat_dev.sock[sock_ind];
+	struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
 	struct hsmp_message msg = { 0 };
 	phys_addr_t dram_addr;
 	int ret;
@@ -349,7 +349,7 @@ static int hsmp_get_tbl_dram_base(u16 sock_ind)
 umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
 				  struct bin_attribute *battr, int id)
 {
-	if (plat_dev.proto_ver == HSMP_PROTO_VER6)
+	if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6)
 		return battr->attr.mode;
 	else
 		return 0;
@@ -357,17 +357,17 @@ umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
 
 static int hsmp_init_metric_tbl_bin_attr(struct bin_attribute **hattrs, u16 sock_ind)
 {
-	struct bin_attribute *hattr = &plat_dev.sock[sock_ind].hsmp_attr;
+	struct bin_attribute *hattr = &hsmp_pdev.sock[sock_ind].hsmp_attr;
 
 	sysfs_bin_attr_init(hattr);
 	hattr->attr.name	= HSMP_METRICS_TABLE_NAME;
 	hattr->attr.mode	= 0444;
 	hattr->read		= hsmp_metric_tbl_read;
 	hattr->size		= sizeof(struct hsmp_metric_table);
-	hattr->private		= &plat_dev.sock[sock_ind];
+	hattr->private		= &hsmp_pdev.sock[sock_ind];
 	hattrs[0]		= hattr;
 
-	if (plat_dev.proto_ver == HSMP_PROTO_VER6)
+	if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6)
 		return hsmp_get_tbl_dram_base(sock_ind);
 	else
 		return 0;
@@ -404,7 +404,7 @@ int hsmp_cache_proto_ver(u16 sock_ind)
 
 	ret = hsmp_send_message(&msg);
 	if (!ret)
-		plat_dev.proto_ver = msg.args[0];
+		hsmp_pdev.proto_ver = msg.args[0];
 
 	return ret;
 }
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
index 1ff652dc0ef0..a77887d298b6 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.h
+++ b/drivers/platform/x86/amd/hsmp/hsmp.h
@@ -44,7 +44,7 @@ struct hsmp_socket {
 };
 
 struct hsmp_plat_device {
-	struct miscdevice hsmp_device;
+	struct miscdevice mdev;
 	struct hsmp_socket *sock;
 	u32 proto_ver;
 	u16 num_sockets;
@@ -52,7 +52,7 @@ struct hsmp_plat_device {
 	bool is_probed;
 };
 
-extern struct hsmp_plat_device plat_dev;
+extern struct hsmp_plat_device hsmp_pdev;
 
 int init_acpi(struct device *dev);
 ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
index 2ed5a9452244..c297540bb64c 100644
--- a/drivers/platform/x86/amd/hsmp/plat.c
+++ b/drivers/platform/x86/amd/hsmp/plat.c
@@ -68,21 +68,21 @@ static int hsmp_create_non_acpi_sysfs_if(struct device *dev)
 	struct attribute_group *attr_grp;
 	u16 i;
 
-	hsmp_attr_grps = devm_kcalloc(dev, plat_dev.num_sockets + 1,
+	hsmp_attr_grps = devm_kcalloc(dev, hsmp_pdev.num_sockets + 1,
 				      sizeof(*hsmp_attr_grps),
 				      GFP_KERNEL);
 	if (!hsmp_attr_grps)
 		return -ENOMEM;
 
 	/* Create a sysfs directory for each socket */
-	for (i = 0; i < plat_dev.num_sockets; i++) {
+	for (i = 0; i < hsmp_pdev.num_sockets; i++) {
 		attr_grp = devm_kzalloc(dev, sizeof(struct attribute_group),
 					GFP_KERNEL);
 		if (!attr_grp)
 			return -ENOMEM;
 
-		snprintf(plat_dev.sock[i].name, HSMP_ATTR_GRP_NAME_SIZE, "socket%u", (u8)i);
-		attr_grp->name			= plat_dev.sock[i].name;
+		snprintf(hsmp_pdev.sock[i].name, HSMP_ATTR_GRP_NAME_SIZE, "socket%u", (u8)i);
+		attr_grp->name			= hsmp_pdev.sock[i].name;
 		attr_grp->is_bin_visible	= hsmp_is_sock_attr_visible;
 		hsmp_attr_grps[i]		= attr_grp;
 
@@ -105,10 +105,10 @@ static int init_platform_device(struct device *dev)
 	struct hsmp_socket *sock;
 	int ret, i;
 
-	for (i = 0; i < plat_dev.num_sockets; i++) {
+	for (i = 0; i < hsmp_pdev.num_sockets; i++) {
 		if (!node_to_amd_nb(i))
 			return -ENODEV;
-		sock = &plat_dev.sock[i];
+		sock = &hsmp_pdev.sock[i];
 		sock->root			= node_to_amd_nb(i)->root;
 		sock->sock_ind			= i;
 		sock->dev			= dev;
@@ -173,11 +173,11 @@ static int hsmp_pltdrv_probe(struct platform_device *pdev)
 	 * Hence allocate memory for all the sockets at once instead of allocating
 	 * on each probe.
 	 */
-	if (!plat_dev.is_probed) {
-		plat_dev.sock = devm_kcalloc(&pdev->dev, plat_dev.num_sockets,
-					     sizeof(*plat_dev.sock),
-					     GFP_KERNEL);
-		if (!plat_dev.sock)
+	if (!hsmp_pdev.is_probed) {
+		hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
+					      sizeof(*hsmp_pdev.sock),
+					      GFP_KERNEL);
+		if (!hsmp_pdev.sock)
 			return -ENOMEM;
 	}
 
@@ -201,19 +201,19 @@ static int hsmp_pltdrv_probe(struct platform_device *pdev)
 			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
 	}
 
-	if (!plat_dev.is_probed) {
-		plat_dev.hsmp_device.name	= HSMP_CDEV_NAME;
-		plat_dev.hsmp_device.minor	= MISC_DYNAMIC_MINOR;
-		plat_dev.hsmp_device.fops	= &hsmp_fops;
-		plat_dev.hsmp_device.parent	= &pdev->dev;
-		plat_dev.hsmp_device.nodename	= HSMP_DEVNODE_NAME;
-		plat_dev.hsmp_device.mode	= 0644;
+	if (!hsmp_pdev.is_probed) {
+		hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
+		hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
+		hsmp_pdev.mdev.fops	= &hsmp_fops;
+		hsmp_pdev.mdev.parent	= &pdev->dev;
+		hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
+		hsmp_pdev.mdev.mode	= 0644;
 
-		ret = misc_register(&plat_dev.hsmp_device);
+		ret = misc_register(&hsmp_pdev.mdev);
 		if (ret)
 			return ret;
 
-		plat_dev.is_probed = true;
+		hsmp_pdev.is_probed = true;
 	}
 
 	return 0;
@@ -225,9 +225,9 @@ static void hsmp_pltdrv_remove(struct platform_device *pdev)
 	 * We register only one misc_device even on multi socket system.
 	 * So, deregister should happen only once.
 	 */
-	if (plat_dev.is_probed) {
-		misc_deregister(&plat_dev.hsmp_device);
-		plat_dev.is_probed = false;
+	if (hsmp_pdev.is_probed) {
+		misc_deregister(&hsmp_pdev.mdev);
+		hsmp_pdev.is_probed = false;
 	}
 }
 
@@ -299,15 +299,15 @@ static int __init hsmp_plt_init(void)
 	 * amd_nb_num() returns number of SMN/DF interfaces present in the system
 	 * if we have N SMN/DF interfaces that ideally means N sockets
 	 */
-	plat_dev.num_sockets = amd_nb_num();
-	if (plat_dev.num_sockets == 0 || plat_dev.num_sockets > MAX_AMD_SOCKETS)
+	hsmp_pdev.num_sockets = amd_nb_num();
+	if (hsmp_pdev.num_sockets == 0 || hsmp_pdev.num_sockets > MAX_AMD_SOCKETS)
 		return ret;
 
 	ret = platform_driver_register(&amd_hsmp_driver);
 	if (ret)
 		return ret;
 
-	if (!plat_dev.is_acpi_device) {
+	if (!hsmp_pdev.is_acpi_device) {
 		if (legacy_hsmp_support()) {
 			/* Not ACPI device, but supports HSMP, register a plat_dev */
 			ret = hsmp_plat_dev_register();
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [v3 07/11] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers
  2024-07-20 17:45 [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Suma Hegde
                   ` (4 preceding siblings ...)
  2024-07-20 17:45 ` [v3 06/11] platform/x86/amd/hsmp: Change generic plat_dev name to hsmp_pdev Suma Hegde
@ 2024-07-20 17:45 ` Suma Hegde
  2024-07-30  6:16   ` Suma Hegde
                     ` (2 more replies)
  2024-07-20 17:45 ` [v3 08/11] platform/x86/amd/hsmp: Use name space while exporting module symbols Suma Hegde
                   ` (4 subsequent siblings)
  10 siblings, 3 replies; 21+ messages in thread
From: Suma Hegde @ 2024-07-20 17:45 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, hdegoede, Suma Hegde, Naveen Krishna Chatradhi

Separate the probes for ACPI and platform device drivers.
Provide a Kconfig option to select either the
ACPI or the platform device based driver.

Signed-off-by: Suma Hegde <suma.hegde@amd.com>
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
---
Changes since v2:
Following files are modified to add new symbol
 - drivers/platform/x86/amd/hsmp/Kconfig, 
 - drivers/platform/x86/amd/hsmp/Makefile
 - drivers/platform/x86/amd/Makefile
AMD_HSMP is used as common symbol and new AMD_HSMP_PLAT symbol is added

Changes since v1:
Rename "plat_dev" to "hsmp_pdev"

 arch/x86/include/asm/amd_hsmp.h        |   2 +-
 drivers/platform/x86/amd/Makefile      |   2 +-
 drivers/platform/x86/amd/hsmp/Kconfig  |  33 ++++++-
 drivers/platform/x86/amd/hsmp/Makefile |   6 +-
 drivers/platform/x86/amd/hsmp/acpi.c   | 119 ++++++++++++++++++++++--
 drivers/platform/x86/amd/hsmp/hsmp.c   |  25 ++---
 drivers/platform/x86/amd/hsmp/hsmp.h   |   8 +-
 drivers/platform/x86/amd/hsmp/plat.c   | 122 +++++++------------------
 8 files changed, 188 insertions(+), 129 deletions(-)

diff --git a/arch/x86/include/asm/amd_hsmp.h b/arch/x86/include/asm/amd_hsmp.h
index 03c2ce3edaf5..ada14e55f9f4 100644
--- a/arch/x86/include/asm/amd_hsmp.h
+++ b/arch/x86/include/asm/amd_hsmp.h
@@ -5,7 +5,7 @@
 
 #include <uapi/asm/amd_hsmp.h>
 
-#if IS_ENABLED(CONFIG_AMD_HSMP)
+#if IS_ENABLED(CONFIG_AMD_HSMP) || IS_ENABLED(CONFIG_AMD_HSMP_ACPI)
 int hsmp_send_message(struct hsmp_message *msg);
 #else
 static inline int hsmp_send_message(struct hsmp_message *msg)
diff --git a/drivers/platform/x86/amd/Makefile b/drivers/platform/x86/amd/Makefile
index 96ec24c8701b..f0b2fe81c685 100644
--- a/drivers/platform/x86/amd/Makefile
+++ b/drivers/platform/x86/amd/Makefile
@@ -5,6 +5,6 @@
 #
 
 obj-$(CONFIG_AMD_PMC)		+= pmc/
-obj-y				+= hsmp/
+obj-$(CONFIG_AMD_HSMP)		+= hsmp/
 obj-$(CONFIG_AMD_PMF)		+= pmf/
 obj-$(CONFIG_AMD_WBRF)		+= wbrf.o
diff --git a/drivers/platform/x86/amd/hsmp/Kconfig b/drivers/platform/x86/amd/hsmp/Kconfig
index b55d4ed9bceb..23fb98066225 100644
--- a/drivers/platform/x86/amd/hsmp/Kconfig
+++ b/drivers/platform/x86/amd/hsmp/Kconfig
@@ -4,14 +4,39 @@
 #
 
 config AMD_HSMP
-	tristate "AMD HSMP Driver"
-	depends on AMD_NB && X86_64 && ACPI
+	tristate "AMD Host System Management Port driver"
+	depends on AMD_NB
 	help
+	  Host System Management Port (HSMP) interface is a mailbox interface
+	  between the x86 core and the System Management Unit (SMU) firmware.
 	  The driver provides a way for user space tools to monitor and manage
 	  system management functionality on EPYC server CPUs from AMD.
 
-	  Host System Management Port (HSMP) interface is a mailbox interface
-	  between the x86 core and the System Management Unit (SMU) firmware.
+menu "AMD HSMP Probe"
+	depends on AMD_HSMP
+
+config AMD_HSMP_ACPI
+	tristate "ACPI based probe"
+	depends on ACPI
+	help
+	  This driver supports ACPI based probing.
+
+	  You may enable this, if your platform bios provides an ACPI object
+	  as described in the documentation.
 
 	  If you choose to compile this driver as a module the module will be
 	  called amd_hsmp.
+
+config AMD_HSMP_PLAT
+	tristate "Platform device based probe"
+	depends on AMD_HSMP_ACPI=n
+	help
+	  This driver supports platform device based probing.
+
+	  You may enable this, if your platform bios does not provide
+	  HSMP ACPI object.
+
+	  If you choose to compile this driver as a module the module will be
+	  called amd_hsmp.
+
+endmenu
diff --git a/drivers/platform/x86/amd/hsmp/Makefile b/drivers/platform/x86/amd/hsmp/Makefile
index 0cc92865c0a2..18d9a0d1e8c5 100644
--- a/drivers/platform/x86/amd/hsmp/Makefile
+++ b/drivers/platform/x86/amd/hsmp/Makefile
@@ -4,5 +4,7 @@
 # AMD HSMP Driver
 #
 
-obj-$(CONFIG_AMD_HSMP)		+= amd_hsmp.o
-amd_hsmp-objs			:= hsmp.o plat.o acpi.o
+obj-$(CONFIG_AMD_HSMP)			+= amd_hsmp.o
+amd_hsmp-objs				:= hsmp.o
+amd_hsmp-$(CONFIG_AMD_HSMP_PLAT)	+= plat.o
+amd_hsmp-$(CONFIG_AMD_HSMP_ACPI)	+= acpi.o
diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c
index 46cb86d5d550..86100943aadc 100644
--- a/drivers/platform/x86/amd/hsmp/acpi.c
+++ b/drivers/platform/x86/amd/hsmp/acpi.c
@@ -11,29 +11,43 @@
 
 #include "hsmp.h"
 
+#include <asm/amd_nb.h>
+
 #include <linux/acpi.h>
 #include <linux/device.h>
 #include <linux/dev_printk.h>
 #include <linux/ioport.h>
 #include <linux/kstrtox.h>
+#include <linux/platform_device.h>
 #include <linux/uuid.h>
 
 #include <uapi/asm-generic/errno-base.h>
 
+#define DRIVER_NAME		"amd_hsmp"
+#define DRIVER_VERSION		"2.3"
+#define ACPI_HSMP_DEVICE_HID	"AMDI0097"
+
 /* These are the strings specified in ACPI table */
 #define MSG_IDOFF_STR		"MsgIdOffset"
 #define MSG_ARGOFF_STR		"MsgArgOffset"
 #define MSG_RESPOFF_STR		"MsgRspOffset"
 
-void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
-			u32 *value, bool write)
+static int amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
+			      u32 *value, bool write)
 {
 	if (write)
 		iowrite32(*value, sock->virt_base_addr + offset);
 	else
 		*value = ioread32(sock->virt_base_addr + offset);
+	return 0;
 }
 
+static const struct file_operations hsmp_fops = {
+	.owner		= THIS_MODULE,
+	.unlocked_ioctl	= hsmp_ioctl,
+	.compat_ioctl	= hsmp_ioctl,
+};
+
 /* This is the UUID used for HSMP */
 static const guid_t acpi_hsmp_uuid = GUID_INIT(0xb74d619d, 0x5707, 0x48bd,
 						0xa6, 0x9f, 0x4e, 0xa2,
@@ -194,9 +208,9 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
 	struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
 	int ret;
 
-	sock->sock_ind			= sock_ind;
-	sock->dev			= dev;
-	hsmp_pdev.is_acpi_device	= true;
+	sock->sock_ind		= sock_ind;
+	sock->dev		= dev;
+	sock->amd_hsmp_rdwr	= amd_hsmp_acpi_rdwr;
 
 	sema_init(&sock->hsmp_sem, 1);
 
@@ -209,7 +223,7 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
 	return hsmp_read_acpi_dsd(sock);
 }
 
-int hsmp_create_acpi_sysfs_if(struct device *dev)
+static int hsmp_create_acpi_sysfs_if(struct device *dev)
 {
 	struct attribute_group *attr_grp;
 	u16 sock_ind;
@@ -232,7 +246,7 @@ int hsmp_create_acpi_sysfs_if(struct device *dev)
 	return devm_device_add_group(dev, attr_grp);
 }
 
-int init_acpi(struct device *dev)
+static int init_acpi(struct device *dev)
 {
 	u16 sock_ind;
 	int ret;
@@ -266,3 +280,94 @@ int init_acpi(struct device *dev)
 
 	return ret;
 }
+
+static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
+	{ACPI_HSMP_DEVICE_HID, 0},
+	{}
+};
+MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
+
+static bool check_acpi_support(struct device *dev)
+{
+	struct acpi_device *adev = ACPI_COMPANION(dev);
+
+	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
+		return true;
+
+	return false;
+}
+
+static int hsmp_acpi_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	if (!hsmp_pdev.is_probed) {
+		hsmp_pdev.num_sockets = amd_nb_num();
+		if (hsmp_pdev.num_sockets == 0 || hsmp_pdev.num_sockets > MAX_AMD_SOCKETS)
+			return -ENODEV;
+
+		hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
+					      sizeof(*hsmp_pdev.sock),
+					      GFP_KERNEL);
+		if (!hsmp_pdev.sock)
+			return -ENOMEM;
+	}
+
+	if (!check_acpi_support(&pdev->dev)) {
+		dev_err(&pdev->dev, "Not ACPI device?\n");
+		return -ENODEV;
+	}
+
+	ret = init_acpi(&pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to initialize HSMP interface.\n");
+		return ret;
+	}
+
+	ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
+	if (ret)
+		dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
+
+	if (!hsmp_pdev.is_probed) {
+		hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
+		hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
+		hsmp_pdev.mdev.fops	= &hsmp_fops;
+		hsmp_pdev.mdev.parent	= &pdev->dev;
+		hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
+		hsmp_pdev.mdev.mode	= 0644;
+
+		ret = misc_register(&hsmp_pdev.mdev);
+		if (ret)
+			return ret;
+		hsmp_pdev.is_probed = true;
+	}
+
+	return 0;
+}
+
+static void hsmp_acpi_remove(struct platform_device *pdev)
+{
+	/*
+	 * We register only one misc_device even on multi-socket system.
+	 * So, deregister should happen only once.
+	 */
+	if (hsmp_pdev.is_probed) {
+		misc_deregister(&hsmp_pdev.mdev);
+		hsmp_pdev.is_probed = false;
+	}
+}
+
+static struct platform_driver amd_hsmp_driver = {
+	.probe		= hsmp_acpi_probe,
+	.remove_new	= hsmp_acpi_remove,
+	.driver		= {
+		.name	= DRIVER_NAME,
+		.acpi_match_table = amd_hsmp_acpi_ids,
+	},
+};
+
+module_platform_driver(amd_hsmp_driver);
+
+MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver");
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
index 14edaace4379..759ec1d4d60d 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.c
+++ b/drivers/platform/x86/amd/hsmp/hsmp.c
@@ -31,17 +31,6 @@
 
 struct hsmp_plat_device hsmp_pdev;
 
-static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 offset,
-			 u32 *value, bool write)
-{
-	if (hsmp_pdev.is_acpi_device)
-		amd_hsmp_acpi_rdwr(sock, offset, value, write);
-	else
-		return amd_hsmp_pci_rdwr(sock, offset, value, write);
-
-	return 0;
-}
-
 /*
  * Send a message to the HSMP port via PCI-e config space registers
  * or by writing to MMIO space.
@@ -64,7 +53,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
 
 	/* Clear the status register */
 	mbox_status = HSMP_STATUS_NOT_READY;
-	ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_WR);
+	ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_WR);
 	if (ret) {
 		pr_err("Error %d clearing mailbox status register\n", ret);
 		return ret;
@@ -73,8 +62,8 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
 	index = 0;
 	/* Write any message arguments */
 	while (index < msg->num_args) {
-		ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
-				    &msg->args[index], HSMP_WR);
+		ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
+					  &msg->args[index], HSMP_WR);
 		if (ret) {
 			pr_err("Error %d writing message argument %d\n", ret, index);
 			return ret;
@@ -83,7 +72,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
 	}
 
 	/* Write the message ID which starts the operation */
-	ret = amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id, HSMP_WR);
+	ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id, HSMP_WR);
 	if (ret) {
 		pr_err("Error %d writing message ID %u\n", ret, msg->msg_id);
 		return ret;
@@ -100,7 +89,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
 	timeout	= jiffies + msecs_to_jiffies(HSMP_MSG_TIMEOUT);
 
 	while (time_before(jiffies, timeout)) {
-		ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_RD);
+		ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_RD);
 		if (ret) {
 			pr_err("Error %d reading mailbox status\n", ret);
 			return ret;
@@ -135,8 +124,8 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
 	 */
 	index = 0;
 	while (index < msg->response_sz) {
-		ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
-				    &msg->args[index], HSMP_RD);
+		ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
+					  &msg->args[index], HSMP_RD);
 		if (ret) {
 			pr_err("Error %d reading response %u for message ID:%u\n",
 			       ret, index, msg->msg_id);
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
index a77887d298b6..5d4fc7735a87 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.h
+++ b/drivers/platform/x86/amd/hsmp/hsmp.h
@@ -41,6 +41,7 @@ struct hsmp_socket {
 	struct pci_dev *root;
 	struct device *dev;
 	u16 sock_ind;
+	int (*amd_hsmp_rdwr)(struct hsmp_socket *sock, u32 off, u32 *val, bool rw);
 };
 
 struct hsmp_plat_device {
@@ -48,19 +49,14 @@ struct hsmp_plat_device {
 	struct hsmp_socket *sock;
 	u32 proto_ver;
 	u16 num_sockets;
-	bool is_acpi_device;
 	bool is_probed;
 };
 
 extern struct hsmp_plat_device hsmp_pdev;
 
-int init_acpi(struct device *dev);
 ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
 			     struct bin_attribute *bin_attr, char *buf,
 			     loff_t off, size_t count);
-int hsmp_create_acpi_sysfs_if(struct device *dev);
-int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
-		      u32 *value, bool write);
 int hsmp_cache_proto_ver(u16 sock_ind);
 long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
 umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
@@ -68,6 +64,4 @@ umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
 int hsmp_create_attr_list(struct attribute_group *attr_grp,
 			  struct device *dev, u16 sock_ind);
 int hsmp_test(u16 sock_ind, u32 value);
-void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
-			u32 *value, bool write);
 #endif /* HSMP_H */
diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
index c297540bb64c..3bce2c570f2b 100644
--- a/drivers/platform/x86/amd/hsmp/plat.c
+++ b/drivers/platform/x86/amd/hsmp/plat.c
@@ -13,15 +13,13 @@
 
 #include <asm/amd_nb.h>
 
-#include <linux/acpi.h>
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 
 #define DRIVER_NAME		"amd_hsmp"
-#define DRIVER_VERSION		"2.2"
-#define ACPI_HSMP_DEVICE_HID	"AMDI0097"
+#define DRIVER_VERSION		"2.3"
 
 /*
  * To access specific HSMP mailbox register, s/w writes the SMN address of HSMP mailbox
@@ -37,8 +35,8 @@
 #define HSMP_INDEX_REG		0xc4
 #define HSMP_DATA_REG		0xc8
 
-int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
-		      u32 *value, bool write)
+static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
+			     u32 *value, bool write)
 {
 	int ret;
 
@@ -113,6 +111,7 @@ static int init_platform_device(struct device *dev)
 		sock->sock_ind			= i;
 		sock->dev			= dev;
 		sock->mbinfo.base_addr		= SMN_HSMP_BASE;
+		sock->amd_hsmp_rdwr		= amd_hsmp_pci_rdwr;
 
 		/*
 		 * This is a transitional change from non-ACPI to ACPI, only
@@ -146,89 +145,39 @@ static int init_platform_device(struct device *dev)
 	return 0;
 }
 
-static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
-	{ACPI_HSMP_DEVICE_HID, 0},
-	{}
-};
-MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
-
-static bool check_acpi_support(struct device *dev)
-{
-	struct acpi_device *adev = ACPI_COMPANION(dev);
-
-	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
-		return true;
-
-	return false;
-}
-
 static int hsmp_pltdrv_probe(struct platform_device *pdev)
 {
 	int ret;
 
-	/*
-	 * On ACPI supported BIOS, there is an ACPI HSMP device added for
-	 * each socket, so the per socket probing, but the memory allocated for
-	 * sockets should be contiguous to access it as an array,
-	 * Hence allocate memory for all the sockets at once instead of allocating
-	 * on each probe.
-	 */
-	if (!hsmp_pdev.is_probed) {
-		hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
-					      sizeof(*hsmp_pdev.sock),
-					      GFP_KERNEL);
-		if (!hsmp_pdev.sock)
-			return -ENOMEM;
-	}
+	hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
+				      sizeof(*hsmp_pdev.sock),
+				      GFP_KERNEL);
+	if (!hsmp_pdev.sock)
+		return -ENOMEM;
 
-	if (check_acpi_support(&pdev->dev)) {
-		ret = init_acpi(&pdev->dev);
-		if (ret) {
-			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
-			return ret;
-		}
-		ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
-		if (ret)
-			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
-	} else {
-		ret = init_platform_device(&pdev->dev);
-		if (ret) {
-			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
-			return ret;
-		}
-		ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
-		if (ret)
-			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
+	ret = init_platform_device(&pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
+		return ret;
 	}
 
-	if (!hsmp_pdev.is_probed) {
-		hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
-		hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
-		hsmp_pdev.mdev.fops	= &hsmp_fops;
-		hsmp_pdev.mdev.parent	= &pdev->dev;
-		hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
-		hsmp_pdev.mdev.mode	= 0644;
-
-		ret = misc_register(&hsmp_pdev.mdev);
-		if (ret)
-			return ret;
+	ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
+	if (ret)
+		dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
 
-		hsmp_pdev.is_probed = true;
-	}
+	hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
+	hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
+	hsmp_pdev.mdev.fops	= &hsmp_fops;
+	hsmp_pdev.mdev.parent	= &pdev->dev;
+	hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
+	hsmp_pdev.mdev.mode	= 0644;
 
-	return 0;
+	return misc_register(&hsmp_pdev.mdev);
 }
 
 static void hsmp_pltdrv_remove(struct platform_device *pdev)
 {
-	/*
-	 * We register only one misc_device even on multi socket system.
-	 * So, deregister should happen only once.
-	 */
-	if (hsmp_pdev.is_probed) {
-		misc_deregister(&hsmp_pdev.mdev);
-		hsmp_pdev.is_probed = false;
-	}
+	misc_deregister(&hsmp_pdev.mdev);
 }
 
 static struct platform_driver amd_hsmp_driver = {
@@ -236,7 +185,6 @@ static struct platform_driver amd_hsmp_driver = {
 	.remove_new	= hsmp_pltdrv_remove,
 	.driver		= {
 		.name	= DRIVER_NAME,
-		.acpi_match_table = amd_hsmp_acpi_ids,
 	},
 };
 
@@ -295,6 +243,12 @@ static int __init hsmp_plt_init(void)
 {
 	int ret = -ENODEV;
 
+	if (!legacy_hsmp_support()) {
+		pr_info("HSMP is not supported on Family:%x model:%x\n",
+			boot_cpu_data.x86, boot_cpu_data.x86_model);
+		return ret;
+	}
+
 	/*
 	 * amd_nb_num() returns number of SMN/DF interfaces present in the system
 	 * if we have N SMN/DF interfaces that ideally means N sockets
@@ -307,19 +261,9 @@ static int __init hsmp_plt_init(void)
 	if (ret)
 		return ret;
 
-	if (!hsmp_pdev.is_acpi_device) {
-		if (legacy_hsmp_support()) {
-			/* Not ACPI device, but supports HSMP, register a plat_dev */
-			ret = hsmp_plat_dev_register();
-		} else {
-			/* Not ACPI, Does not support HSMP */
-			pr_info("HSMP is not supported on Family:%x model:%x\n",
-				boot_cpu_data.x86, boot_cpu_data.x86_model);
-			ret = -ENODEV;
-		}
-		if (ret)
-			platform_driver_unregister(&amd_hsmp_driver);
-	}
+	ret = hsmp_plat_dev_register();
+	if (ret)
+		platform_driver_unregister(&amd_hsmp_driver);
 
 	return ret;
 }
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [v3 08/11] platform/x86/amd/hsmp: Use name space while exporting module symbols
  2024-07-20 17:45 [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Suma Hegde
                   ` (5 preceding siblings ...)
  2024-07-20 17:45 ` [v3 07/11] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers Suma Hegde
@ 2024-07-20 17:45 ` Suma Hegde
  2024-07-20 17:45 ` [v3 09/11] platform/x86/amd/hsmp: Move read() and is_bin_visible() to respective files Suma Hegde
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Suma Hegde @ 2024-07-20 17:45 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, hdegoede, Suma Hegde, Naveen Krishna Chatradhi

hsmp_send_message() is exported with AMD_HSMP name space.
The other modules who would like to use this symbol,
need to import AMD_HSMP namespace using MODULE_IMPORT_NS()
to get away with warning.

Signed-off-by: Suma Hegde <suma.hegde@amd.com>
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
---
Changes since v2:
None
Changes since v1:
None

 drivers/platform/x86/amd/hsmp/hsmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
index 759ec1d4d60d..119a1f8895ca 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.c
+++ b/drivers/platform/x86/amd/hsmp/hsmp.c
@@ -186,7 +186,7 @@ int hsmp_send_message(struct hsmp_message *msg)
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(hsmp_send_message);
+EXPORT_SYMBOL_NS_GPL(hsmp_send_message, AMD_HSMP);
 
 int hsmp_test(u16 sock_ind, u32 value)
 {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [v3 09/11] platform/x86/amd/hsmp: Move read() and is_bin_visible() to respective files
  2024-07-20 17:45 [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Suma Hegde
                   ` (6 preceding siblings ...)
  2024-07-20 17:45 ` [v3 08/11] platform/x86/amd/hsmp: Use name space while exporting module symbols Suma Hegde
@ 2024-07-20 17:45 ` Suma Hegde
  2024-08-07 12:37   ` Ilpo Järvinen
  2024-07-20 17:45 ` [v3 10/11] platform/x86/amd/hsmp: Use dev_groups in the driver structure Suma Hegde
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Suma Hegde @ 2024-07-20 17:45 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, hdegoede, Suma Hegde, Naveen Krishna Chatradhi

The .read() and .is_bin_visibile() need to be handled differently in acpi
and platform drivers, due to the way the sysfs files are created.

This is in preparation to using .dev_groups instead of dynamic sysfs
creation. The sysfs at this point is not functional, it will be enabled in
the next patch.

Signed-off-by: Suma Hegde <suma.hegde@amd.com>
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
---
Changes since v2:
None
Changes since v1:
1. Change is_visible to is_bin_visible in commit message
1. Add parenthesis around read and is_bin_visible in commit message
2. Change plat_dev to hsmp_pdev, hsmp_device to mdev
3. Remove unnecessary if, else conditions in hsmp_is_sock_attr_visible
4. Change un cached to un-cached

 drivers/platform/x86/amd/hsmp/acpi.c | 41 ++++++++++++++++++++
 drivers/platform/x86/amd/hsmp/hsmp.c | 37 ------------------
 drivers/platform/x86/amd/hsmp/plat.c | 57 ++++++++++++++++++++++++++++
 3 files changed, 98 insertions(+), 37 deletions(-)

diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c
index 86100943aadc..7cb38c8dc627 100644
--- a/drivers/platform/x86/amd/hsmp/acpi.c
+++ b/drivers/platform/x86/amd/hsmp/acpi.c
@@ -11,6 +11,7 @@
 
 #include "hsmp.h"
 
+#include <asm/amd_hsmp.h>
 #include <asm/amd_nb.h>
 
 #include <linux/acpi.h>
@@ -214,6 +215,8 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
 
 	sema_init(&sock->hsmp_sem, 1);
 
+	dev_set_drvdata(dev, sock);
+
 	/* Read MP1 base address from CRS method */
 	ret = hsmp_read_acpi_crs(sock);
 	if (ret)
@@ -246,6 +249,44 @@ static int hsmp_create_acpi_sysfs_if(struct device *dev)
 	return devm_device_add_group(dev, attr_grp);
 }
 
+ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
+			     struct bin_attribute *bin_attr, char *buf,
+			     loff_t off, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct hsmp_socket *sock = dev_get_drvdata(dev);
+	struct hsmp_message msg = { 0 };
+	int ret;
+
+	if (!sock)
+		return -EINVAL;
+
+	/* Do not support lseek(), reads entire metric table */
+	if (count < bin_attr->size) {
+		dev_err(sock->dev, "Wrong buffer size\n");
+		return -EINVAL;
+	}
+
+	msg.msg_id      = HSMP_GET_METRIC_TABLE;
+	msg.sock_ind    = sock->sock_ind;
+
+	ret = hsmp_send_message(&msg);
+	if (ret)
+		return ret;
+	memcpy_fromio(buf, sock->metric_tbl_addr, bin_attr->size);
+
+	return bin_attr->size;
+}
+
+umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
+				  struct bin_attribute *battr, int id)
+{
+	if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6)
+		return battr->attr.mode;
+
+	return 0;
+}
+
 static int init_acpi(struct device *dev)
 {
 	u16 sock_ind;
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
index 119a1f8895ca..c906723ae2f2 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.c
+++ b/drivers/platform/x86/amd/hsmp/hsmp.c
@@ -274,34 +274,6 @@ long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 	return 0;
 }
 
-ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
-			     struct bin_attribute *bin_attr, char *buf,
-			     loff_t off, size_t count)
-{
-	struct hsmp_socket *sock = bin_attr->private;
-	struct hsmp_message msg = { 0 };
-	int ret;
-
-	if (!sock)
-		return -EINVAL;
-
-	/* Do not support lseek(), reads entire metric table */
-	if (count < bin_attr->size) {
-		dev_err(sock->dev, "Wrong buffer size\n");
-		return -EINVAL;
-	}
-
-	msg.msg_id	= HSMP_GET_METRIC_TABLE;
-	msg.sock_ind	= sock->sock_ind;
-
-	ret = hsmp_send_message(&msg);
-	if (ret)
-		return ret;
-	memcpy_fromio(buf, sock->metric_tbl_addr, bin_attr->size);
-
-	return bin_attr->size;
-}
-
 static int hsmp_get_tbl_dram_base(u16 sock_ind)
 {
 	struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
@@ -335,15 +307,6 @@ static int hsmp_get_tbl_dram_base(u16 sock_ind)
 	return 0;
 }
 
-umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
-				  struct bin_attribute *battr, int id)
-{
-	if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6)
-		return battr->attr.mode;
-	else
-		return 0;
-}
-
 static int hsmp_init_metric_tbl_bin_attr(struct bin_attribute **hattrs, u16 sock_ind)
 {
 	struct bin_attribute *hattr = &hsmp_pdev.sock[sock_ind].hsmp_attr;
diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
index 3bce2c570f2b..c2b83363713f 100644
--- a/drivers/platform/x86/amd/hsmp/plat.c
+++ b/drivers/platform/x86/amd/hsmp/plat.c
@@ -11,6 +11,7 @@
 
 #include "hsmp.h"
 
+#include <asm/amd_hsmp.h>
 #include <asm/amd_nb.h>
 
 #include <linux/device.h>
@@ -90,6 +91,62 @@ static int hsmp_create_non_acpi_sysfs_if(struct device *dev)
 	return device_add_groups(dev, hsmp_attr_grps);
 }
 
+ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
+			     struct bin_attribute *bin_attr, char *buf,
+			     loff_t off, size_t count)
+{
+	struct hsmp_message msg = { 0 };
+	struct hsmp_socket *sock;
+	u8 sock_ind;
+	int ret;
+
+	ret = kstrtou8(bin_attr->private, 10, &sock_ind);
+	if (ret)
+		return ret;
+
+	if (sock_ind >= hsmp_pdev.num_sockets)
+		return -EINVAL;
+
+	sock = &hsmp_pdev.sock[sock_ind];
+	if (!sock)
+		return -EINVAL;
+
+	/* Do not support lseek(), reads entire metric table */
+	if (count < bin_attr->size) {
+		dev_err(sock->dev, "Wrong buffer size\n");
+		return -EINVAL;
+	}
+
+	msg.msg_id	= HSMP_GET_METRIC_TABLE;
+	msg.sock_ind	= sock_ind;
+
+	ret = hsmp_send_message(&msg);
+	if (ret)
+		return ret;
+	memcpy_fromio(buf, sock->metric_tbl_addr, bin_attr->size);
+
+	return bin_attr->size;
+}
+
+umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
+				  struct bin_attribute *battr, int id)
+{
+	u8 sock_ind;
+	int ret;
+
+	ret = kstrtou8(battr->private, 10, &sock_ind);
+	if (ret)
+		return ret;
+
+	if (id == 0 && sock_ind >= hsmp_pdev.num_sockets)
+		return SYSFS_GROUP_INVISIBLE;
+
+	if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6)
+		return battr->attr.mode;
+
+	return 0;
+}
+
 static inline bool is_f1a_m0h(void)
 {
 	if (boot_cpu_data.x86 == 0x1A && boot_cpu_data.x86_model <= 0x0F)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [v3 10/11] platform/x86/amd/hsmp: Use dev_groups in the driver structure
  2024-07-20 17:45 [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Suma Hegde
                   ` (7 preceding siblings ...)
  2024-07-20 17:45 ` [v3 09/11] platform/x86/amd/hsmp: Move read() and is_bin_visible() to respective files Suma Hegde
@ 2024-07-20 17:45 ` Suma Hegde
  2024-07-20 17:45 ` [v3 11/11] platform/x86/amd/hsmp: Fix potential spectre issue Suma Hegde
  2024-08-07 11:33 ` [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Ilpo Järvinen
  10 siblings, 0 replies; 21+ messages in thread
From: Suma Hegde @ 2024-07-20 17:45 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, hdegoede, Suma Hegde, Naveen Krishna Chatradhi

Move out of device_add_group() variants, instead assign static array of
attribute groups to .dev_groups in platform_driver structure.
Then use is_visible to enable only the necessary files on the platform.

Signed-off-by: Suma Hegde <suma.hegde@amd.com>
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
---
Changes since v2:
None
Changes since v1:
Change plat_dev to hsmp_pdev

 drivers/platform/x86/amd/hsmp/acpi.c |  65 ++++++++--------
 drivers/platform/x86/amd/hsmp/hsmp.c |  40 +---------
 drivers/platform/x86/amd/hsmp/hsmp.h |   8 +-
 drivers/platform/x86/amd/hsmp/plat.c | 106 +++++++++++++++++----------
 4 files changed, 102 insertions(+), 117 deletions(-)

diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c
index 7cb38c8dc627..4b1470ca8675 100644
--- a/drivers/platform/x86/amd/hsmp/acpi.c
+++ b/drivers/platform/x86/amd/hsmp/acpi.c
@@ -226,32 +226,9 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
 	return hsmp_read_acpi_dsd(sock);
 }
 
-static int hsmp_create_acpi_sysfs_if(struct device *dev)
-{
-	struct attribute_group *attr_grp;
-	u16 sock_ind;
-	int ret;
-
-	attr_grp = devm_kzalloc(dev, sizeof(struct attribute_group), GFP_KERNEL);
-	if (!attr_grp)
-		return -ENOMEM;
-
-	attr_grp->is_bin_visible = hsmp_is_sock_attr_visible;
-
-	ret = hsmp_get_uid(dev, &sock_ind);
-	if (ret)
-		return ret;
-
-	ret = hsmp_create_attr_list(attr_grp, dev, sock_ind);
-	if (ret)
-		return ret;
-
-	return devm_device_add_group(dev, attr_grp);
-}
-
-ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
-			     struct bin_attribute *bin_attr, char *buf,
-			     loff_t off, size_t count)
+static ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
+				    struct bin_attribute *bin_attr, char *buf,
+				    loff_t off, size_t count)
 {
 	struct device *dev = container_of(kobj, struct device, kobj);
 	struct hsmp_socket *sock = dev_get_drvdata(dev);
@@ -278,8 +255,8 @@ ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
 	return bin_attr->size;
 }
 
-umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
-				  struct bin_attribute *battr, int id)
+static umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
+					 struct bin_attribute *battr, int id)
 {
 	if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6)
 		return battr->attr.mode;
@@ -319,9 +296,36 @@ static int init_acpi(struct device *dev)
 		return ret;
 	}
 
+	if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6) {
+		ret = hsmp_get_tbl_dram_base(sock_ind);
+		if (ret)
+			dev_err(dev, "Failed to init metric table\n");
+	}
+
 	return ret;
 }
 
+static struct bin_attribute  hsmp_metric_tbl_attr = {
+	.attr = { .name = HSMP_METRICS_TABLE_NAME, .mode = 0444},
+	.read = hsmp_metric_tbl_read,
+	.size = sizeof(struct hsmp_metric_table),
+};
+
+static struct bin_attribute *hsmp_attr_list[] = {
+	&hsmp_metric_tbl_attr,
+	NULL
+};
+
+static struct attribute_group hsmp_attr_grp = {
+	.bin_attrs = hsmp_attr_list,
+	.is_bin_visible = hsmp_is_sock_attr_visible,
+};
+
+static const struct attribute_group *hsmp_groups[] = {
+	&hsmp_attr_grp,
+	NULL
+};
+
 static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
 	{ACPI_HSMP_DEVICE_HID, 0},
 	{}
@@ -365,10 +369,6 @@ static int hsmp_acpi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
-	if (ret)
-		dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
-
 	if (!hsmp_pdev.is_probed) {
 		hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
 		hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
@@ -404,6 +404,7 @@ static struct platform_driver amd_hsmp_driver = {
 	.driver		= {
 		.name	= DRIVER_NAME,
 		.acpi_match_table = amd_hsmp_acpi_ids,
+		.dev_groups = hsmp_groups,
 	},
 };
 
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
index c906723ae2f2..c382b494b9c7 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.c
+++ b/drivers/platform/x86/amd/hsmp/hsmp.c
@@ -274,7 +274,7 @@ long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
 	return 0;
 }
 
-static int hsmp_get_tbl_dram_base(u16 sock_ind)
+int hsmp_get_tbl_dram_base(u16 sock_ind)
 {
 	struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
 	struct hsmp_message msg = { 0 };
@@ -307,44 +307,6 @@ static int hsmp_get_tbl_dram_base(u16 sock_ind)
 	return 0;
 }
 
-static int hsmp_init_metric_tbl_bin_attr(struct bin_attribute **hattrs, u16 sock_ind)
-{
-	struct bin_attribute *hattr = &hsmp_pdev.sock[sock_ind].hsmp_attr;
-
-	sysfs_bin_attr_init(hattr);
-	hattr->attr.name	= HSMP_METRICS_TABLE_NAME;
-	hattr->attr.mode	= 0444;
-	hattr->read		= hsmp_metric_tbl_read;
-	hattr->size		= sizeof(struct hsmp_metric_table);
-	hattr->private		= &hsmp_pdev.sock[sock_ind];
-	hattrs[0]		= hattr;
-
-	if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6)
-		return hsmp_get_tbl_dram_base(sock_ind);
-	else
-		return 0;
-}
-
-/* One bin sysfs for metrics table */
-#define NUM_HSMP_ATTRS		1
-
-int hsmp_create_attr_list(struct attribute_group *attr_grp,
-			  struct device *dev, u16 sock_ind)
-{
-	struct bin_attribute **hsmp_bin_attrs;
-
-	/* Null terminated list of attributes */
-	hsmp_bin_attrs = devm_kcalloc(dev, NUM_HSMP_ATTRS + 1,
-				      sizeof(*hsmp_bin_attrs),
-				      GFP_KERNEL);
-	if (!hsmp_bin_attrs)
-		return -ENOMEM;
-
-	attr_grp->bin_attrs = hsmp_bin_attrs;
-
-	return hsmp_init_metric_tbl_bin_attr(hsmp_bin_attrs, sock_ind);
-}
-
 int hsmp_cache_proto_ver(u16 sock_ind)
 {
 	struct hsmp_message msg = { 0 };
diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
index 5d4fc7735a87..b70f40c2726c 100644
--- a/drivers/platform/x86/amd/hsmp/hsmp.h
+++ b/drivers/platform/x86/amd/hsmp/hsmp.h
@@ -54,14 +54,8 @@ struct hsmp_plat_device {
 
 extern struct hsmp_plat_device hsmp_pdev;
 
-ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
-			     struct bin_attribute *bin_attr, char *buf,
-			     loff_t off, size_t count);
 int hsmp_cache_proto_ver(u16 sock_ind);
 long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
-umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
-				  struct bin_attribute *battr, int id);
-int hsmp_create_attr_list(struct attribute_group *attr_grp,
-			  struct device *dev, u16 sock_ind);
 int hsmp_test(u16 sock_ind, u32 value);
+int hsmp_get_tbl_dram_base(u16 sock_ind);
 #endif /* HSMP_H */
diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
index c2b83363713f..33868346b5a0 100644
--- a/drivers/platform/x86/amd/hsmp/plat.c
+++ b/drivers/platform/x86/amd/hsmp/plat.c
@@ -61,39 +61,9 @@ static const struct file_operations hsmp_fops = {
 	.compat_ioctl	= hsmp_ioctl,
 };
 
-static int hsmp_create_non_acpi_sysfs_if(struct device *dev)
-{
-	const struct attribute_group **hsmp_attr_grps;
-	struct attribute_group *attr_grp;
-	u16 i;
-
-	hsmp_attr_grps = devm_kcalloc(dev, hsmp_pdev.num_sockets + 1,
-				      sizeof(*hsmp_attr_grps),
-				      GFP_KERNEL);
-	if (!hsmp_attr_grps)
-		return -ENOMEM;
-
-	/* Create a sysfs directory for each socket */
-	for (i = 0; i < hsmp_pdev.num_sockets; i++) {
-		attr_grp = devm_kzalloc(dev, sizeof(struct attribute_group),
-					GFP_KERNEL);
-		if (!attr_grp)
-			return -ENOMEM;
-
-		snprintf(hsmp_pdev.sock[i].name, HSMP_ATTR_GRP_NAME_SIZE, "socket%u", (u8)i);
-		attr_grp->name			= hsmp_pdev.sock[i].name;
-		attr_grp->is_bin_visible	= hsmp_is_sock_attr_visible;
-		hsmp_attr_grps[i]		= attr_grp;
-
-		hsmp_create_attr_list(attr_grp, dev, i);
-	}
-
-	return device_add_groups(dev, hsmp_attr_grps);
-}
-
-ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
-			     struct bin_attribute *bin_attr, char *buf,
-			     loff_t off, size_t count)
+static ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
+				    struct bin_attribute *bin_attr, char *buf,
+				    loff_t off, size_t count)
 {
 	struct hsmp_message msg = { 0 };
 	struct hsmp_socket *sock;
@@ -128,8 +98,8 @@ ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
 	return bin_attr->size;
 }
 
-umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
-				  struct bin_attribute *battr, int id)
+static umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
+					 struct bin_attribute *battr, int id)
 {
 	u8 sock_ind;
 	int ret;
@@ -147,6 +117,61 @@ umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
 	return 0;
 }
 
+/*
+ * AMD supports maximum of 8 sockets in a system.
+ * Static array of 8 + 1(for NULL) elements is created below
+ * to create sysfs groups for sockets.
+ * is_bin_visible function is used to show / hide the necessary groups.
+ */
+#define HSMP_BIN_ATTR(index, _list) \
+static struct bin_attribute attr##index = { \
+	.attr = { .name = HSMP_METRICS_TABLE_NAME, .mode = 0444}, \
+	.private = #index, \
+	.read = hsmp_metric_tbl_read, \
+	.size = sizeof(struct hsmp_metric_table), \
+}; \
+static struct bin_attribute _list[] = { \
+	&attr##index, \
+	NULL \
+}
+
+HSMP_BIN_ATTR(0, *sock0_attr_list);
+HSMP_BIN_ATTR(1, *sock1_attr_list);
+HSMP_BIN_ATTR(2, *sock2_attr_list);
+HSMP_BIN_ATTR(3, *sock3_attr_list);
+HSMP_BIN_ATTR(4, *sock4_attr_list);
+HSMP_BIN_ATTR(5, *sock5_attr_list);
+HSMP_BIN_ATTR(6, *sock6_attr_list);
+HSMP_BIN_ATTR(7, *sock7_attr_list);
+
+#define HSMP_BIN_ATTR_GRP(index, _list, _name) \
+static struct attribute_group sock##index##_attr_grp = { \
+	.bin_attrs = _list, \
+	.is_bin_visible = hsmp_is_sock_attr_visible, \
+	.name = #_name, \
+}
+
+HSMP_BIN_ATTR_GRP(0, sock0_attr_list, socket0);
+HSMP_BIN_ATTR_GRP(1, sock1_attr_list, socket1);
+HSMP_BIN_ATTR_GRP(2, sock2_attr_list, socket2);
+HSMP_BIN_ATTR_GRP(3, sock3_attr_list, socket3);
+HSMP_BIN_ATTR_GRP(4, sock4_attr_list, socket4);
+HSMP_BIN_ATTR_GRP(5, sock5_attr_list, socket5);
+HSMP_BIN_ATTR_GRP(6, sock6_attr_list, socket6);
+HSMP_BIN_ATTR_GRP(7, sock7_attr_list, socket7);
+
+static const struct attribute_group *hsmp_groups[] = {
+	&sock0_attr_grp,
+	&sock1_attr_grp,
+	&sock2_attr_grp,
+	&sock3_attr_grp,
+	&sock4_attr_grp,
+	&sock5_attr_grp,
+	&sock6_attr_grp,
+	&sock7_attr_grp,
+	NULL
+};
+
 static inline bool is_f1a_m0h(void)
 {
 	if (boot_cpu_data.x86 == 0x1A && boot_cpu_data.x86_model <= 0x0F)
@@ -197,6 +222,12 @@ static int init_platform_device(struct device *dev)
 			dev_err(dev, "Failed to read HSMP protocol version\n");
 			return ret;
 		}
+
+		if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6) {
+			ret = hsmp_get_tbl_dram_base(i);
+			if (ret)
+				dev_err(dev, "Failed to init metric table\n");
+		}
 	}
 
 	return 0;
@@ -218,10 +249,6 @@ static int hsmp_pltdrv_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
-	if (ret)
-		dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
-
 	hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
 	hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
 	hsmp_pdev.mdev.fops	= &hsmp_fops;
@@ -242,6 +269,7 @@ static struct platform_driver amd_hsmp_driver = {
 	.remove_new	= hsmp_pltdrv_remove,
 	.driver		= {
 		.name	= DRIVER_NAME,
+		.dev_groups = hsmp_groups,
 	},
 };
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [v3 11/11] platform/x86/amd/hsmp: Fix potential spectre issue
  2024-07-20 17:45 [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Suma Hegde
                   ` (8 preceding siblings ...)
  2024-07-20 17:45 ` [v3 10/11] platform/x86/amd/hsmp: Use dev_groups in the driver structure Suma Hegde
@ 2024-07-20 17:45 ` Suma Hegde
  2024-08-07 11:33 ` [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Ilpo Järvinen
  10 siblings, 0 replies; 21+ messages in thread
From: Suma Hegde @ 2024-07-20 17:45 UTC (permalink / raw)
  To: platform-driver-x86
  Cc: ilpo.jarvinen, hdegoede, Suma Hegde, Naveen Krishna Chatradhi

Fix below warning caused by smatch by using array_index_nospec()
to clamp the index within the range.
"warn: potential spectre issue 'plat_dev.sock' [r] (local cap)"

Signed-off-by: Suma Hegde <suma.hegde@amd.com>
Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
---
Changes since v2:
None
Changes since v1:
Change plat_dev to hsmp_pdev

 drivers/platform/x86/amd/hsmp/acpi.c | 3 +++
 drivers/platform/x86/amd/hsmp/plat.c | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c
index 4b1470ca8675..cc859c9fe2dd 100644
--- a/drivers/platform/x86/amd/hsmp/acpi.c
+++ b/drivers/platform/x86/amd/hsmp/acpi.c
@@ -19,6 +19,7 @@
 #include <linux/dev_printk.h>
 #include <linux/ioport.h>
 #include <linux/kstrtox.h>
+#include <linux/nospec.h>
 #include <linux/platform_device.h>
 #include <linux/uuid.h>
 
@@ -275,6 +276,8 @@ static int init_acpi(struct device *dev)
 	if (sock_ind >= hsmp_pdev.num_sockets)
 		return -EINVAL;
 
+	sock_ind = array_index_nospec(sock_ind, hsmp_pdev.num_sockets);
+
 	ret = hsmp_parse_acpi_table(dev, sock_ind);
 	if (ret) {
 		dev_err(dev, "Failed to parse ACPI table\n");
diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
index 33868346b5a0..00dc7a0d358d 100644
--- a/drivers/platform/x86/amd/hsmp/plat.c
+++ b/drivers/platform/x86/amd/hsmp/plat.c
@@ -17,6 +17,7 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/nospec.h>
 #include <linux/platform_device.h>
 
 #define DRIVER_NAME		"amd_hsmp"
@@ -77,6 +78,8 @@ static ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
 	if (sock_ind >= hsmp_pdev.num_sockets)
 		return -EINVAL;
 
+	sock_ind = array_index_nospec(sock_ind, hsmp_pdev.num_sockets);
+
 	sock = &hsmp_pdev.sock[sock_ind];
 	if (!sock)
 		return -EINVAL;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [v3 07/11] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers
  2024-07-20 17:45 ` [v3 07/11] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers Suma Hegde
@ 2024-07-30  6:16   ` Suma Hegde
  2024-07-30 13:20     ` Ilpo Järvinen
  2024-08-07 12:31   ` Ilpo Järvinen
  2024-08-07 14:17   ` Ilpo Järvinen
  2 siblings, 1 reply; 21+ messages in thread
From: Suma Hegde @ 2024-07-30  6:16 UTC (permalink / raw)
  To: platform-driver-x86; +Cc: ilpo.jarvinen, hdegoede, Naveen Krishna Chatradhi

Hi Ilpo,

Can you please check the Kconfig and Makefile changes and provide your 
feedback?

Thanks and Regards,
Suma

On 7/20/2024 11:15 PM, Suma Hegde wrote:
> Separate the probes for ACPI and platform device drivers.
> Provide a Kconfig option to select either the
> ACPI or the platform device based driver.
>
> Signed-off-by: Suma Hegde <suma.hegde@amd.com>
> Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
> ---
> Changes since v2:
> Following files are modified to add new symbol
>   - drivers/platform/x86/amd/hsmp/Kconfig,
>   - drivers/platform/x86/amd/hsmp/Makefile
>   - drivers/platform/x86/amd/Makefile
> AMD_HSMP is used as common symbol and new AMD_HSMP_PLAT symbol is added
>
> Changes since v1:
> Rename "plat_dev" to "hsmp_pdev"
>
>   arch/x86/include/asm/amd_hsmp.h        |   2 +-
>   drivers/platform/x86/amd/Makefile      |   2 +-
>   drivers/platform/x86/amd/hsmp/Kconfig  |  33 ++++++-
>   drivers/platform/x86/amd/hsmp/Makefile |   6 +-
>   drivers/platform/x86/amd/hsmp/acpi.c   | 119 ++++++++++++++++++++++--
>   drivers/platform/x86/amd/hsmp/hsmp.c   |  25 ++---
>   drivers/platform/x86/amd/hsmp/hsmp.h   |   8 +-
>   drivers/platform/x86/amd/hsmp/plat.c   | 122 +++++++------------------
>   8 files changed, 188 insertions(+), 129 deletions(-)
>
> diff --git a/arch/x86/include/asm/amd_hsmp.h b/arch/x86/include/asm/amd_hsmp.h
> index 03c2ce3edaf5..ada14e55f9f4 100644
> --- a/arch/x86/include/asm/amd_hsmp.h
> +++ b/arch/x86/include/asm/amd_hsmp.h
> @@ -5,7 +5,7 @@
>   
>   #include <uapi/asm/amd_hsmp.h>
>   
> -#if IS_ENABLED(CONFIG_AMD_HSMP)
> +#if IS_ENABLED(CONFIG_AMD_HSMP) || IS_ENABLED(CONFIG_AMD_HSMP_ACPI)
>   int hsmp_send_message(struct hsmp_message *msg);
>   #else
>   static inline int hsmp_send_message(struct hsmp_message *msg)
> diff --git a/drivers/platform/x86/amd/Makefile b/drivers/platform/x86/amd/Makefile
> index 96ec24c8701b..f0b2fe81c685 100644
> --- a/drivers/platform/x86/amd/Makefile
> +++ b/drivers/platform/x86/amd/Makefile
> @@ -5,6 +5,6 @@
>   #
>   
>   obj-$(CONFIG_AMD_PMC)		+= pmc/
> -obj-y				+= hsmp/
> +obj-$(CONFIG_AMD_HSMP)		+= hsmp/
>   obj-$(CONFIG_AMD_PMF)		+= pmf/
>   obj-$(CONFIG_AMD_WBRF)		+= wbrf.o
> diff --git a/drivers/platform/x86/amd/hsmp/Kconfig b/drivers/platform/x86/amd/hsmp/Kconfig
> index b55d4ed9bceb..23fb98066225 100644
> --- a/drivers/platform/x86/amd/hsmp/Kconfig
> +++ b/drivers/platform/x86/amd/hsmp/Kconfig
> @@ -4,14 +4,39 @@
>   #
>   
>   config AMD_HSMP
> -	tristate "AMD HSMP Driver"
> -	depends on AMD_NB && X86_64 && ACPI
> +	tristate "AMD Host System Management Port driver"
> +	depends on AMD_NB
>   	help
> +	  Host System Management Port (HSMP) interface is a mailbox interface
> +	  between the x86 core and the System Management Unit (SMU) firmware.
>   	  The driver provides a way for user space tools to monitor and manage
>   	  system management functionality on EPYC server CPUs from AMD.
>   
> -	  Host System Management Port (HSMP) interface is a mailbox interface
> -	  between the x86 core and the System Management Unit (SMU) firmware.
> +menu "AMD HSMP Probe"
> +	depends on AMD_HSMP
> +
> +config AMD_HSMP_ACPI
> +	tristate "ACPI based probe"
> +	depends on ACPI
> +	help
> +	  This driver supports ACPI based probing.
> +
> +	  You may enable this, if your platform bios provides an ACPI object
> +	  as described in the documentation.
>   
>   	  If you choose to compile this driver as a module the module will be
>   	  called amd_hsmp.
> +
> +config AMD_HSMP_PLAT
> +	tristate "Platform device based probe"
> +	depends on AMD_HSMP_ACPI=n
> +	help
> +	  This driver supports platform device based probing.
> +
> +	  You may enable this, if your platform bios does not provide
> +	  HSMP ACPI object.
> +
> +	  If you choose to compile this driver as a module the module will be
> +	  called amd_hsmp.
> +
> +endmenu
> diff --git a/drivers/platform/x86/amd/hsmp/Makefile b/drivers/platform/x86/amd/hsmp/Makefile
> index 0cc92865c0a2..18d9a0d1e8c5 100644
> --- a/drivers/platform/x86/amd/hsmp/Makefile
> +++ b/drivers/platform/x86/amd/hsmp/Makefile
> @@ -4,5 +4,7 @@
>   # AMD HSMP Driver
>   #
>   
> -obj-$(CONFIG_AMD_HSMP)		+= amd_hsmp.o
> -amd_hsmp-objs			:= hsmp.o plat.o acpi.o
> +obj-$(CONFIG_AMD_HSMP)			+= amd_hsmp.o
> +amd_hsmp-objs				:= hsmp.o
> +amd_hsmp-$(CONFIG_AMD_HSMP_PLAT)	+= plat.o
> +amd_hsmp-$(CONFIG_AMD_HSMP_ACPI)	+= acpi.o
> diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c
> index 46cb86d5d550..86100943aadc 100644
> --- a/drivers/platform/x86/amd/hsmp/acpi.c
> +++ b/drivers/platform/x86/amd/hsmp/acpi.c
> @@ -11,29 +11,43 @@
>   
>   #include "hsmp.h"
>   
> +#include <asm/amd_nb.h>
> +
>   #include <linux/acpi.h>
>   #include <linux/device.h>
>   #include <linux/dev_printk.h>
>   #include <linux/ioport.h>
>   #include <linux/kstrtox.h>
> +#include <linux/platform_device.h>
>   #include <linux/uuid.h>
>   
>   #include <uapi/asm-generic/errno-base.h>
>   
> +#define DRIVER_NAME		"amd_hsmp"
> +#define DRIVER_VERSION		"2.3"
> +#define ACPI_HSMP_DEVICE_HID	"AMDI0097"
> +
>   /* These are the strings specified in ACPI table */
>   #define MSG_IDOFF_STR		"MsgIdOffset"
>   #define MSG_ARGOFF_STR		"MsgArgOffset"
>   #define MSG_RESPOFF_STR		"MsgRspOffset"
>   
> -void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
> -			u32 *value, bool write)
> +static int amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
> +			      u32 *value, bool write)
>   {
>   	if (write)
>   		iowrite32(*value, sock->virt_base_addr + offset);
>   	else
>   		*value = ioread32(sock->virt_base_addr + offset);
> +	return 0;
>   }
>   
> +static const struct file_operations hsmp_fops = {
> +	.owner		= THIS_MODULE,
> +	.unlocked_ioctl	= hsmp_ioctl,
> +	.compat_ioctl	= hsmp_ioctl,
> +};
> +
>   /* This is the UUID used for HSMP */
>   static const guid_t acpi_hsmp_uuid = GUID_INIT(0xb74d619d, 0x5707, 0x48bd,
>   						0xa6, 0x9f, 0x4e, 0xa2,
> @@ -194,9 +208,9 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
>   	struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
>   	int ret;
>   
> -	sock->sock_ind			= sock_ind;
> -	sock->dev			= dev;
> -	hsmp_pdev.is_acpi_device	= true;
> +	sock->sock_ind		= sock_ind;
> +	sock->dev		= dev;
> +	sock->amd_hsmp_rdwr	= amd_hsmp_acpi_rdwr;
>   
>   	sema_init(&sock->hsmp_sem, 1);
>   
> @@ -209,7 +223,7 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
>   	return hsmp_read_acpi_dsd(sock);
>   }
>   
> -int hsmp_create_acpi_sysfs_if(struct device *dev)
> +static int hsmp_create_acpi_sysfs_if(struct device *dev)
>   {
>   	struct attribute_group *attr_grp;
>   	u16 sock_ind;
> @@ -232,7 +246,7 @@ int hsmp_create_acpi_sysfs_if(struct device *dev)
>   	return devm_device_add_group(dev, attr_grp);
>   }
>   
> -int init_acpi(struct device *dev)
> +static int init_acpi(struct device *dev)
>   {
>   	u16 sock_ind;
>   	int ret;
> @@ -266,3 +280,94 @@ int init_acpi(struct device *dev)
>   
>   	return ret;
>   }
> +
> +static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
> +	{ACPI_HSMP_DEVICE_HID, 0},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
> +
> +static bool check_acpi_support(struct device *dev)
> +{
> +	struct acpi_device *adev = ACPI_COMPANION(dev);
> +
> +	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
> +		return true;
> +
> +	return false;
> +}
> +
> +static int hsmp_acpi_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +
> +	if (!hsmp_pdev.is_probed) {
> +		hsmp_pdev.num_sockets = amd_nb_num();
> +		if (hsmp_pdev.num_sockets == 0 || hsmp_pdev.num_sockets > MAX_AMD_SOCKETS)
> +			return -ENODEV;
> +
> +		hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
> +					      sizeof(*hsmp_pdev.sock),
> +					      GFP_KERNEL);
> +		if (!hsmp_pdev.sock)
> +			return -ENOMEM;
> +	}
> +
> +	if (!check_acpi_support(&pdev->dev)) {
> +		dev_err(&pdev->dev, "Not ACPI device?\n");
> +		return -ENODEV;
> +	}
> +
> +	ret = init_acpi(&pdev->dev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed to initialize HSMP interface.\n");
> +		return ret;
> +	}
> +
> +	ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
> +	if (ret)
> +		dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
> +
> +	if (!hsmp_pdev.is_probed) {
> +		hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
> +		hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
> +		hsmp_pdev.mdev.fops	= &hsmp_fops;
> +		hsmp_pdev.mdev.parent	= &pdev->dev;
> +		hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
> +		hsmp_pdev.mdev.mode	= 0644;
> +
> +		ret = misc_register(&hsmp_pdev.mdev);
> +		if (ret)
> +			return ret;
> +		hsmp_pdev.is_probed = true;
> +	}
> +
> +	return 0;
> +}
> +
> +static void hsmp_acpi_remove(struct platform_device *pdev)
> +{
> +	/*
> +	 * We register only one misc_device even on multi-socket system.
> +	 * So, deregister should happen only once.
> +	 */
> +	if (hsmp_pdev.is_probed) {
> +		misc_deregister(&hsmp_pdev.mdev);
> +		hsmp_pdev.is_probed = false;
> +	}
> +}
> +
> +static struct platform_driver amd_hsmp_driver = {
> +	.probe		= hsmp_acpi_probe,
> +	.remove_new	= hsmp_acpi_remove,
> +	.driver		= {
> +		.name	= DRIVER_NAME,
> +		.acpi_match_table = amd_hsmp_acpi_ids,
> +	},
> +};
> +
> +module_platform_driver(amd_hsmp_driver);
> +
> +MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver");
> +MODULE_VERSION(DRIVER_VERSION);
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
> index 14edaace4379..759ec1d4d60d 100644
> --- a/drivers/platform/x86/amd/hsmp/hsmp.c
> +++ b/drivers/platform/x86/amd/hsmp/hsmp.c
> @@ -31,17 +31,6 @@
>   
>   struct hsmp_plat_device hsmp_pdev;
>   
> -static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 offset,
> -			 u32 *value, bool write)
> -{
> -	if (hsmp_pdev.is_acpi_device)
> -		amd_hsmp_acpi_rdwr(sock, offset, value, write);
> -	else
> -		return amd_hsmp_pci_rdwr(sock, offset, value, write);
> -
> -	return 0;
> -}
> -
>   /*
>    * Send a message to the HSMP port via PCI-e config space registers
>    * or by writing to MMIO space.
> @@ -64,7 +53,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
>   
>   	/* Clear the status register */
>   	mbox_status = HSMP_STATUS_NOT_READY;
> -	ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_WR);
> +	ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_WR);
>   	if (ret) {
>   		pr_err("Error %d clearing mailbox status register\n", ret);
>   		return ret;
> @@ -73,8 +62,8 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
>   	index = 0;
>   	/* Write any message arguments */
>   	while (index < msg->num_args) {
> -		ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
> -				    &msg->args[index], HSMP_WR);
> +		ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
> +					  &msg->args[index], HSMP_WR);
>   		if (ret) {
>   			pr_err("Error %d writing message argument %d\n", ret, index);
>   			return ret;
> @@ -83,7 +72,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
>   	}
>   
>   	/* Write the message ID which starts the operation */
> -	ret = amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id, HSMP_WR);
> +	ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id, HSMP_WR);
>   	if (ret) {
>   		pr_err("Error %d writing message ID %u\n", ret, msg->msg_id);
>   		return ret;
> @@ -100,7 +89,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
>   	timeout	= jiffies + msecs_to_jiffies(HSMP_MSG_TIMEOUT);
>   
>   	while (time_before(jiffies, timeout)) {
> -		ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_RD);
> +		ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_RD);
>   		if (ret) {
>   			pr_err("Error %d reading mailbox status\n", ret);
>   			return ret;
> @@ -135,8 +124,8 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
>   	 */
>   	index = 0;
>   	while (index < msg->response_sz) {
> -		ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
> -				    &msg->args[index], HSMP_RD);
> +		ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
> +					  &msg->args[index], HSMP_RD);
>   		if (ret) {
>   			pr_err("Error %d reading response %u for message ID:%u\n",
>   			       ret, index, msg->msg_id);
> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
> index a77887d298b6..5d4fc7735a87 100644
> --- a/drivers/platform/x86/amd/hsmp/hsmp.h
> +++ b/drivers/platform/x86/amd/hsmp/hsmp.h
> @@ -41,6 +41,7 @@ struct hsmp_socket {
>   	struct pci_dev *root;
>   	struct device *dev;
>   	u16 sock_ind;
> +	int (*amd_hsmp_rdwr)(struct hsmp_socket *sock, u32 off, u32 *val, bool rw);
>   };
>   
>   struct hsmp_plat_device {
> @@ -48,19 +49,14 @@ struct hsmp_plat_device {
>   	struct hsmp_socket *sock;
>   	u32 proto_ver;
>   	u16 num_sockets;
> -	bool is_acpi_device;
>   	bool is_probed;
>   };
>   
>   extern struct hsmp_plat_device hsmp_pdev;
>   
> -int init_acpi(struct device *dev);
>   ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
>   			     struct bin_attribute *bin_attr, char *buf,
>   			     loff_t off, size_t count);
> -int hsmp_create_acpi_sysfs_if(struct device *dev);
> -int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
> -		      u32 *value, bool write);
>   int hsmp_cache_proto_ver(u16 sock_ind);
>   long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
>   umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
> @@ -68,6 +64,4 @@ umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
>   int hsmp_create_attr_list(struct attribute_group *attr_grp,
>   			  struct device *dev, u16 sock_ind);
>   int hsmp_test(u16 sock_ind, u32 value);
> -void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
> -			u32 *value, bool write);
>   #endif /* HSMP_H */
> diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
> index c297540bb64c..3bce2c570f2b 100644
> --- a/drivers/platform/x86/amd/hsmp/plat.c
> +++ b/drivers/platform/x86/amd/hsmp/plat.c
> @@ -13,15 +13,13 @@
>   
>   #include <asm/amd_nb.h>
>   
> -#include <linux/acpi.h>
>   #include <linux/device.h>
>   #include <linux/module.h>
>   #include <linux/pci.h>
>   #include <linux/platform_device.h>
>   
>   #define DRIVER_NAME		"amd_hsmp"
> -#define DRIVER_VERSION		"2.2"
> -#define ACPI_HSMP_DEVICE_HID	"AMDI0097"
> +#define DRIVER_VERSION		"2.3"
>   
>   /*
>    * To access specific HSMP mailbox register, s/w writes the SMN address of HSMP mailbox
> @@ -37,8 +35,8 @@
>   #define HSMP_INDEX_REG		0xc4
>   #define HSMP_DATA_REG		0xc8
>   
> -int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
> -		      u32 *value, bool write)
> +static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
> +			     u32 *value, bool write)
>   {
>   	int ret;
>   
> @@ -113,6 +111,7 @@ static int init_platform_device(struct device *dev)
>   		sock->sock_ind			= i;
>   		sock->dev			= dev;
>   		sock->mbinfo.base_addr		= SMN_HSMP_BASE;
> +		sock->amd_hsmp_rdwr		= amd_hsmp_pci_rdwr;
>   
>   		/*
>   		 * This is a transitional change from non-ACPI to ACPI, only
> @@ -146,89 +145,39 @@ static int init_platform_device(struct device *dev)
>   	return 0;
>   }
>   
> -static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
> -	{ACPI_HSMP_DEVICE_HID, 0},
> -	{}
> -};
> -MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
> -
> -static bool check_acpi_support(struct device *dev)
> -{
> -	struct acpi_device *adev = ACPI_COMPANION(dev);
> -
> -	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
> -		return true;
> -
> -	return false;
> -}
> -
>   static int hsmp_pltdrv_probe(struct platform_device *pdev)
>   {
>   	int ret;
>   
> -	/*
> -	 * On ACPI supported BIOS, there is an ACPI HSMP device added for
> -	 * each socket, so the per socket probing, but the memory allocated for
> -	 * sockets should be contiguous to access it as an array,
> -	 * Hence allocate memory for all the sockets at once instead of allocating
> -	 * on each probe.
> -	 */
> -	if (!hsmp_pdev.is_probed) {
> -		hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
> -					      sizeof(*hsmp_pdev.sock),
> -					      GFP_KERNEL);
> -		if (!hsmp_pdev.sock)
> -			return -ENOMEM;
> -	}
> +	hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
> +				      sizeof(*hsmp_pdev.sock),
> +				      GFP_KERNEL);
> +	if (!hsmp_pdev.sock)
> +		return -ENOMEM;
>   
> -	if (check_acpi_support(&pdev->dev)) {
> -		ret = init_acpi(&pdev->dev);
> -		if (ret) {
> -			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
> -			return ret;
> -		}
> -		ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
> -		if (ret)
> -			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
> -	} else {
> -		ret = init_platform_device(&pdev->dev);
> -		if (ret) {
> -			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
> -			return ret;
> -		}
> -		ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
> -		if (ret)
> -			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
> +	ret = init_platform_device(&pdev->dev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
> +		return ret;
>   	}
>   
> -	if (!hsmp_pdev.is_probed) {
> -		hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
> -		hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
> -		hsmp_pdev.mdev.fops	= &hsmp_fops;
> -		hsmp_pdev.mdev.parent	= &pdev->dev;
> -		hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
> -		hsmp_pdev.mdev.mode	= 0644;
> -
> -		ret = misc_register(&hsmp_pdev.mdev);
> -		if (ret)
> -			return ret;
> +	ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
> +	if (ret)
> +		dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
>   
> -		hsmp_pdev.is_probed = true;
> -	}
> +	hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
> +	hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
> +	hsmp_pdev.mdev.fops	= &hsmp_fops;
> +	hsmp_pdev.mdev.parent	= &pdev->dev;
> +	hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
> +	hsmp_pdev.mdev.mode	= 0644;
>   
> -	return 0;
> +	return misc_register(&hsmp_pdev.mdev);
>   }
>   
>   static void hsmp_pltdrv_remove(struct platform_device *pdev)
>   {
> -	/*
> -	 * We register only one misc_device even on multi socket system.
> -	 * So, deregister should happen only once.
> -	 */
> -	if (hsmp_pdev.is_probed) {
> -		misc_deregister(&hsmp_pdev.mdev);
> -		hsmp_pdev.is_probed = false;
> -	}
> +	misc_deregister(&hsmp_pdev.mdev);
>   }
>   
>   static struct platform_driver amd_hsmp_driver = {
> @@ -236,7 +185,6 @@ static struct platform_driver amd_hsmp_driver = {
>   	.remove_new	= hsmp_pltdrv_remove,
>   	.driver		= {
>   		.name	= DRIVER_NAME,
> -		.acpi_match_table = amd_hsmp_acpi_ids,
>   	},
>   };
>   
> @@ -295,6 +243,12 @@ static int __init hsmp_plt_init(void)
>   {
>   	int ret = -ENODEV;
>   
> +	if (!legacy_hsmp_support()) {
> +		pr_info("HSMP is not supported on Family:%x model:%x\n",
> +			boot_cpu_data.x86, boot_cpu_data.x86_model);
> +		return ret;
> +	}
> +
>   	/*
>   	 * amd_nb_num() returns number of SMN/DF interfaces present in the system
>   	 * if we have N SMN/DF interfaces that ideally means N sockets
> @@ -307,19 +261,9 @@ static int __init hsmp_plt_init(void)
>   	if (ret)
>   		return ret;
>   
> -	if (!hsmp_pdev.is_acpi_device) {
> -		if (legacy_hsmp_support()) {
> -			/* Not ACPI device, but supports HSMP, register a plat_dev */
> -			ret = hsmp_plat_dev_register();
> -		} else {
> -			/* Not ACPI, Does not support HSMP */
> -			pr_info("HSMP is not supported on Family:%x model:%x\n",
> -				boot_cpu_data.x86, boot_cpu_data.x86_model);
> -			ret = -ENODEV;
> -		}
> -		if (ret)
> -			platform_driver_unregister(&amd_hsmp_driver);
> -	}
> +	ret = hsmp_plat_dev_register();
> +	if (ret)
> +		platform_driver_unregister(&amd_hsmp_driver);
>   
>   	return ret;
>   }

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [v3 07/11] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers
  2024-07-30  6:16   ` Suma Hegde
@ 2024-07-30 13:20     ` Ilpo Järvinen
  2024-08-06 11:40       ` Suma Hegde
  0 siblings, 1 reply; 21+ messages in thread
From: Ilpo Järvinen @ 2024-07-30 13:20 UTC (permalink / raw)
  To: Suma Hegde; +Cc: platform-driver-x86, Hans de Goede, Naveen Krishna Chatradhi

On Tue, 30 Jul 2024, Suma Hegde wrote:

> Can you please check the Kconfig and Makefile changes and provide your
> feedback?

The Kconfig symbols looked better (but I only took a short glance but I'll 
take a look at it later, likely not before next week).

I'm not fully sure if it's good to base the exclusion into build time 
dependencies though. With distros, the expectation is that they enable 
everything which means the ACPI one will always be enabled and built, and 
the legacy module never is. I don't know if there's some mechanism to 
prioritize one module over the other if both would be built. I'd expect 
that to be the most desirable behavior here, ie., first try if ACPI one 
loads and if it doesn't probe successfully, try with the PLAT one? Maybe 
Hans knows something towards that direction?

-- 
 i.

> On 7/20/2024 11:15 PM, Suma Hegde wrote:
> > Separate the probes for ACPI and platform device drivers.
> > Provide a Kconfig option to select either the
> > ACPI or the platform device based driver.
> > 
> > Signed-off-by: Suma Hegde <suma.hegde@amd.com>
> > Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
> > ---
> > Changes since v2:
> > Following files are modified to add new symbol
> >   - drivers/platform/x86/amd/hsmp/Kconfig,
> >   - drivers/platform/x86/amd/hsmp/Makefile
> >   - drivers/platform/x86/amd/Makefile
> > AMD_HSMP is used as common symbol and new AMD_HSMP_PLAT symbol is added
> > 
> > Changes since v1:
> > Rename "plat_dev" to "hsmp_pdev"
> > 
> >   arch/x86/include/asm/amd_hsmp.h        |   2 +-
> >   drivers/platform/x86/amd/Makefile      |   2 +-
> >   drivers/platform/x86/amd/hsmp/Kconfig  |  33 ++++++-
> >   drivers/platform/x86/amd/hsmp/Makefile |   6 +-
> >   drivers/platform/x86/amd/hsmp/acpi.c   | 119 ++++++++++++++++++++++--
> >   drivers/platform/x86/amd/hsmp/hsmp.c   |  25 ++---
> >   drivers/platform/x86/amd/hsmp/hsmp.h   |   8 +-
> >   drivers/platform/x86/amd/hsmp/plat.c   | 122 +++++++------------------
> >   8 files changed, 188 insertions(+), 129 deletions(-)
> > 
> > diff --git a/arch/x86/include/asm/amd_hsmp.h
> > b/arch/x86/include/asm/amd_hsmp.h
> > index 03c2ce3edaf5..ada14e55f9f4 100644
> > --- a/arch/x86/include/asm/amd_hsmp.h
> > +++ b/arch/x86/include/asm/amd_hsmp.h
> > @@ -5,7 +5,7 @@
> >     #include <uapi/asm/amd_hsmp.h>
> >   -#if IS_ENABLED(CONFIG_AMD_HSMP)
> > +#if IS_ENABLED(CONFIG_AMD_HSMP) || IS_ENABLED(CONFIG_AMD_HSMP_ACPI)
> >   int hsmp_send_message(struct hsmp_message *msg);
> >   #else
> >   static inline int hsmp_send_message(struct hsmp_message *msg)
> > diff --git a/drivers/platform/x86/amd/Makefile
> > b/drivers/platform/x86/amd/Makefile
> > index 96ec24c8701b..f0b2fe81c685 100644
> > --- a/drivers/platform/x86/amd/Makefile
> > +++ b/drivers/platform/x86/amd/Makefile
> > @@ -5,6 +5,6 @@
> >   #
> >     obj-$(CONFIG_AMD_PMC)		+= pmc/
> > -obj-y				+= hsmp/
> > +obj-$(CONFIG_AMD_HSMP)		+= hsmp/
> >   obj-$(CONFIG_AMD_PMF)		+= pmf/
> >   obj-$(CONFIG_AMD_WBRF)		+= wbrf.o
> > diff --git a/drivers/platform/x86/amd/hsmp/Kconfig
> > b/drivers/platform/x86/amd/hsmp/Kconfig
> > index b55d4ed9bceb..23fb98066225 100644
> > --- a/drivers/platform/x86/amd/hsmp/Kconfig
> > +++ b/drivers/platform/x86/amd/hsmp/Kconfig
> > @@ -4,14 +4,39 @@
> >   #
> >     config AMD_HSMP
> > -	tristate "AMD HSMP Driver"
> > -	depends on AMD_NB && X86_64 && ACPI
> > +	tristate "AMD Host System Management Port driver"
> > +	depends on AMD_NB
> >   	help
> > +	  Host System Management Port (HSMP) interface is a mailbox interface
> > +	  between the x86 core and the System Management Unit (SMU) firmware.
> >   	  The driver provides a way for user space tools to monitor and manage
> >   	  system management functionality on EPYC server CPUs from AMD.
> >   -	  Host System Management Port (HSMP) interface is a mailbox interface
> > -	  between the x86 core and the System Management Unit (SMU) firmware.
> > +menu "AMD HSMP Probe"
> > +	depends on AMD_HSMP
> > +
> > +config AMD_HSMP_ACPI
> > +	tristate "ACPI based probe"
> > +	depends on ACPI
> > +	help
> > +	  This driver supports ACPI based probing.
> > +
> > +	  You may enable this, if your platform bios provides an ACPI object
> > +	  as described in the documentation.
> >     	  If you choose to compile this driver as a module the module will be
> >   	  called amd_hsmp.
> > +
> > +config AMD_HSMP_PLAT
> > +	tristate "Platform device based probe"
> > +	depends on AMD_HSMP_ACPI=n
> > +	help
> > +	  This driver supports platform device based probing.
> > +
> > +	  You may enable this, if your platform bios does not provide
> > +	  HSMP ACPI object.
> > +
> > +	  If you choose to compile this driver as a module the module will be
> > +	  called amd_hsmp.
> > +
> > +endmenu
> > diff --git a/drivers/platform/x86/amd/hsmp/Makefile
> > b/drivers/platform/x86/amd/hsmp/Makefile
> > index 0cc92865c0a2..18d9a0d1e8c5 100644
> > --- a/drivers/platform/x86/amd/hsmp/Makefile
> > +++ b/drivers/platform/x86/amd/hsmp/Makefile
> > @@ -4,5 +4,7 @@
> >   # AMD HSMP Driver
> >   #
> >   -obj-$(CONFIG_AMD_HSMP)		+= amd_hsmp.o
> > -amd_hsmp-objs			:= hsmp.o plat.o acpi.o
> > +obj-$(CONFIG_AMD_HSMP)			+= amd_hsmp.o
> > +amd_hsmp-objs				:= hsmp.o
> > +amd_hsmp-$(CONFIG_AMD_HSMP_PLAT)	+= plat.o
> > +amd_hsmp-$(CONFIG_AMD_HSMP_ACPI)	+= acpi.o
> > diff --git a/drivers/platform/x86/amd/hsmp/acpi.c
> > b/drivers/platform/x86/amd/hsmp/acpi.c
> > index 46cb86d5d550..86100943aadc 100644
> > --- a/drivers/platform/x86/amd/hsmp/acpi.c
> > +++ b/drivers/platform/x86/amd/hsmp/acpi.c
> > @@ -11,29 +11,43 @@
> >     #include "hsmp.h"
> >   +#include <asm/amd_nb.h>
> > +
> >   #include <linux/acpi.h>
> >   #include <linux/device.h>
> >   #include <linux/dev_printk.h>
> >   #include <linux/ioport.h>
> >   #include <linux/kstrtox.h>
> > +#include <linux/platform_device.h>
> >   #include <linux/uuid.h>
> >     #include <uapi/asm-generic/errno-base.h>
> >   +#define DRIVER_NAME		"amd_hsmp"
> > +#define DRIVER_VERSION		"2.3"
> > +#define ACPI_HSMP_DEVICE_HID	"AMDI0097"
> > +
> >   /* These are the strings specified in ACPI table */
> >   #define MSG_IDOFF_STR		"MsgIdOffset"
> >   #define MSG_ARGOFF_STR		"MsgArgOffset"
> >   #define MSG_RESPOFF_STR		"MsgRspOffset"
> >   -void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
> > -			u32 *value, bool write)
> > +static int amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
> > +			      u32 *value, bool write)
> >   {
> >   	if (write)
> >   		iowrite32(*value, sock->virt_base_addr + offset);
> >   	else
> >   		*value = ioread32(sock->virt_base_addr + offset);
> > +	return 0;
> >   }
> >   +static const struct file_operations hsmp_fops = {
> > +	.owner		= THIS_MODULE,
> > +	.unlocked_ioctl	= hsmp_ioctl,
> > +	.compat_ioctl	= hsmp_ioctl,
> > +};
> > +
> >   /* This is the UUID used for HSMP */
> >   static const guid_t acpi_hsmp_uuid = GUID_INIT(0xb74d619d, 0x5707, 0x48bd,
> >   						0xa6, 0x9f, 0x4e, 0xa2,
> > @@ -194,9 +208,9 @@ static int hsmp_parse_acpi_table(struct device *dev, u16
> > sock_ind)
> >   	struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
> >   	int ret;
> >   -	sock->sock_ind			= sock_ind;
> > -	sock->dev			= dev;
> > -	hsmp_pdev.is_acpi_device	= true;
> > +	sock->sock_ind		= sock_ind;
> > +	sock->dev		= dev;
> > +	sock->amd_hsmp_rdwr	= amd_hsmp_acpi_rdwr;
> >     	sema_init(&sock->hsmp_sem, 1);
> >   @@ -209,7 +223,7 @@ static int hsmp_parse_acpi_table(struct device *dev,
> > u16 sock_ind)
> >   	return hsmp_read_acpi_dsd(sock);
> >   }
> >   -int hsmp_create_acpi_sysfs_if(struct device *dev)
> > +static int hsmp_create_acpi_sysfs_if(struct device *dev)
> >   {
> >   	struct attribute_group *attr_grp;
> >   	u16 sock_ind;
> > @@ -232,7 +246,7 @@ int hsmp_create_acpi_sysfs_if(struct device *dev)
> >   	return devm_device_add_group(dev, attr_grp);
> >   }
> >   -int init_acpi(struct device *dev)
> > +static int init_acpi(struct device *dev)
> >   {
> >   	u16 sock_ind;
> >   	int ret;
> > @@ -266,3 +280,94 @@ int init_acpi(struct device *dev)
> >     	return ret;
> >   }
> > +
> > +static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
> > +	{ACPI_HSMP_DEVICE_HID, 0},
> > +	{}
> > +};
> > +MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
> > +
> > +static bool check_acpi_support(struct device *dev)
> > +{
> > +	struct acpi_device *adev = ACPI_COMPANION(dev);
> > +
> > +	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
> > +		return true;
> > +
> > +	return false;
> > +}
> > +
> > +static int hsmp_acpi_probe(struct platform_device *pdev)
> > +{
> > +	int ret;
> > +
> > +	if (!hsmp_pdev.is_probed) {
> > +		hsmp_pdev.num_sockets = amd_nb_num();
> > +		if (hsmp_pdev.num_sockets == 0 || hsmp_pdev.num_sockets >
> > MAX_AMD_SOCKETS)
> > +			return -ENODEV;
> > +
> > +		hsmp_pdev.sock = devm_kcalloc(&pdev->dev,
> > hsmp_pdev.num_sockets,
> > +					      sizeof(*hsmp_pdev.sock),
> > +					      GFP_KERNEL);
> > +		if (!hsmp_pdev.sock)
> > +			return -ENOMEM;
> > +	}
> > +
> > +	if (!check_acpi_support(&pdev->dev)) {
> > +		dev_err(&pdev->dev, "Not ACPI device?\n");
> > +		return -ENODEV;
> > +	}
> > +
> > +	ret = init_acpi(&pdev->dev);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "Failed to initialize HSMP interface.\n");
> > +		return ret;
> > +	}
> > +
> > +	ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
> > +	if (ret)
> > +		dev_err(&pdev->dev, "Failed to create HSMP sysfs
> > interface\n");
> > +
> > +	if (!hsmp_pdev.is_probed) {
> > +		hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
> > +		hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
> > +		hsmp_pdev.mdev.fops	= &hsmp_fops;
> > +		hsmp_pdev.mdev.parent	= &pdev->dev;
> > +		hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
> > +		hsmp_pdev.mdev.mode	= 0644;
> > +
> > +		ret = misc_register(&hsmp_pdev.mdev);
> > +		if (ret)
> > +			return ret;
> > +		hsmp_pdev.is_probed = true;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static void hsmp_acpi_remove(struct platform_device *pdev)
> > +{
> > +	/*
> > +	 * We register only one misc_device even on multi-socket system.
> > +	 * So, deregister should happen only once.
> > +	 */
> > +	if (hsmp_pdev.is_probed) {
> > +		misc_deregister(&hsmp_pdev.mdev);
> > +		hsmp_pdev.is_probed = false;
> > +	}
> > +}
> > +
> > +static struct platform_driver amd_hsmp_driver = {
> > +	.probe		= hsmp_acpi_probe,
> > +	.remove_new	= hsmp_acpi_remove,
> > +	.driver		= {
> > +		.name	= DRIVER_NAME,
> > +		.acpi_match_table = amd_hsmp_acpi_ids,
> > +	},
> > +};
> > +
> > +module_platform_driver(amd_hsmp_driver);
> > +
> > +MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver");
> > +MODULE_VERSION(DRIVER_VERSION);
> > +MODULE_LICENSE("GPL v2");
> > diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c
> > b/drivers/platform/x86/amd/hsmp/hsmp.c
> > index 14edaace4379..759ec1d4d60d 100644
> > --- a/drivers/platform/x86/amd/hsmp/hsmp.c
> > +++ b/drivers/platform/x86/amd/hsmp/hsmp.c
> > @@ -31,17 +31,6 @@
> >     struct hsmp_plat_device hsmp_pdev;
> >   -static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 offset,
> > -			 u32 *value, bool write)
> > -{
> > -	if (hsmp_pdev.is_acpi_device)
> > -		amd_hsmp_acpi_rdwr(sock, offset, value, write);
> > -	else
> > -		return amd_hsmp_pci_rdwr(sock, offset, value, write);
> > -
> > -	return 0;
> > -}
> > -
> >   /*
> >    * Send a message to the HSMP port via PCI-e config space registers
> >    * or by writing to MMIO space.
> > @@ -64,7 +53,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock,
> > struct hsmp_message *ms
> >     	/* Clear the status register */
> >   	mbox_status = HSMP_STATUS_NOT_READY;
> > -	ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status,
> > HSMP_WR);
> > +	ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status,
> > HSMP_WR);
> >   	if (ret) {
> >   		pr_err("Error %d clearing mailbox status register\n", ret);
> >   		return ret;
> > @@ -73,8 +62,8 @@ static int __hsmp_send_message(struct hsmp_socket *sock,
> > struct hsmp_message *ms
> >   	index = 0;
> >   	/* Write any message arguments */
> >   	while (index < msg->num_args) {
> > -		ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
> > -				    &msg->args[index], HSMP_WR);
> > +		ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index
> > << 2),
> > +					  &msg->args[index], HSMP_WR);
> >   		if (ret) {
> >   			pr_err("Error %d writing message argument %d\n", ret,
> > index);
> >   			return ret;
> > @@ -83,7 +72,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock,
> > struct hsmp_message *ms
> >   	}
> >     	/* Write the message ID which starts the operation */
> > -	ret = amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id, HSMP_WR);
> > +	ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id,
> > HSMP_WR);
> >   	if (ret) {
> >   		pr_err("Error %d writing message ID %u\n", ret, msg->msg_id);
> >   		return ret;
> > @@ -100,7 +89,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock,
> > struct hsmp_message *ms
> >   	timeout	= jiffies + msecs_to_jiffies(HSMP_MSG_TIMEOUT);
> >     	while (time_before(jiffies, timeout)) {
> > -		ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status,
> > HSMP_RD);
> > +		ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off,
> > &mbox_status, HSMP_RD);
> >   		if (ret) {
> >   			pr_err("Error %d reading mailbox status\n", ret);
> >   			return ret;
> > @@ -135,8 +124,8 @@ static int __hsmp_send_message(struct hsmp_socket *sock,
> > struct hsmp_message *ms
> >   	 */
> >   	index = 0;
> >   	while (index < msg->response_sz) {
> > -		ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
> > -				    &msg->args[index], HSMP_RD);
> > +		ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index
> > << 2),
> > +					  &msg->args[index], HSMP_RD);
> >   		if (ret) {
> >   			pr_err("Error %d reading response %u for message
> > ID:%u\n",
> >   			       ret, index, msg->msg_id);
> > diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h
> > b/drivers/platform/x86/amd/hsmp/hsmp.h
> > index a77887d298b6..5d4fc7735a87 100644
> > --- a/drivers/platform/x86/amd/hsmp/hsmp.h
> > +++ b/drivers/platform/x86/amd/hsmp/hsmp.h
> > @@ -41,6 +41,7 @@ struct hsmp_socket {
> >   	struct pci_dev *root;
> >   	struct device *dev;
> >   	u16 sock_ind;
> > +	int (*amd_hsmp_rdwr)(struct hsmp_socket *sock, u32 off, u32 *val, bool
> > rw);
> >   };
> >     struct hsmp_plat_device {
> > @@ -48,19 +49,14 @@ struct hsmp_plat_device {
> >   	struct hsmp_socket *sock;
> >   	u32 proto_ver;
> >   	u16 num_sockets;
> > -	bool is_acpi_device;
> >   	bool is_probed;
> >   };
> >     extern struct hsmp_plat_device hsmp_pdev;
> >   -int init_acpi(struct device *dev);
> >   ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
> >   			     struct bin_attribute *bin_attr, char *buf,
> >   			     loff_t off, size_t count);
> > -int hsmp_create_acpi_sysfs_if(struct device *dev);
> > -int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
> > -		      u32 *value, bool write);
> >   int hsmp_cache_proto_ver(u16 sock_ind);
> >   long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
> >   umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
> > @@ -68,6 +64,4 @@ umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
> >   int hsmp_create_attr_list(struct attribute_group *attr_grp,
> >   			  struct device *dev, u16 sock_ind);
> >   int hsmp_test(u16 sock_ind, u32 value);
> > -void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
> > -			u32 *value, bool write);
> >   #endif /* HSMP_H */
> > diff --git a/drivers/platform/x86/amd/hsmp/plat.c
> > b/drivers/platform/x86/amd/hsmp/plat.c
> > index c297540bb64c..3bce2c570f2b 100644
> > --- a/drivers/platform/x86/amd/hsmp/plat.c
> > +++ b/drivers/platform/x86/amd/hsmp/plat.c
> > @@ -13,15 +13,13 @@
> >     #include <asm/amd_nb.h>
> >   -#include <linux/acpi.h>
> >   #include <linux/device.h>
> >   #include <linux/module.h>
> >   #include <linux/pci.h>
> >   #include <linux/platform_device.h>
> >     #define DRIVER_NAME		"amd_hsmp"
> > -#define DRIVER_VERSION		"2.2"
> > -#define ACPI_HSMP_DEVICE_HID	"AMDI0097"
> > +#define DRIVER_VERSION		"2.3"
> >     /*
> >    * To access specific HSMP mailbox register, s/w writes the SMN address of
> > HSMP mailbox
> > @@ -37,8 +35,8 @@
> >   #define HSMP_INDEX_REG		0xc4
> >   #define HSMP_DATA_REG		0xc8
> >   -int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
> > -		      u32 *value, bool write)
> > +static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
> > +			     u32 *value, bool write)
> >   {
> >   	int ret;
> >   @@ -113,6 +111,7 @@ static int init_platform_device(struct device *dev)
> >   		sock->sock_ind			= i;
> >   		sock->dev			= dev;
> >   		sock->mbinfo.base_addr		= SMN_HSMP_BASE;
> > +		sock->amd_hsmp_rdwr		= amd_hsmp_pci_rdwr;
> >     		/*
> >   		 * This is a transitional change from non-ACPI to ACPI, only
> > @@ -146,89 +145,39 @@ static int init_platform_device(struct device *dev)
> >   	return 0;
> >   }
> >   -static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
> > -	{ACPI_HSMP_DEVICE_HID, 0},
> > -	{}
> > -};
> > -MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
> > -
> > -static bool check_acpi_support(struct device *dev)
> > -{
> > -	struct acpi_device *adev = ACPI_COMPANION(dev);
> > -
> > -	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
> > -		return true;
> > -
> > -	return false;
> > -}
> > -
> >   static int hsmp_pltdrv_probe(struct platform_device *pdev)
> >   {
> >   	int ret;
> >   -	/*
> > -	 * On ACPI supported BIOS, there is an ACPI HSMP device added for
> > -	 * each socket, so the per socket probing, but the memory allocated
> > for
> > -	 * sockets should be contiguous to access it as an array,
> > -	 * Hence allocate memory for all the sockets at once instead of
> > allocating
> > -	 * on each probe.
> > -	 */
> > -	if (!hsmp_pdev.is_probed) {
> > -		hsmp_pdev.sock = devm_kcalloc(&pdev->dev,
> > hsmp_pdev.num_sockets,
> > -					      sizeof(*hsmp_pdev.sock),
> > -					      GFP_KERNEL);
> > -		if (!hsmp_pdev.sock)
> > -			return -ENOMEM;
> > -	}
> > +	hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
> > +				      sizeof(*hsmp_pdev.sock),
> > +				      GFP_KERNEL);
> > +	if (!hsmp_pdev.sock)
> > +		return -ENOMEM;
> >   -	if (check_acpi_support(&pdev->dev)) {
> > -		ret = init_acpi(&pdev->dev);
> > -		if (ret) {
> > -			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
> > -			return ret;
> > -		}
> > -		ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
> > -		if (ret)
> > -			dev_err(&pdev->dev, "Failed to create HSMP sysfs
> > interface\n");
> > -	} else {
> > -		ret = init_platform_device(&pdev->dev);
> > -		if (ret) {
> > -			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
> > -			return ret;
> > -		}
> > -		ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
> > -		if (ret)
> > -			dev_err(&pdev->dev, "Failed to create HSMP sysfs
> > interface\n");
> > +	ret = init_platform_device(&pdev->dev);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
> > +		return ret;
> >   	}
> >   -	if (!hsmp_pdev.is_probed) {
> > -		hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
> > -		hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
> > -		hsmp_pdev.mdev.fops	= &hsmp_fops;
> > -		hsmp_pdev.mdev.parent	= &pdev->dev;
> > -		hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
> > -		hsmp_pdev.mdev.mode	= 0644;
> > -
> > -		ret = misc_register(&hsmp_pdev.mdev);
> > -		if (ret)
> > -			return ret;
> > +	ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
> > +	if (ret)
> > +		dev_err(&pdev->dev, "Failed to create HSMP sysfs
> > interface\n");
> >   -		hsmp_pdev.is_probed = true;
> > -	}
> > +	hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
> > +	hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
> > +	hsmp_pdev.mdev.fops	= &hsmp_fops;
> > +	hsmp_pdev.mdev.parent	= &pdev->dev;
> > +	hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
> > +	hsmp_pdev.mdev.mode	= 0644;
> >   -	return 0;
> > +	return misc_register(&hsmp_pdev.mdev);
> >   }
> >     static void hsmp_pltdrv_remove(struct platform_device *pdev)
> >   {
> > -	/*
> > -	 * We register only one misc_device even on multi socket system.
> > -	 * So, deregister should happen only once.
> > -	 */
> > -	if (hsmp_pdev.is_probed) {
> > -		misc_deregister(&hsmp_pdev.mdev);
> > -		hsmp_pdev.is_probed = false;
> > -	}
> > +	misc_deregister(&hsmp_pdev.mdev);
> >   }
> >     static struct platform_driver amd_hsmp_driver = {
> > @@ -236,7 +185,6 @@ static struct platform_driver amd_hsmp_driver = {
> >   	.remove_new	= hsmp_pltdrv_remove,
> >   	.driver		= {
> >   		.name	= DRIVER_NAME,
> > -		.acpi_match_table = amd_hsmp_acpi_ids,
> >   	},
> >   };
> >   @@ -295,6 +243,12 @@ static int __init hsmp_plt_init(void)
> >   {
> >   	int ret = -ENODEV;
> >   +	if (!legacy_hsmp_support()) {
> > +		pr_info("HSMP is not supported on Family:%x model:%x\n",
> > +			boot_cpu_data.x86, boot_cpu_data.x86_model);
> > +		return ret;
> > +	}
> > +
> >   	/*
> >   	 * amd_nb_num() returns number of SMN/DF interfaces present in the
> > system
> >   	 * if we have N SMN/DF interfaces that ideally means N sockets
> > @@ -307,19 +261,9 @@ static int __init hsmp_plt_init(void)
> >   	if (ret)
> >   		return ret;
> >   -	if (!hsmp_pdev.is_acpi_device) {
> > -		if (legacy_hsmp_support()) {
> > -			/* Not ACPI device, but supports HSMP, register a
> > plat_dev */
> > -			ret = hsmp_plat_dev_register();
> > -		} else {
> > -			/* Not ACPI, Does not support HSMP */
> > -			pr_info("HSMP is not supported on Family:%x
> > model:%x\n",
> > -				boot_cpu_data.x86, boot_cpu_data.x86_model);
> > -			ret = -ENODEV;
> > -		}
> > -		if (ret)
> > -			platform_driver_unregister(&amd_hsmp_driver);
> > -	}
> > +	ret = hsmp_plat_dev_register();
> > +	if (ret)
> > +		platform_driver_unregister(&amd_hsmp_driver);
> >     	return ret;
> >   }
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [v3 07/11] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers
  2024-07-30 13:20     ` Ilpo Järvinen
@ 2024-08-06 11:40       ` Suma Hegde
  0 siblings, 0 replies; 21+ messages in thread
From: Suma Hegde @ 2024-08-06 11:40 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: platform-driver-x86, Hans de Goede, Naveen Krishna Chatradhi

Hi Ilpo,

On 7/30/2024 6:50 PM, Ilpo Järvinen wrote:
> Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding.
>
>
> On Tue, 30 Jul 2024, Suma Hegde wrote:
>
>> Can you please check the Kconfig and Makefile changes and provide your
>> feedback?
> The Kconfig symbols looked better (but I only took a short glance but I'll
> take a look at it later, likely not before next week).
>
> I'm not fully sure if it's good to base the exclusion into build time
> dependencies though.

The current hsmp driver in the linux without this patch series, 
dynamically checks if ACPI HSMP object is present and if not available 
registers a plat device.

But with this method, we are not able to support sysfs groups through 
dev_groups pointer separately for ACPI and platform device based drivers.

So to address above issue as well as based on your suggestion, we have 
split the driver into two and made them mutually exclusive.

And, we are supporting ACPI alone for future platforms, platform device 
based driver is only for legacy purpose.

> With distros, the expectation is that they enable
> everything which means the ACPI one will always be enabled and built, and
> the legacy module never is.
We are not selecting HSMP ACPI module by default based on ACPI config, 
so either ACPI or plat device based driver can be enabled.
> I don't know if there's some mechanism to
> prioritize one module over the other if both would be built. I'd expect
> that to be the most desirable behavior here, ie., first try if ACPI one
> loads and if it doesn't probe successfully, try with the PLAT one? Maybe
> Hans knows something towards that direction?

> --
>   i.
>
>> On 7/20/2024 11:15 PM, Suma Hegde wrote:
>>> Separate the probes for ACPI and platform device drivers.
>>> Provide a Kconfig option to select either the
>>> ACPI or the platform device based driver.
>>>
>>> Signed-off-by: Suma Hegde <suma.hegde@amd.com>
>>> Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
>>> ---
>>> Changes since v2:
>>> Following files are modified to add new symbol
>>>    - drivers/platform/x86/amd/hsmp/Kconfig,
>>>    - drivers/platform/x86/amd/hsmp/Makefile
>>>    - drivers/platform/x86/amd/Makefile
>>> AMD_HSMP is used as common symbol and new AMD_HSMP_PLAT symbol is added
>>>
>>> Changes since v1:
>>> Rename "plat_dev" to "hsmp_pdev"
>>>
>>>    arch/x86/include/asm/amd_hsmp.h        |   2 +-
>>>    drivers/platform/x86/amd/Makefile      |   2 +-
>>>    drivers/platform/x86/amd/hsmp/Kconfig  |  33 ++++++-
>>>    drivers/platform/x86/amd/hsmp/Makefile |   6 +-
>>>    drivers/platform/x86/amd/hsmp/acpi.c   | 119 ++++++++++++++++++++++--
>>>    drivers/platform/x86/amd/hsmp/hsmp.c   |  25 ++---
>>>    drivers/platform/x86/amd/hsmp/hsmp.h   |   8 +-
>>>    drivers/platform/x86/amd/hsmp/plat.c   | 122 +++++++------------------
>>>    8 files changed, 188 insertions(+), 129 deletions(-)
>>>
>>> diff --git a/arch/x86/include/asm/amd_hsmp.h
>>> b/arch/x86/include/asm/amd_hsmp.h
>>> index 03c2ce3edaf5..ada14e55f9f4 100644
>>> --- a/arch/x86/include/asm/amd_hsmp.h
>>> +++ b/arch/x86/include/asm/amd_hsmp.h
>>> @@ -5,7 +5,7 @@
>>>      #include <uapi/asm/amd_hsmp.h>
>>>    -#if IS_ENABLED(CONFIG_AMD_HSMP)
>>> +#if IS_ENABLED(CONFIG_AMD_HSMP) || IS_ENABLED(CONFIG_AMD_HSMP_ACPI)
>>>    int hsmp_send_message(struct hsmp_message *msg);
>>>    #else
>>>    static inline int hsmp_send_message(struct hsmp_message *msg)
>>> diff --git a/drivers/platform/x86/amd/Makefile
>>> b/drivers/platform/x86/amd/Makefile
>>> index 96ec24c8701b..f0b2fe81c685 100644
>>> --- a/drivers/platform/x86/amd/Makefile
>>> +++ b/drivers/platform/x86/amd/Makefile
>>> @@ -5,6 +5,6 @@
>>>    #
>>>      obj-$(CONFIG_AMD_PMC)           += pmc/
>>> -obj-y                              += hsmp/
>>> +obj-$(CONFIG_AMD_HSMP)             += hsmp/
>>>    obj-$(CONFIG_AMD_PMF)             += pmf/
>>>    obj-$(CONFIG_AMD_WBRF)            += wbrf.o
>>> diff --git a/drivers/platform/x86/amd/hsmp/Kconfig
>>> b/drivers/platform/x86/amd/hsmp/Kconfig
>>> index b55d4ed9bceb..23fb98066225 100644
>>> --- a/drivers/platform/x86/amd/hsmp/Kconfig
>>> +++ b/drivers/platform/x86/amd/hsmp/Kconfig
>>> @@ -4,14 +4,39 @@
>>>    #
>>>      config AMD_HSMP
>>> -   tristate "AMD HSMP Driver"
>>> -   depends on AMD_NB && X86_64 && ACPI
>>> +   tristate "AMD Host System Management Port driver"
>>> +   depends on AMD_NB
>>>      help
>>> +     Host System Management Port (HSMP) interface is a mailbox interface
>>> +     between the x86 core and the System Management Unit (SMU) firmware.
>>>        The driver provides a way for user space tools to monitor and manage
>>>        system management functionality on EPYC server CPUs from AMD.
>>>    -   Host System Management Port (HSMP) interface is a mailbox interface
>>> -     between the x86 core and the System Management Unit (SMU) firmware.
>>> +menu "AMD HSMP Probe"
>>> +   depends on AMD_HSMP
>>> +
>>> +config AMD_HSMP_ACPI
>>> +   tristate "ACPI based probe"
>>> +   depends on ACPI
>>> +   help
>>> +     This driver supports ACPI based probing.
>>> +
>>> +     You may enable this, if your platform bios provides an ACPI object
>>> +     as described in the documentation.
>>>                If you choose to compile this driver as a module the module will be
>>>        called amd_hsmp.
>>> +
>>> +config AMD_HSMP_PLAT
>>> +   tristate "Platform device based probe"
>>> +   depends on AMD_HSMP_ACPI=n
>>> +   help
>>> +     This driver supports platform device based probing.
>>> +
>>> +     You may enable this, if your platform bios does not provide
>>> +     HSMP ACPI object.
>>> +
>>> +     If you choose to compile this driver as a module the module will be
>>> +     called amd_hsmp.
>>> +
>>> +endmenu
>>> diff --git a/drivers/platform/x86/amd/hsmp/Makefile
>>> b/drivers/platform/x86/amd/hsmp/Makefile
>>> index 0cc92865c0a2..18d9a0d1e8c5 100644
>>> --- a/drivers/platform/x86/amd/hsmp/Makefile
>>> +++ b/drivers/platform/x86/amd/hsmp/Makefile
>>> @@ -4,5 +4,7 @@
>>>    # AMD HSMP Driver
>>>    #
>>>    -obj-$(CONFIG_AMD_HSMP)           += amd_hsmp.o
>>> -amd_hsmp-objs                      := hsmp.o plat.o acpi.o
>>> +obj-$(CONFIG_AMD_HSMP)                     += amd_hsmp.o
>>> +amd_hsmp-objs                              := hsmp.o
>>> +amd_hsmp-$(CONFIG_AMD_HSMP_PLAT)   += plat.o
>>> +amd_hsmp-$(CONFIG_AMD_HSMP_ACPI)   += acpi.o
>>> diff --git a/drivers/platform/x86/amd/hsmp/acpi.c
>>> b/drivers/platform/x86/amd/hsmp/acpi.c
>>> index 46cb86d5d550..86100943aadc 100644
>>> --- a/drivers/platform/x86/amd/hsmp/acpi.c
>>> +++ b/drivers/platform/x86/amd/hsmp/acpi.c
>>> @@ -11,29 +11,43 @@
>>>      #include "hsmp.h"
>>>    +#include <asm/amd_nb.h>
>>> +
>>>    #include <linux/acpi.h>
>>>    #include <linux/device.h>
>>>    #include <linux/dev_printk.h>
>>>    #include <linux/ioport.h>
>>>    #include <linux/kstrtox.h>
>>> +#include <linux/platform_device.h>
>>>    #include <linux/uuid.h>
>>>      #include <uapi/asm-generic/errno-base.h>
>>>    +#define DRIVER_NAME              "amd_hsmp"
>>> +#define DRIVER_VERSION             "2.3"
>>> +#define ACPI_HSMP_DEVICE_HID       "AMDI0097"
>>> +
>>>    /* These are the strings specified in ACPI table */
>>>    #define MSG_IDOFF_STR             "MsgIdOffset"
>>>    #define MSG_ARGOFF_STR            "MsgArgOffset"
>>>    #define MSG_RESPOFF_STR           "MsgRspOffset"
>>>    -void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
>>> -                   u32 *value, bool write)
>>> +static int amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
>>> +                         u32 *value, bool write)
>>>    {
>>>      if (write)
>>>              iowrite32(*value, sock->virt_base_addr + offset);
>>>      else
>>>              *value = ioread32(sock->virt_base_addr + offset);
>>> +   return 0;
>>>    }
>>>    +static const struct file_operations hsmp_fops = {
>>> +   .owner          = THIS_MODULE,
>>> +   .unlocked_ioctl = hsmp_ioctl,
>>> +   .compat_ioctl   = hsmp_ioctl,
>>> +};
>>> +
>>>    /* This is the UUID used for HSMP */
>>>    static const guid_t acpi_hsmp_uuid = GUID_INIT(0xb74d619d, 0x5707, 0x48bd,
>>>                                              0xa6, 0x9f, 0x4e, 0xa2,
>>> @@ -194,9 +208,9 @@ static int hsmp_parse_acpi_table(struct device *dev, u16
>>> sock_ind)
>>>      struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
>>>      int ret;
>>>    - sock->sock_ind                  = sock_ind;
>>> -   sock->dev                       = dev;
>>> -   hsmp_pdev.is_acpi_device        = true;
>>> +   sock->sock_ind          = sock_ind;
>>> +   sock->dev               = dev;
>>> +   sock->amd_hsmp_rdwr     = amd_hsmp_acpi_rdwr;
>>>              sema_init(&sock->hsmp_sem, 1);
>>>    @@ -209,7 +223,7 @@ static int hsmp_parse_acpi_table(struct device *dev,
>>> u16 sock_ind)
>>>      return hsmp_read_acpi_dsd(sock);
>>>    }
>>>    -int hsmp_create_acpi_sysfs_if(struct device *dev)
>>> +static int hsmp_create_acpi_sysfs_if(struct device *dev)
>>>    {
>>>      struct attribute_group *attr_grp;
>>>      u16 sock_ind;
>>> @@ -232,7 +246,7 @@ int hsmp_create_acpi_sysfs_if(struct device *dev)
>>>      return devm_device_add_group(dev, attr_grp);
>>>    }
>>>    -int init_acpi(struct device *dev)
>>> +static int init_acpi(struct device *dev)
>>>    {
>>>      u16 sock_ind;
>>>      int ret;
>>> @@ -266,3 +280,94 @@ int init_acpi(struct device *dev)
>>>              return ret;
>>>    }
>>> +
>>> +static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
>>> +   {ACPI_HSMP_DEVICE_HID, 0},
>>> +   {}
>>> +};
>>> +MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
>>> +
>>> +static bool check_acpi_support(struct device *dev)
>>> +{
>>> +   struct acpi_device *adev = ACPI_COMPANION(dev);
>>> +
>>> +   if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
>>> +           return true;
>>> +
>>> +   return false;
>>> +}
>>> +
>>> +static int hsmp_acpi_probe(struct platform_device *pdev)
>>> +{
>>> +   int ret;
>>> +
>>> +   if (!hsmp_pdev.is_probed) {
>>> +           hsmp_pdev.num_sockets = amd_nb_num();
>>> +           if (hsmp_pdev.num_sockets == 0 || hsmp_pdev.num_sockets >
>>> MAX_AMD_SOCKETS)
>>> +                   return -ENODEV;
>>> +
>>> +           hsmp_pdev.sock = devm_kcalloc(&pdev->dev,
>>> hsmp_pdev.num_sockets,
>>> +                                         sizeof(*hsmp_pdev.sock),
>>> +                                         GFP_KERNEL);
>>> +           if (!hsmp_pdev.sock)
>>> +                   return -ENOMEM;
>>> +   }
>>> +
>>> +   if (!check_acpi_support(&pdev->dev)) {
>>> +           dev_err(&pdev->dev, "Not ACPI device?\n");
>>> +           return -ENODEV;
>>> +   }
>>> +
>>> +   ret = init_acpi(&pdev->dev);
>>> +   if (ret) {
>>> +           dev_err(&pdev->dev, "Failed to initialize HSMP interface.\n");
>>> +           return ret;
>>> +   }
>>> +
>>> +   ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
>>> +   if (ret)
>>> +           dev_err(&pdev->dev, "Failed to create HSMP sysfs
>>> interface\n");
>>> +
>>> +   if (!hsmp_pdev.is_probed) {
>>> +           hsmp_pdev.mdev.name     = HSMP_CDEV_NAME;
>>> +           hsmp_pdev.mdev.minor    = MISC_DYNAMIC_MINOR;
>>> +           hsmp_pdev.mdev.fops     = &hsmp_fops;
>>> +           hsmp_pdev.mdev.parent   = &pdev->dev;
>>> +           hsmp_pdev.mdev.nodename = HSMP_DEVNODE_NAME;
>>> +           hsmp_pdev.mdev.mode     = 0644;
>>> +
>>> +           ret = misc_register(&hsmp_pdev.mdev);
>>> +           if (ret)
>>> +                   return ret;
>>> +           hsmp_pdev.is_probed = true;
>>> +   }
>>> +
>>> +   return 0;
>>> +}
>>> +
>>> +static void hsmp_acpi_remove(struct platform_device *pdev)
>>> +{
>>> +   /*
>>> +    * We register only one misc_device even on multi-socket system.
>>> +    * So, deregister should happen only once.
>>> +    */
>>> +   if (hsmp_pdev.is_probed) {
>>> +           misc_deregister(&hsmp_pdev.mdev);
>>> +           hsmp_pdev.is_probed = false;
>>> +   }
>>> +}
>>> +
>>> +static struct platform_driver amd_hsmp_driver = {
>>> +   .probe          = hsmp_acpi_probe,
>>> +   .remove_new     = hsmp_acpi_remove,
>>> +   .driver         = {
>>> +           .name   = DRIVER_NAME,
>>> +           .acpi_match_table = amd_hsmp_acpi_ids,
>>> +   },
>>> +};
>>> +
>>> +module_platform_driver(amd_hsmp_driver);
>>> +
>>> +MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver");
>>> +MODULE_VERSION(DRIVER_VERSION);
>>> +MODULE_LICENSE("GPL v2");
>>> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c
>>> b/drivers/platform/x86/amd/hsmp/hsmp.c
>>> index 14edaace4379..759ec1d4d60d 100644
>>> --- a/drivers/platform/x86/amd/hsmp/hsmp.c
>>> +++ b/drivers/platform/x86/amd/hsmp/hsmp.c
>>> @@ -31,17 +31,6 @@
>>>      struct hsmp_plat_device hsmp_pdev;
>>>    -static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 offset,
>>> -                    u32 *value, bool write)
>>> -{
>>> -   if (hsmp_pdev.is_acpi_device)
>>> -           amd_hsmp_acpi_rdwr(sock, offset, value, write);
>>> -   else
>>> -           return amd_hsmp_pci_rdwr(sock, offset, value, write);
>>> -
>>> -   return 0;
>>> -}
>>> -
>>>    /*
>>>     * Send a message to the HSMP port via PCI-e config space registers
>>>     * or by writing to MMIO space.
>>> @@ -64,7 +53,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock,
>>> struct hsmp_message *ms
>>>              /* Clear the status register */
>>>      mbox_status = HSMP_STATUS_NOT_READY;
>>> -   ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status,
>>> HSMP_WR);
>>> +   ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status,
>>> HSMP_WR);
>>>      if (ret) {
>>>              pr_err("Error %d clearing mailbox status register\n", ret);
>>>              return ret;
>>> @@ -73,8 +62,8 @@ static int __hsmp_send_message(struct hsmp_socket *sock,
>>> struct hsmp_message *ms
>>>      index = 0;
>>>      /* Write any message arguments */
>>>      while (index < msg->num_args) {
>>> -           ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
>>> -                               &msg->args[index], HSMP_WR);
>>> +           ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index
>>> << 2),
>>> +                                     &msg->args[index], HSMP_WR);
>>>              if (ret) {
>>>                      pr_err("Error %d writing message argument %d\n", ret,
>>> index);
>>>                      return ret;
>>> @@ -83,7 +72,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock,
>>> struct hsmp_message *ms
>>>      }
>>>              /* Write the message ID which starts the operation */
>>> -   ret = amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id, HSMP_WR);
>>> +   ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id,
>>> HSMP_WR);
>>>      if (ret) {
>>>              pr_err("Error %d writing message ID %u\n", ret, msg->msg_id);
>>>              return ret;
>>> @@ -100,7 +89,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock,
>>> struct hsmp_message *ms
>>>      timeout = jiffies + msecs_to_jiffies(HSMP_MSG_TIMEOUT);
>>>              while (time_before(jiffies, timeout)) {
>>> -           ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status,
>>> HSMP_RD);
>>> +           ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off,
>>> &mbox_status, HSMP_RD);
>>>              if (ret) {
>>>                      pr_err("Error %d reading mailbox status\n", ret);
>>>                      return ret;
>>> @@ -135,8 +124,8 @@ static int __hsmp_send_message(struct hsmp_socket *sock,
>>> struct hsmp_message *ms
>>>       */
>>>      index = 0;
>>>      while (index < msg->response_sz) {
>>> -           ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
>>> -                               &msg->args[index], HSMP_RD);
>>> +           ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index
>>> << 2),
>>> +                                     &msg->args[index], HSMP_RD);
>>>              if (ret) {
>>>                      pr_err("Error %d reading response %u for message
>>> ID:%u\n",
>>>                             ret, index, msg->msg_id);
>>> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h
>>> b/drivers/platform/x86/amd/hsmp/hsmp.h
>>> index a77887d298b6..5d4fc7735a87 100644
>>> --- a/drivers/platform/x86/amd/hsmp/hsmp.h
>>> +++ b/drivers/platform/x86/amd/hsmp/hsmp.h
>>> @@ -41,6 +41,7 @@ struct hsmp_socket {
>>>      struct pci_dev *root;
>>>      struct device *dev;
>>>      u16 sock_ind;
>>> +   int (*amd_hsmp_rdwr)(struct hsmp_socket *sock, u32 off, u32 *val, bool
>>> rw);
>>>    };
>>>      struct hsmp_plat_device {
>>> @@ -48,19 +49,14 @@ struct hsmp_plat_device {
>>>      struct hsmp_socket *sock;
>>>      u32 proto_ver;
>>>      u16 num_sockets;
>>> -   bool is_acpi_device;
>>>      bool is_probed;
>>>    };
>>>      extern struct hsmp_plat_device hsmp_pdev;
>>>    -int init_acpi(struct device *dev);
>>>    ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
>>>                           struct bin_attribute *bin_attr, char *buf,
>>>                           loff_t off, size_t count);
>>> -int hsmp_create_acpi_sysfs_if(struct device *dev);
>>> -int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
>>> -                 u32 *value, bool write);
>>>    int hsmp_cache_proto_ver(u16 sock_ind);
>>>    long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
>>>    umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
>>> @@ -68,6 +64,4 @@ umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
>>>    int hsmp_create_attr_list(struct attribute_group *attr_grp,
>>>                        struct device *dev, u16 sock_ind);
>>>    int hsmp_test(u16 sock_ind, u32 value);
>>> -void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
>>> -                   u32 *value, bool write);
>>>    #endif /* HSMP_H */
>>> diff --git a/drivers/platform/x86/amd/hsmp/plat.c
>>> b/drivers/platform/x86/amd/hsmp/plat.c
>>> index c297540bb64c..3bce2c570f2b 100644
>>> --- a/drivers/platform/x86/amd/hsmp/plat.c
>>> +++ b/drivers/platform/x86/amd/hsmp/plat.c
>>> @@ -13,15 +13,13 @@
>>>      #include <asm/amd_nb.h>
>>>    -#include <linux/acpi.h>
>>>    #include <linux/device.h>
>>>    #include <linux/module.h>
>>>    #include <linux/pci.h>
>>>    #include <linux/platform_device.h>
>>>      #define DRIVER_NAME             "amd_hsmp"
>>> -#define DRIVER_VERSION             "2.2"
>>> -#define ACPI_HSMP_DEVICE_HID       "AMDI0097"
>>> +#define DRIVER_VERSION             "2.3"
>>>      /*
>>>     * To access specific HSMP mailbox register, s/w writes the SMN address of
>>> HSMP mailbox
>>> @@ -37,8 +35,8 @@
>>>    #define HSMP_INDEX_REG            0xc4
>>>    #define HSMP_DATA_REG             0xc8
>>>    -int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
>>> -                 u32 *value, bool write)
>>> +static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
>>> +                        u32 *value, bool write)
>>>    {
>>>      int ret;
>>>    @@ -113,6 +111,7 @@ static int init_platform_device(struct device *dev)
>>>              sock->sock_ind                  = i;
>>>              sock->dev                       = dev;
>>>              sock->mbinfo.base_addr          = SMN_HSMP_BASE;
>>> +           sock->amd_hsmp_rdwr             = amd_hsmp_pci_rdwr;
>>>                      /*
>>>               * This is a transitional change from non-ACPI to ACPI, only
>>> @@ -146,89 +145,39 @@ static int init_platform_device(struct device *dev)
>>>      return 0;
>>>    }
>>>    -static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
>>> -   {ACPI_HSMP_DEVICE_HID, 0},
>>> -   {}
>>> -};
>>> -MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
>>> -
>>> -static bool check_acpi_support(struct device *dev)
>>> -{
>>> -   struct acpi_device *adev = ACPI_COMPANION(dev);
>>> -
>>> -   if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
>>> -           return true;
>>> -
>>> -   return false;
>>> -}
>>> -
>>>    static int hsmp_pltdrv_probe(struct platform_device *pdev)
>>>    {
>>>      int ret;
>>>    - /*
>>> -    * On ACPI supported BIOS, there is an ACPI HSMP device added for
>>> -    * each socket, so the per socket probing, but the memory allocated
>>> for
>>> -    * sockets should be contiguous to access it as an array,
>>> -    * Hence allocate memory for all the sockets at once instead of
>>> allocating
>>> -    * on each probe.
>>> -    */
>>> -   if (!hsmp_pdev.is_probed) {
>>> -           hsmp_pdev.sock = devm_kcalloc(&pdev->dev,
>>> hsmp_pdev.num_sockets,
>>> -                                         sizeof(*hsmp_pdev.sock),
>>> -                                         GFP_KERNEL);
>>> -           if (!hsmp_pdev.sock)
>>> -                   return -ENOMEM;
>>> -   }
>>> +   hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
>>> +                                 sizeof(*hsmp_pdev.sock),
>>> +                                 GFP_KERNEL);
>>> +   if (!hsmp_pdev.sock)
>>> +           return -ENOMEM;
>>>    - if (check_acpi_support(&pdev->dev)) {
>>> -           ret = init_acpi(&pdev->dev);
>>> -           if (ret) {
>>> -                   dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
>>> -                   return ret;
>>> -           }
>>> -           ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
>>> -           if (ret)
>>> -                   dev_err(&pdev->dev, "Failed to create HSMP sysfs
>>> interface\n");
>>> -   } else {
>>> -           ret = init_platform_device(&pdev->dev);
>>> -           if (ret) {
>>> -                   dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
>>> -                   return ret;
>>> -           }
>>> -           ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
>>> -           if (ret)
>>> -                   dev_err(&pdev->dev, "Failed to create HSMP sysfs
>>> interface\n");
>>> +   ret = init_platform_device(&pdev->dev);
>>> +   if (ret) {
>>> +           dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
>>> +           return ret;
>>>      }
>>>    - if (!hsmp_pdev.is_probed) {
>>> -           hsmp_pdev.mdev.name     = HSMP_CDEV_NAME;
>>> -           hsmp_pdev.mdev.minor    = MISC_DYNAMIC_MINOR;
>>> -           hsmp_pdev.mdev.fops     = &hsmp_fops;
>>> -           hsmp_pdev.mdev.parent   = &pdev->dev;
>>> -           hsmp_pdev.mdev.nodename = HSMP_DEVNODE_NAME;
>>> -           hsmp_pdev.mdev.mode     = 0644;
>>> -
>>> -           ret = misc_register(&hsmp_pdev.mdev);
>>> -           if (ret)
>>> -                   return ret;
>>> +   ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
>>> +   if (ret)
>>> +           dev_err(&pdev->dev, "Failed to create HSMP sysfs
>>> interface\n");
>>>    -         hsmp_pdev.is_probed = true;
>>> -   }
>>> +   hsmp_pdev.mdev.name     = HSMP_CDEV_NAME;
>>> +   hsmp_pdev.mdev.minor    = MISC_DYNAMIC_MINOR;
>>> +   hsmp_pdev.mdev.fops     = &hsmp_fops;
>>> +   hsmp_pdev.mdev.parent   = &pdev->dev;
>>> +   hsmp_pdev.mdev.nodename = HSMP_DEVNODE_NAME;
>>> +   hsmp_pdev.mdev.mode     = 0644;
>>>    - return 0;
>>> +   return misc_register(&hsmp_pdev.mdev);
>>>    }
>>>      static void hsmp_pltdrv_remove(struct platform_device *pdev)
>>>    {
>>> -   /*
>>> -    * We register only one misc_device even on multi socket system.
>>> -    * So, deregister should happen only once.
>>> -    */
>>> -   if (hsmp_pdev.is_probed) {
>>> -           misc_deregister(&hsmp_pdev.mdev);
>>> -           hsmp_pdev.is_probed = false;
>>> -   }
>>> +   misc_deregister(&hsmp_pdev.mdev);
>>>    }
>>>      static struct platform_driver amd_hsmp_driver = {
>>> @@ -236,7 +185,6 @@ static struct platform_driver amd_hsmp_driver = {
>>>      .remove_new     = hsmp_pltdrv_remove,
>>>      .driver         = {
>>>              .name   = DRIVER_NAME,
>>> -           .acpi_match_table = amd_hsmp_acpi_ids,
>>>      },
>>>    };
>>>    @@ -295,6 +243,12 @@ static int __init hsmp_plt_init(void)
>>>    {
>>>      int ret = -ENODEV;
>>>    + if (!legacy_hsmp_support()) {
>>> +           pr_info("HSMP is not supported on Family:%x model:%x\n",
>>> +                   boot_cpu_data.x86, boot_cpu_data.x86_model);
>>> +           return ret;
>>> +   }
>>> +
>>>      /*
>>>       * amd_nb_num() returns number of SMN/DF interfaces present in the
>>> system
>>>       * if we have N SMN/DF interfaces that ideally means N sockets
>>> @@ -307,19 +261,9 @@ static int __init hsmp_plt_init(void)
>>>      if (ret)
>>>              return ret;
>>>    - if (!hsmp_pdev.is_acpi_device) {
>>> -           if (legacy_hsmp_support()) {
>>> -                   /* Not ACPI device, but supports HSMP, register a
>>> plat_dev */
>>> -                   ret = hsmp_plat_dev_register();
>>> -           } else {
>>> -                   /* Not ACPI, Does not support HSMP */
>>> -                   pr_info("HSMP is not supported on Family:%x
>>> model:%x\n",
>>> -                           boot_cpu_data.x86, boot_cpu_data.x86_model);
>>> -                   ret = -ENODEV;
>>> -           }
>>> -           if (ret)
>>> -                   platform_driver_unregister(&amd_hsmp_driver);
>>> -   }
>>> +   ret = hsmp_plat_dev_register();
>>> +   if (ret)
>>> +           platform_driver_unregister(&amd_hsmp_driver);
>>>              return ret;
>>>    }

Thanks and Regards,

Suma


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory
  2024-07-20 17:45 [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Suma Hegde
                   ` (9 preceding siblings ...)
  2024-07-20 17:45 ` [v3 11/11] platform/x86/amd/hsmp: Fix potential spectre issue Suma Hegde
@ 2024-08-07 11:33 ` Ilpo Järvinen
  10 siblings, 0 replies; 21+ messages in thread
From: Ilpo Järvinen @ 2024-08-07 11:33 UTC (permalink / raw)
  To: Suma Hegde; +Cc: platform-driver-x86, Hans de Goede, Naveen Krishna Chatradhi

[-- Attachment #1: Type: text/plain, Size: 4475 bytes --]

On Sat, 20 Jul 2024, Suma Hegde wrote:

> This is in preparation to splitting ACPI and platform device drivers.
> Create and move hsmp specific code into its own directory,
> no logical changes.
> 
> Signed-off-by: Suma Hegde <suma.hegde@amd.com>
> Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>

Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

-- 
 i.

> ---
> Changes since v2:
> None
> Changes since v1:
> None
> 
>  MAINTAINERS                                |  2 +-
>  drivers/platform/x86/amd/Kconfig           | 14 +-------------
>  drivers/platform/x86/amd/Makefile          |  3 +--
>  drivers/platform/x86/amd/hsmp/Kconfig      | 17 +++++++++++++++++
>  drivers/platform/x86/amd/hsmp/Makefile     |  8 ++++++++
>  drivers/platform/x86/amd/{ => hsmp}/hsmp.c |  0
>  6 files changed, 28 insertions(+), 16 deletions(-)
>  create mode 100644 drivers/platform/x86/amd/hsmp/Kconfig
>  create mode 100644 drivers/platform/x86/amd/hsmp/Makefile
>  rename drivers/platform/x86/amd/{ => hsmp}/hsmp.c (100%)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d6c90161c7bf..a7d79d1f7ec1 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1037,7 +1037,7 @@ S:	Maintained
>  F:	Documentation/arch/x86/amd_hsmp.rst
>  F:	arch/x86/include/asm/amd_hsmp.h
>  F:	arch/x86/include/uapi/asm/amd_hsmp.h
> -F:	drivers/platform/x86/amd/hsmp.c
> +F:	drivers/platform/x86/amd/hsmp/
>  
>  AMD IOMMU (AMD-VI)
>  M:	Joerg Roedel <joro@8bytes.org>
> diff --git a/drivers/platform/x86/amd/Kconfig b/drivers/platform/x86/amd/Kconfig
> index f88682d36447..2c671cc17d63 100644
> --- a/drivers/platform/x86/amd/Kconfig
> +++ b/drivers/platform/x86/amd/Kconfig
> @@ -3,22 +3,10 @@
>  # AMD x86 Platform Specific Drivers
>  #
>  
> +source "drivers/platform/x86/amd/hsmp/Kconfig"
>  source "drivers/platform/x86/amd/pmf/Kconfig"
>  source "drivers/platform/x86/amd/pmc/Kconfig"
>  
> -config AMD_HSMP
> -	tristate "AMD HSMP Driver"
> -	depends on AMD_NB && X86_64 && ACPI
> -	help
> -	  The driver provides a way for user space tools to monitor and manage
> -	  system management functionality on EPYC server CPUs from AMD.
> -
> -	  Host System Management Port (HSMP) interface is a mailbox interface
> -	  between the x86 core and the System Management Unit (SMU) firmware.
> -
> -	  If you choose to compile this driver as a module the module will be
> -	  called amd_hsmp.
> -
>  config AMD_WBRF
>  	bool "AMD Wifi RF Band mitigations (WBRF)"
>  	depends on ACPI
> diff --git a/drivers/platform/x86/amd/Makefile b/drivers/platform/x86/amd/Makefile
> index dcec0a46f8af..96ec24c8701b 100644
> --- a/drivers/platform/x86/amd/Makefile
> +++ b/drivers/platform/x86/amd/Makefile
> @@ -5,7 +5,6 @@
>  #
>  
>  obj-$(CONFIG_AMD_PMC)		+= pmc/
> -amd_hsmp-y			:= hsmp.o
> -obj-$(CONFIG_AMD_HSMP)		+= amd_hsmp.o
> +obj-y				+= hsmp/
>  obj-$(CONFIG_AMD_PMF)		+= pmf/
>  obj-$(CONFIG_AMD_WBRF)		+= wbrf.o
> diff --git a/drivers/platform/x86/amd/hsmp/Kconfig b/drivers/platform/x86/amd/hsmp/Kconfig
> new file mode 100644
> index 000000000000..b55d4ed9bceb
> --- /dev/null
> +++ b/drivers/platform/x86/amd/hsmp/Kconfig
> @@ -0,0 +1,17 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# AMD HSMP Driver
> +#
> +
> +config AMD_HSMP
> +	tristate "AMD HSMP Driver"
> +	depends on AMD_NB && X86_64 && ACPI
> +	help
> +	  The driver provides a way for user space tools to monitor and manage
> +	  system management functionality on EPYC server CPUs from AMD.
> +
> +	  Host System Management Port (HSMP) interface is a mailbox interface
> +	  between the x86 core and the System Management Unit (SMU) firmware.
> +
> +	  If you choose to compile this driver as a module the module will be
> +	  called amd_hsmp.
> diff --git a/drivers/platform/x86/amd/hsmp/Makefile b/drivers/platform/x86/amd/hsmp/Makefile
> new file mode 100644
> index 000000000000..fda64906a5e8
> --- /dev/null
> +++ b/drivers/platform/x86/amd/hsmp/Makefile
> @@ -0,0 +1,8 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Makefile for drivers/platform/x86/amd/hsmp
> +# AMD HSMP Driver
> +#
> +
> +obj-$(CONFIG_AMD_HSMP)		+= amd_hsmp.o
> +amd_hsmp-objs			:= hsmp.o
> diff --git a/drivers/platform/x86/amd/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
> similarity index 100%
> rename from drivers/platform/x86/amd/hsmp.c
> rename to drivers/platform/x86/amd/hsmp/hsmp.c
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [v3 03/11] platform/x86/amd/hsmp: Move structure and macros to header file
  2024-07-20 17:45 ` [v3 03/11] platform/x86/amd/hsmp: Move structure and macros to header file Suma Hegde
@ 2024-08-07 11:39   ` Ilpo Järvinen
  0 siblings, 0 replies; 21+ messages in thread
From: Ilpo Järvinen @ 2024-08-07 11:39 UTC (permalink / raw)
  To: Suma Hegde; +Cc: platform-driver-x86, Hans de Goede, Naveen Krishna Chatradhi

[-- Attachment #1: Type: text/plain, Size: 4366 bytes --]

On Sat, 20 Jul 2024, Suma Hegde wrote:

> This is in preparation to splitting ACPI and platform device drivers.
> No logical change, move common structures and macros to hsmp.h
> 
> Signed-off-by: Suma Hegde <suma.hegde@amd.com>
> Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> ---
> Changes since v2:
> None
> Changes since v1:
> 1. Correct typo mistake in commit message
> 2. Add "Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>"
> 3. Arrange header files in alphabetical order for hsmp.h
> 
>  drivers/platform/x86/amd/hsmp/hsmp.c | 42 ++--------------------
>  drivers/platform/x86/amd/hsmp/hsmp.h | 54 ++++++++++++++++++++++++++++
>  2 files changed, 56 insertions(+), 40 deletions(-)
>  create mode 100644 drivers/platform/x86/amd/hsmp/hsmp.h
> 
> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
> index 10ab9b2437f1..2c9ba51b9614 100644
> --- a/drivers/platform/x86/amd/hsmp/hsmp.c
> +++ b/drivers/platform/x86/amd/hsmp/hsmp.c
> @@ -9,15 +9,14 @@
>  
>  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>  
> +#include "hsmp.h"
> +
>  #include <asm/amd_hsmp.h>
>  #include <asm/amd_nb.h>
>  #include <linux/delay.h>
> -#include <linux/io.h>
> -#include <linux/miscdevice.h>
>  #include <linux/module.h>
>  #include <linux/pci.h>
>  #include <linux/platform_device.h>
> -#include <linux/semaphore.h>
>  #include <linux/acpi.h>
>  
>  #define DRIVER_NAME		"amd_hsmp"
> @@ -51,48 +50,11 @@
>  #define HSMP_INDEX_REG		0xc4
>  #define HSMP_DATA_REG		0xc8
>  
> -#define HSMP_CDEV_NAME		"hsmp_cdev"
> -#define HSMP_DEVNODE_NAME	"hsmp"
> -#define HSMP_METRICS_TABLE_NAME	"metrics_bin"
> -
> -#define HSMP_ATTR_GRP_NAME_SIZE	10
> -
>  /* These are the strings specified in ACPI table */
>  #define MSG_IDOFF_STR		"MsgIdOffset"
>  #define MSG_ARGOFF_STR		"MsgArgOffset"
>  #define MSG_RESPOFF_STR		"MsgRspOffset"
>  
> -#define MAX_AMD_SOCKETS 8
> -
> -struct hsmp_mbaddr_info {
> -	u32 base_addr;
> -	u32 msg_id_off;
> -	u32 msg_resp_off;
> -	u32 msg_arg_off;
> -	u32 size;
> -};
> -
> -struct hsmp_socket {
> -	struct bin_attribute hsmp_attr;
> -	struct hsmp_mbaddr_info mbinfo;
> -	void __iomem *metric_tbl_addr;
> -	void __iomem *virt_base_addr;
> -	struct semaphore hsmp_sem;
> -	char name[HSMP_ATTR_GRP_NAME_SIZE];
> -	struct pci_dev *root;
> -	struct device *dev;
> -	u16 sock_ind;
> -};
> -
> -struct hsmp_plat_device {
> -	struct miscdevice hsmp_device;
> -	struct hsmp_socket *sock;
> -	u32 proto_ver;
> -	u16 num_sockets;
> -	bool is_acpi_device;
> -	bool is_probed;
> -};
> -
>  static struct hsmp_plat_device plat_dev;
>  
>  static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
> new file mode 100644
> index 000000000000..5afc7167fac1
> --- /dev/null
> +++ b/drivers/platform/x86/amd/hsmp/hsmp.h
> @@ -0,0 +1,54 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * AMD HSMP Platform Driver
> + * Copyright (c) 2024, AMD.
> + * All Rights Reserved.
> + *
> + * Header file for HSMP driver
> + */
> +
> +#ifndef HSMP_H
> +#define HSMP_H
> +
> +#include <linux/io.h>
> +#include <linux/miscdevice.h>
> +#include <linux/semaphore.h>
> +
> +#define HSMP_METRICS_TABLE_NAME	"metrics_bin"
> +
> +#define HSMP_ATTR_GRP_NAME_SIZE	10
> +
> +#define MAX_AMD_SOCKETS 8
> +
> +#define HSMP_CDEV_NAME		"hsmp_cdev"
> +#define HSMP_DEVNODE_NAME	"hsmp"
> +
> +struct hsmp_mbaddr_info {
> +	u32 base_addr;
> +	u32 msg_id_off;
> +	u32 msg_resp_off;
> +	u32 msg_arg_off;
> +	u32 size;
> +};
> +
> +struct hsmp_socket {
> +	struct bin_attribute hsmp_attr;

This requires #include <linux/sysfs.h>

-- 
 i.

> +	struct hsmp_mbaddr_info mbinfo;
> +	void __iomem *metric_tbl_addr;
> +	void __iomem *virt_base_addr;
> +	struct semaphore hsmp_sem;
> +	char name[HSMP_ATTR_GRP_NAME_SIZE];
> +	struct pci_dev *root;
> +	struct device *dev;
> +	u16 sock_ind;
> +};
> +
> +struct hsmp_plat_device {
> +	struct miscdevice hsmp_device;
> +	struct hsmp_socket *sock;
> +	u32 proto_ver;
> +	u16 num_sockets;
> +	bool is_acpi_device;
> +	bool is_probed;
> +};
> +#endif /* HSMP_H */
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [v3 07/11] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers
  2024-07-20 17:45 ` [v3 07/11] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers Suma Hegde
  2024-07-30  6:16   ` Suma Hegde
@ 2024-08-07 12:31   ` Ilpo Järvinen
  2024-08-07 14:17   ` Ilpo Järvinen
  2 siblings, 0 replies; 21+ messages in thread
From: Ilpo Järvinen @ 2024-08-07 12:31 UTC (permalink / raw)
  To: Suma Hegde; +Cc: platform-driver-x86, Hans de Goede, Naveen Krishna Chatradhi

On Sat, 20 Jul 2024, Suma Hegde wrote:

> Separate the probes for ACPI and platform device drivers.
> Provide a Kconfig option to select either the
> ACPI or the platform device based driver.
> 
> Signed-off-by: Suma Hegde <suma.hegde@amd.com>
> Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
> ---
> Changes since v2:
> Following files are modified to add new symbol
>  - drivers/platform/x86/amd/hsmp/Kconfig, 
>  - drivers/platform/x86/amd/hsmp/Makefile
>  - drivers/platform/x86/amd/Makefile
> AMD_HSMP is used as common symbol and new AMD_HSMP_PLAT symbol is added
> 
> Changes since v1:
> Rename "plat_dev" to "hsmp_pdev"
> 
>  arch/x86/include/asm/amd_hsmp.h        |   2 +-
>  drivers/platform/x86/amd/Makefile      |   2 +-
>  drivers/platform/x86/amd/hsmp/Kconfig  |  33 ++++++-
>  drivers/platform/x86/amd/hsmp/Makefile |   6 +-
>  drivers/platform/x86/amd/hsmp/acpi.c   | 119 ++++++++++++++++++++++--
>  drivers/platform/x86/amd/hsmp/hsmp.c   |  25 ++---
>  drivers/platform/x86/amd/hsmp/hsmp.h   |   8 +-
>  drivers/platform/x86/amd/hsmp/plat.c   | 122 +++++++------------------
>  8 files changed, 188 insertions(+), 129 deletions(-)
> 
> diff --git a/arch/x86/include/asm/amd_hsmp.h b/arch/x86/include/asm/amd_hsmp.h
> index 03c2ce3edaf5..ada14e55f9f4 100644
> --- a/arch/x86/include/asm/amd_hsmp.h
> +++ b/arch/x86/include/asm/amd_hsmp.h
> @@ -5,7 +5,7 @@
>  
>  #include <uapi/asm/amd_hsmp.h>
>  
> -#if IS_ENABLED(CONFIG_AMD_HSMP)
> +#if IS_ENABLED(CONFIG_AMD_HSMP) || IS_ENABLED(CONFIG_AMD_HSMP_ACPI)
>  int hsmp_send_message(struct hsmp_message *msg);
>  #else
>  static inline int hsmp_send_message(struct hsmp_message *msg)
> diff --git a/drivers/platform/x86/amd/Makefile b/drivers/platform/x86/amd/Makefile
> index 96ec24c8701b..f0b2fe81c685 100644
> --- a/drivers/platform/x86/amd/Makefile
> +++ b/drivers/platform/x86/amd/Makefile
> @@ -5,6 +5,6 @@
>  #
>  
>  obj-$(CONFIG_AMD_PMC)		+= pmc/
> -obj-y				+= hsmp/
> +obj-$(CONFIG_AMD_HSMP)		+= hsmp/
>  obj-$(CONFIG_AMD_PMF)		+= pmf/
>  obj-$(CONFIG_AMD_WBRF)		+= wbrf.o
> diff --git a/drivers/platform/x86/amd/hsmp/Kconfig b/drivers/platform/x86/amd/hsmp/Kconfig
> index b55d4ed9bceb..23fb98066225 100644
> --- a/drivers/platform/x86/amd/hsmp/Kconfig
> +++ b/drivers/platform/x86/amd/hsmp/Kconfig
> @@ -4,14 +4,39 @@
>  #
>  
>  config AMD_HSMP
> -	tristate "AMD HSMP Driver"
> -	depends on AMD_NB && X86_64 && ACPI
> +	tristate "AMD Host System Management Port driver"
> +	depends on AMD_NB

This SYMBOL shouldn't be user visible at all since it's "library" for the 
other two drivers.

Since the other two will be select this, depends on won't propagate 
correctly so move it to the menu instead.

>  	help
> +	  Host System Management Port (HSMP) interface is a mailbox interface
> +	  between the x86 core and the System Management Unit (SMU) firmware.
>  	  The driver provides a way for user space tools to monitor and manage
>  	  system management functionality on EPYC server CPUs from AMD.
>
> -	  Host System Management Port (HSMP) interface is a mailbox interface
> -	  between the x86 core and the System Management Unit (SMU) firmware.
> +menu "AMD HSMP Probe"
> +	depends on AMD_HSMP

depends on AMD_NB

> +
> +config AMD_HSMP_ACPI
> +	tristate "ACPI based probe"
> +	depends on ACPI

select AMD_HSMP

> +	help
> +	  This driver supports ACPI based probing.
> +
> +	  You may enable this, if your platform bios provides an ACPI object

BIOS

> +	  as described in the documentation.

"in the documentation" ???

>  
>  	  If you choose to compile this driver as a module the module will be
>  	  called amd_hsmp.
> +
> +config AMD_HSMP_PLAT
> +	tristate "Platform device based probe"
> +	depends on AMD_HSMP_ACPI=n

select AMD_HSMP

> +	help
> +	  This driver supports platform device based probing.
> +
> +	  You may enable this, if your platform bios does not provide

BIOS

> +	  HSMP ACPI object.
> +
> +	  If you choose to compile this driver as a module the module will be
> +	  called amd_hsmp.
> +
> +endmenu

You'll probably also want to rewrite some of the string slightly to match 
the changes this causes in the user-visible config entries.

> diff --git a/drivers/platform/x86/amd/hsmp/Makefile b/drivers/platform/x86/amd/hsmp/Makefile
> index 0cc92865c0a2..18d9a0d1e8c5 100644
> --- a/drivers/platform/x86/amd/hsmp/Makefile
> +++ b/drivers/platform/x86/amd/hsmp/Makefile
> @@ -4,5 +4,7 @@
>  # AMD HSMP Driver
>  #
>  
> -obj-$(CONFIG_AMD_HSMP)		+= amd_hsmp.o
> -amd_hsmp-objs			:= hsmp.o plat.o acpi.o
> +obj-$(CONFIG_AMD_HSMP)			+= amd_hsmp.o
> +amd_hsmp-objs				:= hsmp.o
> +amd_hsmp-$(CONFIG_AMD_HSMP_PLAT)	+= plat.o
> +amd_hsmp-$(CONFIG_AMD_HSMP_ACPI)	+= acpi.o
> diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c
> index 46cb86d5d550..86100943aadc 100644
> --- a/drivers/platform/x86/amd/hsmp/acpi.c
> +++ b/drivers/platform/x86/amd/hsmp/acpi.c
> @@ -11,29 +11,43 @@
>  
>  #include "hsmp.h"
>  
> +#include <asm/amd_nb.h>
> +
>  #include <linux/acpi.h>
>  #include <linux/device.h>
>  #include <linux/dev_printk.h>
>  #include <linux/ioport.h>
>  #include <linux/kstrtox.h>
> +#include <linux/platform_device.h>
>  #include <linux/uuid.h>
>  
>  #include <uapi/asm-generic/errno-base.h>
>  
> +#define DRIVER_NAME		"amd_hsmp"
> +#define DRIVER_VERSION		"2.3"
> +#define ACPI_HSMP_DEVICE_HID	"AMDI0097"
> +
>  /* These are the strings specified in ACPI table */
>  #define MSG_IDOFF_STR		"MsgIdOffset"
>  #define MSG_ARGOFF_STR		"MsgArgOffset"
>  #define MSG_RESPOFF_STR		"MsgRspOffset"
>  
> -void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
> -			u32 *value, bool write)
> +static int amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
> +			      u32 *value, bool write)
>  {
>  	if (write)
>  		iowrite32(*value, sock->virt_base_addr + offset);
>  	else
>  		*value = ioread32(sock->virt_base_addr + offset);
> +	return 0;
>  }
>  
> +static const struct file_operations hsmp_fops = {
> +	.owner		= THIS_MODULE,
> +	.unlocked_ioctl	= hsmp_ioctl,
> +	.compat_ioctl	= hsmp_ioctl,
> +};
> +
>  /* This is the UUID used for HSMP */
>  static const guid_t acpi_hsmp_uuid = GUID_INIT(0xb74d619d, 0x5707, 0x48bd,
>  						0xa6, 0x9f, 0x4e, 0xa2,
> @@ -194,9 +208,9 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
>  	struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
>  	int ret;
>  
> -	sock->sock_ind			= sock_ind;
> -	sock->dev			= dev;
> -	hsmp_pdev.is_acpi_device	= true;
> +	sock->sock_ind		= sock_ind;
> +	sock->dev		= dev;
> +	sock->amd_hsmp_rdwr	= amd_hsmp_acpi_rdwr;
>  
>  	sema_init(&sock->hsmp_sem, 1);
>  
> @@ -209,7 +223,7 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
>  	return hsmp_read_acpi_dsd(sock);
>  }
>  
> -int hsmp_create_acpi_sysfs_if(struct device *dev)
> +static int hsmp_create_acpi_sysfs_if(struct device *dev)
>  {
>  	struct attribute_group *attr_grp;
>  	u16 sock_ind;
> @@ -232,7 +246,7 @@ int hsmp_create_acpi_sysfs_if(struct device *dev)
>  	return devm_device_add_group(dev, attr_grp);
>  }
>  
> -int init_acpi(struct device *dev)
> +static int init_acpi(struct device *dev)
>  {
>  	u16 sock_ind;
>  	int ret;
> @@ -266,3 +280,94 @@ int init_acpi(struct device *dev)
>  
>  	return ret;
>  }
> +
> +static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
> +	{ACPI_HSMP_DEVICE_HID, 0},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
> +
> +static bool check_acpi_support(struct device *dev)
> +{
> +	struct acpi_device *adev = ACPI_COMPANION(dev);
> +
> +	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
> +		return true;
> +
> +	return false;
> +}
> +
> +static int hsmp_acpi_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +
> +	if (!hsmp_pdev.is_probed) {
> +		hsmp_pdev.num_sockets = amd_nb_num();
> +		if (hsmp_pdev.num_sockets == 0 || hsmp_pdev.num_sockets > MAX_AMD_SOCKETS)
> +			return -ENODEV;
> +
> +		hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
> +					      sizeof(*hsmp_pdev.sock),
> +					      GFP_KERNEL);

Unrelated to this patch, don't you need a mutex to protect against two 
concurrent probes?

> +		if (!hsmp_pdev.sock)
> +			return -ENOMEM;
> +	}
> +
> +	if (!check_acpi_support(&pdev->dev)) {
> +		dev_err(&pdev->dev, "Not ACPI device?\n");
> +		return -ENODEV;
> +	}
> +
> +	ret = init_acpi(&pdev->dev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed to initialize HSMP interface.\n");
> +		return ret;
> +	}
> +
> +	ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
> +	if (ret)
> +		dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
> +
> +	if (!hsmp_pdev.is_probed) {
> +		hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
> +		hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
> +		hsmp_pdev.mdev.fops	= &hsmp_fops;
> +		hsmp_pdev.mdev.parent	= &pdev->dev;
> +		hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
> +		hsmp_pdev.mdev.mode	= 0644;
> +
> +		ret = misc_register(&hsmp_pdev.mdev);
> +		if (ret)
> +			return ret;
> +		hsmp_pdev.is_probed = true;
> +	}
> +
> +	return 0;
> +}
> +
> +static void hsmp_acpi_remove(struct platform_device *pdev)
> +{
> +	/*
> +	 * We register only one misc_device even on multi-socket system.
> +	 * So, deregister should happen only once.
> +	 */
> +	if (hsmp_pdev.is_probed) {
> +		misc_deregister(&hsmp_pdev.mdev);
> +		hsmp_pdev.is_probed = false;
> +	}
> +}
> +
> +static struct platform_driver amd_hsmp_driver = {
> +	.probe		= hsmp_acpi_probe,
> +	.remove_new	= hsmp_acpi_remove,
> +	.driver		= {
> +		.name	= DRIVER_NAME,
> +		.acpi_match_table = amd_hsmp_acpi_ids,
> +	},
> +};
> +
> +module_platform_driver(amd_hsmp_driver);
> +
> +MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver");
> +MODULE_VERSION(DRIVER_VERSION);
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
> index 14edaace4379..759ec1d4d60d 100644
> --- a/drivers/platform/x86/amd/hsmp/hsmp.c
> +++ b/drivers/platform/x86/amd/hsmp/hsmp.c
> @@ -31,17 +31,6 @@
>  
>  struct hsmp_plat_device hsmp_pdev;
>  
> -static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 offset,
> -			 u32 *value, bool write)
> -{
> -	if (hsmp_pdev.is_acpi_device)
> -		amd_hsmp_acpi_rdwr(sock, offset, value, write);
> -	else
> -		return amd_hsmp_pci_rdwr(sock, offset, value, write);
> -
> -	return 0;
> -}
> -
>  /*
>   * Send a message to the HSMP port via PCI-e config space registers
>   * or by writing to MMIO space.
> @@ -64,7 +53,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
>  
>  	/* Clear the status register */
>  	mbox_status = HSMP_STATUS_NOT_READY;
> -	ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_WR);
> +	ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_WR);
>  	if (ret) {
>  		pr_err("Error %d clearing mailbox status register\n", ret);
>  		return ret;
> @@ -73,8 +62,8 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
>  	index = 0;
>  	/* Write any message arguments */
>  	while (index < msg->num_args) {
> -		ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
> -				    &msg->args[index], HSMP_WR);
> +		ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
> +					  &msg->args[index], HSMP_WR);
>  		if (ret) {
>  			pr_err("Error %d writing message argument %d\n", ret, index);
>  			return ret;
> @@ -83,7 +72,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
>  	}
>  
>  	/* Write the message ID which starts the operation */
> -	ret = amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id, HSMP_WR);
> +	ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_id_off, &msg->msg_id, HSMP_WR);
>  	if (ret) {
>  		pr_err("Error %d writing message ID %u\n", ret, msg->msg_id);
>  		return ret;
> @@ -100,7 +89,7 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
>  	timeout	= jiffies + msecs_to_jiffies(HSMP_MSG_TIMEOUT);
>  
>  	while (time_before(jiffies, timeout)) {
> -		ret = amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_RD);
> +		ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_resp_off, &mbox_status, HSMP_RD);
>  		if (ret) {
>  			pr_err("Error %d reading mailbox status\n", ret);
>  			return ret;
> @@ -135,8 +124,8 @@ static int __hsmp_send_message(struct hsmp_socket *sock, struct hsmp_message *ms
>  	 */
>  	index = 0;
>  	while (index < msg->response_sz) {
> -		ret = amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
> -				    &msg->args[index], HSMP_RD);
> +		ret = sock->amd_hsmp_rdwr(sock, mbinfo->msg_arg_off + (index << 2),
> +					  &msg->args[index], HSMP_RD);
>  		if (ret) {
>  			pr_err("Error %d reading response %u for message ID:%u\n",
>  			       ret, index, msg->msg_id);
> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
> index a77887d298b6..5d4fc7735a87 100644
> --- a/drivers/platform/x86/amd/hsmp/hsmp.h
> +++ b/drivers/platform/x86/amd/hsmp/hsmp.h
> @@ -41,6 +41,7 @@ struct hsmp_socket {
>  	struct pci_dev *root;
>  	struct device *dev;
>  	u16 sock_ind;
> +	int (*amd_hsmp_rdwr)(struct hsmp_socket *sock, u32 off, u32 *val, bool rw);

This should be introduced earlier in the series in a separate patch 
(before the code is moved anywhere so there's no need to have non-static 
rdwr funcs in any stage of the moving).

>  };
>  
>  struct hsmp_plat_device {
> @@ -48,19 +49,14 @@ struct hsmp_plat_device {
>  	struct hsmp_socket *sock;
>  	u32 proto_ver;
>  	u16 num_sockets;
> -	bool is_acpi_device;
>  	bool is_probed;
>  };
>  
>  extern struct hsmp_plat_device hsmp_pdev;
>  
> -int init_acpi(struct device *dev);
>  ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
>  			     struct bin_attribute *bin_attr, char *buf,
>  			     loff_t off, size_t count);
> -int hsmp_create_acpi_sysfs_if(struct device *dev);
> -int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
> -		      u32 *value, bool write);
>  int hsmp_cache_proto_ver(u16 sock_ind);
>  long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
>  umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
> @@ -68,6 +64,4 @@ umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
>  int hsmp_create_attr_list(struct attribute_group *attr_grp,
>  			  struct device *dev, u16 sock_ind);
>  int hsmp_test(u16 sock_ind, u32 value);
> -void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
> -			u32 *value, bool write);
>  #endif /* HSMP_H */
> diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
> index c297540bb64c..3bce2c570f2b 100644
> --- a/drivers/platform/x86/amd/hsmp/plat.c
> +++ b/drivers/platform/x86/amd/hsmp/plat.c
> @@ -13,15 +13,13 @@
>  
>  #include <asm/amd_nb.h>
>  
> -#include <linux/acpi.h>
>  #include <linux/device.h>
>  #include <linux/module.h>
>  #include <linux/pci.h>
>  #include <linux/platform_device.h>
>  
>  #define DRIVER_NAME		"amd_hsmp"
> -#define DRIVER_VERSION		"2.2"
> -#define ACPI_HSMP_DEVICE_HID	"AMDI0097"
> +#define DRIVER_VERSION		"2.3"
>  
>  /*
>   * To access specific HSMP mailbox register, s/w writes the SMN address of HSMP mailbox
> @@ -37,8 +35,8 @@
>  #define HSMP_INDEX_REG		0xc4
>  #define HSMP_DATA_REG		0xc8
>  
> -int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
> -		      u32 *value, bool write)
> +static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
> +			     u32 *value, bool write)
>  {
>  	int ret;
>  
> @@ -113,6 +111,7 @@ static int init_platform_device(struct device *dev)
>  		sock->sock_ind			= i;
>  		sock->dev			= dev;
>  		sock->mbinfo.base_addr		= SMN_HSMP_BASE;
> +		sock->amd_hsmp_rdwr		= amd_hsmp_pci_rdwr;
>  
>  		/*
>  		 * This is a transitional change from non-ACPI to ACPI, only
> @@ -146,89 +145,39 @@ static int init_platform_device(struct device *dev)
>  	return 0;
>  }
>  
> -static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
> -	{ACPI_HSMP_DEVICE_HID, 0},
> -	{}
> -};
> -MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
> -
> -static bool check_acpi_support(struct device *dev)
> -{
> -	struct acpi_device *adev = ACPI_COMPANION(dev);
> -
> -	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
> -		return true;
> -
> -	return false;
> -}
> -
>  static int hsmp_pltdrv_probe(struct platform_device *pdev)
>  {
>  	int ret;
>  
> -	/*
> -	 * On ACPI supported BIOS, there is an ACPI HSMP device added for
> -	 * each socket, so the per socket probing, but the memory allocated for
> -	 * sockets should be contiguous to access it as an array,
> -	 * Hence allocate memory for all the sockets at once instead of allocating
> -	 * on each probe.
> -	 */
> -	if (!hsmp_pdev.is_probed) {
> -		hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
> -					      sizeof(*hsmp_pdev.sock),
> -					      GFP_KERNEL);
> -		if (!hsmp_pdev.sock)
> -			return -ENOMEM;
> -	}
> +	hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
> +				      sizeof(*hsmp_pdev.sock),
> +				      GFP_KERNEL);
> +	if (!hsmp_pdev.sock)
> +		return -ENOMEM;
>  
> -	if (check_acpi_support(&pdev->dev)) {
> -		ret = init_acpi(&pdev->dev);
> -		if (ret) {
> -			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
> -			return ret;
> -		}
> -		ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
> -		if (ret)
> -			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
> -	} else {
> -		ret = init_platform_device(&pdev->dev);
> -		if (ret) {
> -			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
> -			return ret;
> -		}
> -		ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
> -		if (ret)
> -			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
> +	ret = init_platform_device(&pdev->dev);
> +	if (ret) {
> +		dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
> +		return ret;
>  	}
>  
> -	if (!hsmp_pdev.is_probed) {
> -		hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
> -		hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
> -		hsmp_pdev.mdev.fops	= &hsmp_fops;
> -		hsmp_pdev.mdev.parent	= &pdev->dev;
> -		hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
> -		hsmp_pdev.mdev.mode	= 0644;
> -
> -		ret = misc_register(&hsmp_pdev.mdev);
> -		if (ret)
> -			return ret;
> +	ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
> +	if (ret)
> +		dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
>  
> -		hsmp_pdev.is_probed = true;
> -	}
> +	hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
> +	hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
> +	hsmp_pdev.mdev.fops	= &hsmp_fops;
> +	hsmp_pdev.mdev.parent	= &pdev->dev;
> +	hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
> +	hsmp_pdev.mdev.mode	= 0644;
>  
> -	return 0;
> +	return misc_register(&hsmp_pdev.mdev);
>  }
>  
>  static void hsmp_pltdrv_remove(struct platform_device *pdev)
>  {
> -	/*
> -	 * We register only one misc_device even on multi socket system.
> -	 * So, deregister should happen only once.
> -	 */
> -	if (hsmp_pdev.is_probed) {
> -		misc_deregister(&hsmp_pdev.mdev);
> -		hsmp_pdev.is_probed = false;
> -	}
> +	misc_deregister(&hsmp_pdev.mdev);
>  }
>  
>  static struct platform_driver amd_hsmp_driver = {
> @@ -236,7 +185,6 @@ static struct platform_driver amd_hsmp_driver = {
>  	.remove_new	= hsmp_pltdrv_remove,
>  	.driver		= {
>  		.name	= DRIVER_NAME,
> -		.acpi_match_table = amd_hsmp_acpi_ids,
>  	},
>  };
>  
> @@ -295,6 +243,12 @@ static int __init hsmp_plt_init(void)
>  {
>  	int ret = -ENODEV;
>  
> +	if (!legacy_hsmp_support()) {
> +		pr_info("HSMP is not supported on Family:%x model:%x\n",
> +			boot_cpu_data.x86, boot_cpu_data.x86_model);
> +		return ret;

return -ENODEV; directly.

...the other case below this one should be cleaned up too to directly 
return that value and the ret initilization removed (although not in 
this patch).

-- 
 i.

> +	}
> +
>  	/*
>  	 * amd_nb_num() returns number of SMN/DF interfaces present in the system
>  	 * if we have N SMN/DF interfaces that ideally means N sockets
> @@ -307,19 +261,9 @@ static int __init hsmp_plt_init(void)
>  	if (ret)
>  		return ret;
>  
> -	if (!hsmp_pdev.is_acpi_device) {
> -		if (legacy_hsmp_support()) {
> -			/* Not ACPI device, but supports HSMP, register a plat_dev */
> -			ret = hsmp_plat_dev_register();
> -		} else {
> -			/* Not ACPI, Does not support HSMP */
> -			pr_info("HSMP is not supported on Family:%x model:%x\n",
> -				boot_cpu_data.x86, boot_cpu_data.x86_model);
> -			ret = -ENODEV;
> -		}
> -		if (ret)
> -			platform_driver_unregister(&amd_hsmp_driver);
> -	}
> +	ret = hsmp_plat_dev_register();
> +	if (ret)
> +		platform_driver_unregister(&amd_hsmp_driver);
>  
>  	return ret;
>  }
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [v3 06/11] platform/x86/amd/hsmp: Change generic plat_dev name to hsmp_pdev
  2024-07-20 17:45 ` [v3 06/11] platform/x86/amd/hsmp: Change generic plat_dev name to hsmp_pdev Suma Hegde
@ 2024-08-07 12:31   ` Ilpo Järvinen
  0 siblings, 0 replies; 21+ messages in thread
From: Ilpo Järvinen @ 2024-08-07 12:31 UTC (permalink / raw)
  To: Suma Hegde; +Cc: platform-driver-x86, Hans de Goede, Naveen Krishna Chatradhi

[-- Attachment #1: Type: text/plain, Size: 10785 bytes --]

On Sat, 20 Jul 2024, Suma Hegde wrote:

> plat_dev is a commonly used variable name, since its made as extern now,
> change it to more specific name.
> Also change miscdevice hsmp_device to mdev.
> 
> Signed-off-by: Suma Hegde <suma.hegde@amd.com>
> Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
> ---
> Changes since v2:
> None
> Changes since v1:
> 1. This is a new patch to rename generic name "plat_dev"
>    in hsmp.h, hsmp.c, plat.c and acpi.c to more specific name "hsmp_pdev"
> 2. Rename miscdevice hsmp_device to mdev.
> 
>  drivers/platform/x86/amd/hsmp/acpi.c | 10 +++---
>  drivers/platform/x86/amd/hsmp/hsmp.c | 22 ++++++------
>  drivers/platform/x86/amd/hsmp/hsmp.h |  4 +--
>  drivers/platform/x86/amd/hsmp/plat.c | 52 ++++++++++++++--------------
>  4 files changed, 44 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c
> index eca324774141..46cb86d5d550 100644
> --- a/drivers/platform/x86/amd/hsmp/acpi.c
> +++ b/drivers/platform/x86/amd/hsmp/acpi.c
> @@ -191,12 +191,12 @@ static int hsmp_read_acpi_crs(struct hsmp_socket *sock)
>  /* Parse the ACPI table to read the data */
>  static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
>  {
> -	struct hsmp_socket *sock = &plat_dev.sock[sock_ind];
> +	struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
>  	int ret;
>  
> -	sock->sock_ind		= sock_ind;
> -	sock->dev		= dev;
> -	plat_dev.is_acpi_device	= true;
> +	sock->sock_ind			= sock_ind;
> +	sock->dev			= dev;
> +	hsmp_pdev.is_acpi_device	= true;

This a good example why aligning = is usually bad idea because it 
tends to lead to extra code churn like this when the alignment has to be 
maintained.

Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

-- 
 i.

>  	sema_init(&sock->hsmp_sem, 1);
>  
> @@ -240,7 +240,7 @@ int init_acpi(struct device *dev)
>  	ret = hsmp_get_uid(dev, &sock_ind);
>  	if (ret)
>  		return ret;
> -	if (sock_ind >= plat_dev.num_sockets)
> +	if (sock_ind >= hsmp_pdev.num_sockets)
>  		return -EINVAL;
>  
>  	ret = hsmp_parse_acpi_table(dev, sock_ind);
> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
> index 8473c2d1258b..14edaace4379 100644
> --- a/drivers/platform/x86/amd/hsmp/hsmp.c
> +++ b/drivers/platform/x86/amd/hsmp/hsmp.c
> @@ -29,12 +29,12 @@
>  #define HSMP_WR			true
>  #define HSMP_RD			false
>  
> -struct hsmp_plat_device plat_dev;
> +struct hsmp_plat_device hsmp_pdev;
>  
>  static int amd_hsmp_rdwr(struct hsmp_socket *sock, u32 offset,
>  			 u32 *value, bool write)
>  {
> -	if (plat_dev.is_acpi_device)
> +	if (hsmp_pdev.is_acpi_device)
>  		amd_hsmp_acpi_rdwr(sock, offset, value, write);
>  	else
>  		return amd_hsmp_pci_rdwr(sock, offset, value, write);
> @@ -177,9 +177,9 @@ int hsmp_send_message(struct hsmp_message *msg)
>  	if (ret)
>  		return ret;
>  
> -	if (!plat_dev.sock || msg->sock_ind >= plat_dev.num_sockets)
> +	if (!hsmp_pdev.sock || msg->sock_ind >= hsmp_pdev.num_sockets)
>  		return -ENODEV;
> -	sock = &plat_dev.sock[msg->sock_ind];
> +	sock = &hsmp_pdev.sock[msg->sock_ind];
>  
>  	/*
>  	 * The time taken by smu operation to complete is between
> @@ -220,7 +220,7 @@ int hsmp_test(u16 sock_ind, u32 value)
>  
>  	/* Check the response value */
>  	if (msg.args[0] != (value + 1)) {
> -		dev_err(plat_dev.sock[sock_ind].dev,
> +		dev_err(hsmp_pdev.sock[sock_ind].dev,
>  			"Socket %d test message failed, Expected 0x%08X, received 0x%08X\n",
>  			sock_ind, (value + 1), msg.args[0]);
>  		return -EBADE;
> @@ -315,7 +315,7 @@ ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
>  
>  static int hsmp_get_tbl_dram_base(u16 sock_ind)
>  {
> -	struct hsmp_socket *sock = &plat_dev.sock[sock_ind];
> +	struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
>  	struct hsmp_message msg = { 0 };
>  	phys_addr_t dram_addr;
>  	int ret;
> @@ -349,7 +349,7 @@ static int hsmp_get_tbl_dram_base(u16 sock_ind)
>  umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
>  				  struct bin_attribute *battr, int id)
>  {
> -	if (plat_dev.proto_ver == HSMP_PROTO_VER6)
> +	if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6)
>  		return battr->attr.mode;
>  	else
>  		return 0;
> @@ -357,17 +357,17 @@ umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
>  
>  static int hsmp_init_metric_tbl_bin_attr(struct bin_attribute **hattrs, u16 sock_ind)
>  {
> -	struct bin_attribute *hattr = &plat_dev.sock[sock_ind].hsmp_attr;
> +	struct bin_attribute *hattr = &hsmp_pdev.sock[sock_ind].hsmp_attr;
>  
>  	sysfs_bin_attr_init(hattr);
>  	hattr->attr.name	= HSMP_METRICS_TABLE_NAME;
>  	hattr->attr.mode	= 0444;
>  	hattr->read		= hsmp_metric_tbl_read;
>  	hattr->size		= sizeof(struct hsmp_metric_table);
> -	hattr->private		= &plat_dev.sock[sock_ind];
> +	hattr->private		= &hsmp_pdev.sock[sock_ind];
>  	hattrs[0]		= hattr;
>  
> -	if (plat_dev.proto_ver == HSMP_PROTO_VER6)
> +	if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6)
>  		return hsmp_get_tbl_dram_base(sock_ind);
>  	else
>  		return 0;
> @@ -404,7 +404,7 @@ int hsmp_cache_proto_ver(u16 sock_ind)
>  
>  	ret = hsmp_send_message(&msg);
>  	if (!ret)
> -		plat_dev.proto_ver = msg.args[0];
> +		hsmp_pdev.proto_ver = msg.args[0];
>  
>  	return ret;
>  }
> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
> index 1ff652dc0ef0..a77887d298b6 100644
> --- a/drivers/platform/x86/amd/hsmp/hsmp.h
> +++ b/drivers/platform/x86/amd/hsmp/hsmp.h
> @@ -44,7 +44,7 @@ struct hsmp_socket {
>  };
>  
>  struct hsmp_plat_device {
> -	struct miscdevice hsmp_device;
> +	struct miscdevice mdev;
>  	struct hsmp_socket *sock;
>  	u32 proto_ver;
>  	u16 num_sockets;
> @@ -52,7 +52,7 @@ struct hsmp_plat_device {
>  	bool is_probed;
>  };
>  
> -extern struct hsmp_plat_device plat_dev;
> +extern struct hsmp_plat_device hsmp_pdev;
>  
>  int init_acpi(struct device *dev);
>  ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
> diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
> index 2ed5a9452244..c297540bb64c 100644
> --- a/drivers/platform/x86/amd/hsmp/plat.c
> +++ b/drivers/platform/x86/amd/hsmp/plat.c
> @@ -68,21 +68,21 @@ static int hsmp_create_non_acpi_sysfs_if(struct device *dev)
>  	struct attribute_group *attr_grp;
>  	u16 i;
>  
> -	hsmp_attr_grps = devm_kcalloc(dev, plat_dev.num_sockets + 1,
> +	hsmp_attr_grps = devm_kcalloc(dev, hsmp_pdev.num_sockets + 1,
>  				      sizeof(*hsmp_attr_grps),
>  				      GFP_KERNEL);
>  	if (!hsmp_attr_grps)
>  		return -ENOMEM;
>  
>  	/* Create a sysfs directory for each socket */
> -	for (i = 0; i < plat_dev.num_sockets; i++) {
> +	for (i = 0; i < hsmp_pdev.num_sockets; i++) {
>  		attr_grp = devm_kzalloc(dev, sizeof(struct attribute_group),
>  					GFP_KERNEL);
>  		if (!attr_grp)
>  			return -ENOMEM;
>  
> -		snprintf(plat_dev.sock[i].name, HSMP_ATTR_GRP_NAME_SIZE, "socket%u", (u8)i);
> -		attr_grp->name			= plat_dev.sock[i].name;
> +		snprintf(hsmp_pdev.sock[i].name, HSMP_ATTR_GRP_NAME_SIZE, "socket%u", (u8)i);
> +		attr_grp->name			= hsmp_pdev.sock[i].name;
>  		attr_grp->is_bin_visible	= hsmp_is_sock_attr_visible;
>  		hsmp_attr_grps[i]		= attr_grp;
>  
> @@ -105,10 +105,10 @@ static int init_platform_device(struct device *dev)
>  	struct hsmp_socket *sock;
>  	int ret, i;
>  
> -	for (i = 0; i < plat_dev.num_sockets; i++) {
> +	for (i = 0; i < hsmp_pdev.num_sockets; i++) {
>  		if (!node_to_amd_nb(i))
>  			return -ENODEV;
> -		sock = &plat_dev.sock[i];
> +		sock = &hsmp_pdev.sock[i];
>  		sock->root			= node_to_amd_nb(i)->root;
>  		sock->sock_ind			= i;
>  		sock->dev			= dev;
> @@ -173,11 +173,11 @@ static int hsmp_pltdrv_probe(struct platform_device *pdev)
>  	 * Hence allocate memory for all the sockets at once instead of allocating
>  	 * on each probe.
>  	 */
> -	if (!plat_dev.is_probed) {
> -		plat_dev.sock = devm_kcalloc(&pdev->dev, plat_dev.num_sockets,
> -					     sizeof(*plat_dev.sock),
> -					     GFP_KERNEL);
> -		if (!plat_dev.sock)
> +	if (!hsmp_pdev.is_probed) {
> +		hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
> +					      sizeof(*hsmp_pdev.sock),
> +					      GFP_KERNEL);
> +		if (!hsmp_pdev.sock)
>  			return -ENOMEM;
>  	}
>  
> @@ -201,19 +201,19 @@ static int hsmp_pltdrv_probe(struct platform_device *pdev)
>  			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
>  	}
>  
> -	if (!plat_dev.is_probed) {
> -		plat_dev.hsmp_device.name	= HSMP_CDEV_NAME;
> -		plat_dev.hsmp_device.minor	= MISC_DYNAMIC_MINOR;
> -		plat_dev.hsmp_device.fops	= &hsmp_fops;
> -		plat_dev.hsmp_device.parent	= &pdev->dev;
> -		plat_dev.hsmp_device.nodename	= HSMP_DEVNODE_NAME;
> -		plat_dev.hsmp_device.mode	= 0644;
> +	if (!hsmp_pdev.is_probed) {
> +		hsmp_pdev.mdev.name	= HSMP_CDEV_NAME;
> +		hsmp_pdev.mdev.minor	= MISC_DYNAMIC_MINOR;
> +		hsmp_pdev.mdev.fops	= &hsmp_fops;
> +		hsmp_pdev.mdev.parent	= &pdev->dev;
> +		hsmp_pdev.mdev.nodename	= HSMP_DEVNODE_NAME;
> +		hsmp_pdev.mdev.mode	= 0644;
>  
> -		ret = misc_register(&plat_dev.hsmp_device);
> +		ret = misc_register(&hsmp_pdev.mdev);
>  		if (ret)
>  			return ret;
>  
> -		plat_dev.is_probed = true;
> +		hsmp_pdev.is_probed = true;
>  	}
>  
>  	return 0;
> @@ -225,9 +225,9 @@ static void hsmp_pltdrv_remove(struct platform_device *pdev)
>  	 * We register only one misc_device even on multi socket system.
>  	 * So, deregister should happen only once.
>  	 */
> -	if (plat_dev.is_probed) {
> -		misc_deregister(&plat_dev.hsmp_device);
> -		plat_dev.is_probed = false;
> +	if (hsmp_pdev.is_probed) {
> +		misc_deregister(&hsmp_pdev.mdev);
> +		hsmp_pdev.is_probed = false;
>  	}
>  }
>  
> @@ -299,15 +299,15 @@ static int __init hsmp_plt_init(void)
>  	 * amd_nb_num() returns number of SMN/DF interfaces present in the system
>  	 * if we have N SMN/DF interfaces that ideally means N sockets
>  	 */
> -	plat_dev.num_sockets = amd_nb_num();
> -	if (plat_dev.num_sockets == 0 || plat_dev.num_sockets > MAX_AMD_SOCKETS)
> +	hsmp_pdev.num_sockets = amd_nb_num();
> +	if (hsmp_pdev.num_sockets == 0 || hsmp_pdev.num_sockets > MAX_AMD_SOCKETS)
>  		return ret;
>  
>  	ret = platform_driver_register(&amd_hsmp_driver);
>  	if (ret)
>  		return ret;
>  
> -	if (!plat_dev.is_acpi_device) {
> +	if (!hsmp_pdev.is_acpi_device) {
>  		if (legacy_hsmp_support()) {
>  			/* Not ACPI device, but supports HSMP, register a plat_dev */
>  			ret = hsmp_plat_dev_register();
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [v3 09/11] platform/x86/amd/hsmp: Move read() and is_bin_visible() to respective files
  2024-07-20 17:45 ` [v3 09/11] platform/x86/amd/hsmp: Move read() and is_bin_visible() to respective files Suma Hegde
@ 2024-08-07 12:37   ` Ilpo Järvinen
  0 siblings, 0 replies; 21+ messages in thread
From: Ilpo Järvinen @ 2024-08-07 12:37 UTC (permalink / raw)
  To: Suma Hegde; +Cc: platform-driver-x86, Hans de Goede, Naveen Krishna Chatradhi

On Sat, 20 Jul 2024, Suma Hegde wrote:

> The .read() and .is_bin_visibile() need to be handled differently in acpi

ACPI

> and platform drivers, due to the way the sysfs files are created.
> 
> This is in preparation to using .dev_groups instead of dynamic sysfs
> creation. The sysfs at this point is not functional, it will be enabled in
> the next patch.

What does the last sentence mean? If it means that after this commit (w/o 
the next one), sysfs is no longer working, it's not acceptable way to 
construct a patch series. We never intentionally split patches such that 
there's breakage/loss of features in the intermediate state. Thus, 
reconsider how to split things differently so nothing breaks (if nothing 
else helps, just merge the two patches together, this series is already 
much better than the one large move changes was so it shouldn't be a big 
problem).

...If it means something else, you probably should rephrase the sentence.

-- 
 i.

> Signed-off-by: Suma Hegde <suma.hegde@amd.com>
> Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
> ---
> Changes since v2:
> None
> Changes since v1:
> 1. Change is_visible to is_bin_visible in commit message
> 1. Add parenthesis around read and is_bin_visible in commit message
> 2. Change plat_dev to hsmp_pdev, hsmp_device to mdev
> 3. Remove unnecessary if, else conditions in hsmp_is_sock_attr_visible
> 4. Change un cached to un-cached
> 
>  drivers/platform/x86/amd/hsmp/acpi.c | 41 ++++++++++++++++++++
>  drivers/platform/x86/amd/hsmp/hsmp.c | 37 ------------------
>  drivers/platform/x86/amd/hsmp/plat.c | 57 ++++++++++++++++++++++++++++
>  3 files changed, 98 insertions(+), 37 deletions(-)
> 
> diff --git a/drivers/platform/x86/amd/hsmp/acpi.c b/drivers/platform/x86/amd/hsmp/acpi.c
> index 86100943aadc..7cb38c8dc627 100644
> --- a/drivers/platform/x86/amd/hsmp/acpi.c
> +++ b/drivers/platform/x86/amd/hsmp/acpi.c
> @@ -11,6 +11,7 @@
>  
>  #include "hsmp.h"
>  
> +#include <asm/amd_hsmp.h>
>  #include <asm/amd_nb.h>
>  
>  #include <linux/acpi.h>
> @@ -214,6 +215,8 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
>  
>  	sema_init(&sock->hsmp_sem, 1);
>  
> +	dev_set_drvdata(dev, sock);
> +
>  	/* Read MP1 base address from CRS method */
>  	ret = hsmp_read_acpi_crs(sock);
>  	if (ret)
> @@ -246,6 +249,44 @@ static int hsmp_create_acpi_sysfs_if(struct device *dev)
>  	return devm_device_add_group(dev, attr_grp);
>  }
>  
> +ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
> +			     struct bin_attribute *bin_attr, char *buf,
> +			     loff_t off, size_t count)
> +{
> +	struct device *dev = container_of(kobj, struct device, kobj);
> +	struct hsmp_socket *sock = dev_get_drvdata(dev);
> +	struct hsmp_message msg = { 0 };
> +	int ret;
> +
> +	if (!sock)
> +		return -EINVAL;
> +
> +	/* Do not support lseek(), reads entire metric table */
> +	if (count < bin_attr->size) {
> +		dev_err(sock->dev, "Wrong buffer size\n");
> +		return -EINVAL;
> +	}
> +
> +	msg.msg_id      = HSMP_GET_METRIC_TABLE;
> +	msg.sock_ind    = sock->sock_ind;
> +
> +	ret = hsmp_send_message(&msg);
> +	if (ret)
> +		return ret;
> +	memcpy_fromio(buf, sock->metric_tbl_addr, bin_attr->size);
> +
> +	return bin_attr->size;
> +}
> +
> +umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
> +				  struct bin_attribute *battr, int id)
> +{
> +	if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6)
> +		return battr->attr.mode;
> +
> +	return 0;
> +}
> +
>  static int init_acpi(struct device *dev)
>  {
>  	u16 sock_ind;
> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
> index 119a1f8895ca..c906723ae2f2 100644
> --- a/drivers/platform/x86/amd/hsmp/hsmp.c
> +++ b/drivers/platform/x86/amd/hsmp/hsmp.c
> @@ -274,34 +274,6 @@ long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
>  	return 0;
>  }
>  
> -ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
> -			     struct bin_attribute *bin_attr, char *buf,
> -			     loff_t off, size_t count)
> -{
> -	struct hsmp_socket *sock = bin_attr->private;
> -	struct hsmp_message msg = { 0 };
> -	int ret;
> -
> -	if (!sock)
> -		return -EINVAL;
> -
> -	/* Do not support lseek(), reads entire metric table */
> -	if (count < bin_attr->size) {
> -		dev_err(sock->dev, "Wrong buffer size\n");
> -		return -EINVAL;
> -	}
> -
> -	msg.msg_id	= HSMP_GET_METRIC_TABLE;
> -	msg.sock_ind	= sock->sock_ind;
> -
> -	ret = hsmp_send_message(&msg);
> -	if (ret)
> -		return ret;
> -	memcpy_fromio(buf, sock->metric_tbl_addr, bin_attr->size);
> -
> -	return bin_attr->size;
> -}
> -
>  static int hsmp_get_tbl_dram_base(u16 sock_ind)
>  {
>  	struct hsmp_socket *sock = &hsmp_pdev.sock[sock_ind];
> @@ -335,15 +307,6 @@ static int hsmp_get_tbl_dram_base(u16 sock_ind)
>  	return 0;
>  }
>  
> -umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
> -				  struct bin_attribute *battr, int id)
> -{
> -	if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6)
> -		return battr->attr.mode;
> -	else
> -		return 0;
> -}
> -
>  static int hsmp_init_metric_tbl_bin_attr(struct bin_attribute **hattrs, u16 sock_ind)
>  {
>  	struct bin_attribute *hattr = &hsmp_pdev.sock[sock_ind].hsmp_attr;
> diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
> index 3bce2c570f2b..c2b83363713f 100644
> --- a/drivers/platform/x86/amd/hsmp/plat.c
> +++ b/drivers/platform/x86/amd/hsmp/plat.c
> @@ -11,6 +11,7 @@
>  
>  #include "hsmp.h"
>  
> +#include <asm/amd_hsmp.h>
>  #include <asm/amd_nb.h>
>  
>  #include <linux/device.h>
> @@ -90,6 +91,62 @@ static int hsmp_create_non_acpi_sysfs_if(struct device *dev)
>  	return device_add_groups(dev, hsmp_attr_grps);
>  }
>  
> +ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
> +			     struct bin_attribute *bin_attr, char *buf,
> +			     loff_t off, size_t count)
> +{
> +	struct hsmp_message msg = { 0 };
> +	struct hsmp_socket *sock;
> +	u8 sock_ind;
> +	int ret;
> +
> +	ret = kstrtou8(bin_attr->private, 10, &sock_ind);
> +	if (ret)
> +		return ret;
> +
> +	if (sock_ind >= hsmp_pdev.num_sockets)
> +		return -EINVAL;
> +
> +	sock = &hsmp_pdev.sock[sock_ind];
> +	if (!sock)
> +		return -EINVAL;
> +
> +	/* Do not support lseek(), reads entire metric table */
> +	if (count < bin_attr->size) {
> +		dev_err(sock->dev, "Wrong buffer size\n");
> +		return -EINVAL;
> +	}
> +
> +	msg.msg_id	= HSMP_GET_METRIC_TABLE;
> +	msg.sock_ind	= sock_ind;
> +
> +	ret = hsmp_send_message(&msg);
> +	if (ret)
> +		return ret;
> +	memcpy_fromio(buf, sock->metric_tbl_addr, bin_attr->size);
> +
> +	return bin_attr->size;
> +}
> +
> +umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
> +				  struct bin_attribute *battr, int id)
> +{
> +	u8 sock_ind;
> +	int ret;
> +
> +	ret = kstrtou8(battr->private, 10, &sock_ind);
> +	if (ret)
> +		return ret;
> +
> +	if (id == 0 && sock_ind >= hsmp_pdev.num_sockets)
> +		return SYSFS_GROUP_INVISIBLE;
> +
> +	if (hsmp_pdev.proto_ver == HSMP_PROTO_VER6)
> +		return battr->attr.mode;
> +
> +	return 0;
> +}
> +
>  static inline bool is_f1a_m0h(void)
>  {
>  	if (boot_cpu_data.x86 == 0x1A && boot_cpu_data.x86_model <= 0x0F)
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [v3 04/11] platform/x86/amd/hsmp: Move platform device specific code to plat.c
  2024-07-20 17:45 ` [v3 04/11] platform/x86/amd/hsmp: Move platform device specific code to plat.c Suma Hegde
@ 2024-08-07 12:50   ` Ilpo Järvinen
  0 siblings, 0 replies; 21+ messages in thread
From: Ilpo Järvinen @ 2024-08-07 12:50 UTC (permalink / raw)
  To: Suma Hegde; +Cc: platform-driver-x86, Hans de Goede, Naveen Krishna Chatradhi

On Sat, 20 Jul 2024, Suma Hegde wrote:

> Move platform device part to plat.c.
> 
> No functinality/logical changes.
> Common code which can be used by ACPI and platform device
> remains in hsmp.c.
> ACPI code in hsmp.c will be moved to acpi.c in next patch.
>
> Signed-off-by: Suma Hegde <suma.hegde@amd.com>
> Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
> ---
> Changes since v2:
> None
> Changes since v1:
> 1. Include new header file device.h in plat.c
> 2. Arrange headers in alphabetical order
> 3. Add an empty line between asm/ and linux/ headers
>  
>  drivers/platform/x86/amd/hsmp/Makefile |   2 +-
>  drivers/platform/x86/amd/hsmp/hsmp.c   | 350 ++-----------------------
>  drivers/platform/x86/amd/hsmp/hsmp.h   |  17 ++
>  drivers/platform/x86/amd/hsmp/plat.c   | 338 ++++++++++++++++++++++++
>  4 files changed, 371 insertions(+), 336 deletions(-)
>  create mode 100644 drivers/platform/x86/amd/hsmp/plat.c
> 
> diff --git a/drivers/platform/x86/amd/hsmp/Makefile b/drivers/platform/x86/amd/hsmp/Makefile
> index fda64906a5e8..fb8ba04b2f0d 100644
> --- a/drivers/platform/x86/amd/hsmp/Makefile
> +++ b/drivers/platform/x86/amd/hsmp/Makefile
> @@ -5,4 +5,4 @@
>  #
>  
>  obj-$(CONFIG_AMD_HSMP)		+= amd_hsmp.o
> -amd_hsmp-objs			:= hsmp.o
> +amd_hsmp-objs			:= hsmp.o plat.o
> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
> index 2c9ba51b9614..d15a978ff71e 100644
> --- a/drivers/platform/x86/amd/hsmp/hsmp.c
> +++ b/drivers/platform/x86/amd/hsmp/hsmp.c
> @@ -12,16 +12,9 @@
>  #include "hsmp.h"
>  
>  #include <asm/amd_hsmp.h>
> -#include <asm/amd_nb.h>
> -#include <linux/delay.h>
> -#include <linux/module.h>
> -#include <linux/pci.h>
> -#include <linux/platform_device.h>
> -#include <linux/acpi.h>
>  
> -#define DRIVER_NAME		"amd_hsmp"
> -#define DRIVER_VERSION		"2.2"
> -#define ACPI_HSMP_DEVICE_HID	"AMDI0097"
> +#include <linux/acpi.h>
> +#include <linux/delay.h>
>  
>  /* HSMP Status / Error codes */
>  #define HSMP_STATUS_NOT_READY	0x00
> @@ -36,45 +29,12 @@
>  #define HSMP_WR			true
>  #define HSMP_RD			false
>  
> -/*
> - * To access specific HSMP mailbox register, s/w writes the SMN address of HSMP mailbox
> - * register into the SMN_INDEX register, and reads/writes the SMN_DATA reg.
> - * Below are required SMN address for HSMP Mailbox register offsets in SMU address space
> - */
> -#define SMN_HSMP_BASE		0x3B00000
> -#define SMN_HSMP_MSG_ID		0x0010534
> -#define SMN_HSMP_MSG_ID_F1A_M0H	0x0010934
> -#define SMN_HSMP_MSG_RESP	0x0010980
> -#define SMN_HSMP_MSG_DATA	0x00109E0
> -
> -#define HSMP_INDEX_REG		0xc4
> -#define HSMP_DATA_REG		0xc8
> -
>  /* These are the strings specified in ACPI table */
>  #define MSG_IDOFF_STR		"MsgIdOffset"
>  #define MSG_ARGOFF_STR		"MsgArgOffset"
>  #define MSG_RESPOFF_STR		"MsgRspOffset"
>  
> -static struct hsmp_plat_device plat_dev;
> -
> -static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
> -			     u32 *value, bool write)
> -{
> -	int ret;
> -
> -	if (!sock->root)
> -		return -ENODEV;
> -
> -	ret = pci_write_config_dword(sock->root, HSMP_INDEX_REG,
> -				     sock->mbinfo.base_addr + offset);
> -	if (ret)
> -		return ret;
> -
> -	ret = (write ? pci_write_config_dword(sock->root, HSMP_DATA_REG, *value)
> -		     : pci_read_config_dword(sock->root, HSMP_DATA_REG, value));
> -
> -	return ret;
> -}
> +struct hsmp_plat_device plat_dev;
>  
>  static void amd_hsmp_acpi_rdwr(struct hsmp_socket *sock, u32 offset,
>  			       u32 *value, bool write)
> @@ -253,7 +213,7 @@ int hsmp_send_message(struct hsmp_message *msg)
>  }
>  EXPORT_SYMBOL_GPL(hsmp_send_message);
>  
> -static int hsmp_test(u16 sock_ind, u32 value)
> +int hsmp_test(u16 sock_ind, u32 value)
>  {
>  	struct hsmp_message msg = { 0 };
>  	int ret;
> @@ -283,7 +243,7 @@ static int hsmp_test(u16 sock_ind, u32 value)
>  	return ret;
>  }
>  
> -static long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
> +long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
>  {
>  	int __user *arguser = (int  __user *)arg;
>  	struct hsmp_message msg = { 0 };
> @@ -339,12 +299,6 @@ static long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
>  	return 0;
>  }
>  
> -static const struct file_operations hsmp_fops = {
> -	.owner		= THIS_MODULE,
> -	.unlocked_ioctl	= hsmp_ioctl,
> -	.compat_ioctl	= hsmp_ioctl,
> -};
> -
>  /* This is the UUID used for HSMP */
>  static const guid_t acpi_hsmp_uuid = GUID_INIT(0xb74d619d, 0x5707, 0x48bd,
>  						0xa6, 0x9f, 0x4e, 0xa2,
> @@ -520,9 +474,9 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
>  	return hsmp_read_acpi_dsd(sock);
>  }
>  
> -static ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
> -				    struct bin_attribute *bin_attr, char *buf,
> -				    loff_t off, size_t count)
> +ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
> +			     struct bin_attribute *bin_attr, char *buf,
> +			     loff_t off, size_t count)
>  {
>  	struct hsmp_socket *sock = bin_attr->private;
>  	struct hsmp_message msg = { 0 };
> @@ -581,8 +535,8 @@ static int hsmp_get_tbl_dram_base(u16 sock_ind)
>  	return 0;
>  }
>  
> -static umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
> -					 struct bin_attribute *battr, int id)
> +umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
> +				  struct bin_attribute *battr, int id)
>  {
>  	if (plat_dev.proto_ver == HSMP_PROTO_VER6)
>  		return battr->attr.mode;
> @@ -611,8 +565,8 @@ static int hsmp_init_metric_tbl_bin_attr(struct bin_attribute **hattrs, u16 sock
>  /* One bin sysfs for metrics table */
>  #define NUM_HSMP_ATTRS		1
>  
> -static int hsmp_create_attr_list(struct attribute_group *attr_grp,
> -				 struct device *dev, u16 sock_ind)
> +int hsmp_create_attr_list(struct attribute_group *attr_grp,
> +			  struct device *dev, u16 sock_ind)
>  {
>  	struct bin_attribute **hsmp_bin_attrs;
>  
> @@ -628,37 +582,7 @@ static int hsmp_create_attr_list(struct attribute_group *attr_grp,
>  	return hsmp_init_metric_tbl_bin_attr(hsmp_bin_attrs, sock_ind);
>  }
>  
> -static int hsmp_create_non_acpi_sysfs_if(struct device *dev)
> -{
> -	const struct attribute_group **hsmp_attr_grps;
> -	struct attribute_group *attr_grp;
> -	u16 i;
> -
> -	hsmp_attr_grps = devm_kcalloc(dev, plat_dev.num_sockets + 1,
> -				      sizeof(*hsmp_attr_grps),
> -				      GFP_KERNEL);
> -	if (!hsmp_attr_grps)
> -		return -ENOMEM;
> -
> -	/* Create a sysfs directory for each socket */
> -	for (i = 0; i < plat_dev.num_sockets; i++) {
> -		attr_grp = devm_kzalloc(dev, sizeof(struct attribute_group),
> -					GFP_KERNEL);
> -		if (!attr_grp)
> -			return -ENOMEM;
> -
> -		snprintf(plat_dev.sock[i].name, HSMP_ATTR_GRP_NAME_SIZE, "socket%u", (u8)i);
> -		attr_grp->name			= plat_dev.sock[i].name;
> -		attr_grp->is_bin_visible	= hsmp_is_sock_attr_visible;
> -		hsmp_attr_grps[i]		= attr_grp;
> -
> -		hsmp_create_attr_list(attr_grp, dev, i);
> -	}
> -
> -	return device_add_groups(dev, hsmp_attr_grps);
> -}
> -
> -static int hsmp_create_acpi_sysfs_if(struct device *dev)
> +int hsmp_create_acpi_sysfs_if(struct device *dev)
>  {
>  	struct attribute_group *attr_grp;
>  	u16 sock_ind;
> @@ -681,7 +605,7 @@ static int hsmp_create_acpi_sysfs_if(struct device *dev)
>  	return devm_device_add_group(dev, attr_grp);
>  }
>  
> -static int hsmp_cache_proto_ver(u16 sock_ind)
> +int hsmp_cache_proto_ver(u16 sock_ind)
>  {
>  	struct hsmp_message msg = { 0 };
>  	int ret;
> @@ -697,76 +621,7 @@ static int hsmp_cache_proto_ver(u16 sock_ind)
>  	return ret;
>  }
>  
> -static inline bool is_f1a_m0h(void)
> -{
> -	if (boot_cpu_data.x86 == 0x1A && boot_cpu_data.x86_model <= 0x0F)
> -		return true;
> -
> -	return false;
> -}
> -
> -static int init_platform_device(struct device *dev)
> -{
> -	struct hsmp_socket *sock;
> -	int ret, i;
> -
> -	for (i = 0; i < plat_dev.num_sockets; i++) {
> -		if (!node_to_amd_nb(i))
> -			return -ENODEV;
> -		sock = &plat_dev.sock[i];
> -		sock->root			= node_to_amd_nb(i)->root;
> -		sock->sock_ind			= i;
> -		sock->dev			= dev;
> -		sock->mbinfo.base_addr		= SMN_HSMP_BASE;
> -
> -		/*
> -		 * This is a transitional change from non-ACPI to ACPI, only
> -		 * family 0x1A, model 0x00 platform is supported for both ACPI and non-ACPI.
> -		 */
> -		if (is_f1a_m0h())
> -			sock->mbinfo.msg_id_off	= SMN_HSMP_MSG_ID_F1A_M0H;
> -		else
> -			sock->mbinfo.msg_id_off	= SMN_HSMP_MSG_ID;
> -
> -		sock->mbinfo.msg_resp_off	= SMN_HSMP_MSG_RESP;
> -		sock->mbinfo.msg_arg_off	= SMN_HSMP_MSG_DATA;
> -		sema_init(&sock->hsmp_sem, 1);
> -
> -		/* Test the hsmp interface on each socket */
> -		ret = hsmp_test(i, 0xDEADBEEF);
> -		if (ret) {
> -			dev_err(dev, "HSMP test message failed on Fam:%x model:%x\n",
> -				boot_cpu_data.x86, boot_cpu_data.x86_model);
> -			dev_err(dev, "Is HSMP disabled in BIOS ?\n");
> -			return ret;
> -		}
> -		ret = hsmp_cache_proto_ver(i);
> -		if (ret) {
> -			dev_err(dev, "Failed to read HSMP protocol version\n");
> -			return ret;
> -		}
> -	}
> -
> -	return 0;
> -}
> -
> -static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
> -	{ACPI_HSMP_DEVICE_HID, 0},
> -	{}
> -};
> -MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
> -
> -static bool check_acpi_support(struct device *dev)
> -{
> -	struct acpi_device *adev = ACPI_COMPANION(dev);
> -
> -	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
> -		return true;
> -
> -	return false;
> -}
> -
> -static int init_acpi(struct device *dev)
> +int init_acpi(struct device *dev)
>  {
>  	u16 sock_ind;
>  	int ret;
> @@ -800,178 +655,3 @@ static int init_acpi(struct device *dev)
>  
>  	return ret;
>  }
> -
> -static int hsmp_pltdrv_probe(struct platform_device *pdev)
> -{
> -	int ret;
> -
> -	/*
> -	 * On ACPI supported BIOS, there is an ACPI HSMP device added for
> -	 * each socket, so the per socket probing, but the memory allocated for
> -	 * sockets should be contiguous to access it as an array,
> -	 * Hence allocate memory for all the sockets at once instead of allocating
> -	 * on each probe.
> -	 */
> -	if (!plat_dev.is_probed) {
> -		plat_dev.sock = devm_kcalloc(&pdev->dev, plat_dev.num_sockets,
> -					     sizeof(*plat_dev.sock),
> -					     GFP_KERNEL);
> -		if (!plat_dev.sock)
> -			return -ENOMEM;
> -	}
> -	if (check_acpi_support(&pdev->dev)) {
> -		ret = init_acpi(&pdev->dev);
> -		if (ret) {
> -			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
> -			return ret;
> -		}
> -		ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
> -		if (ret)
> -			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
> -	} else {
> -		ret = init_platform_device(&pdev->dev);
> -		if (ret) {
> -			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
> -			return ret;
> -		}
> -		ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
> -		if (ret)
> -			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
> -	}
> -
> -	if (!plat_dev.is_probed) {
> -		plat_dev.hsmp_device.name	= HSMP_CDEV_NAME;
> -		plat_dev.hsmp_device.minor	= MISC_DYNAMIC_MINOR;
> -		plat_dev.hsmp_device.fops	= &hsmp_fops;
> -		plat_dev.hsmp_device.parent	= &pdev->dev;
> -		plat_dev.hsmp_device.nodename	= HSMP_DEVNODE_NAME;
> -		plat_dev.hsmp_device.mode	= 0644;
> -
> -		ret = misc_register(&plat_dev.hsmp_device);
> -		if (ret)
> -			return ret;
> -
> -		plat_dev.is_probed = true;
> -	}
> -
> -	return 0;
> -
> -}
> -
> -static void hsmp_pltdrv_remove(struct platform_device *pdev)
> -{
> -	/*
> -	 * We register only one misc_device even on multi socket system.
> -	 * So, deregister should happen only once.
> -	 */
> -	if (plat_dev.is_probed) {
> -		misc_deregister(&plat_dev.hsmp_device);
> -		plat_dev.is_probed = false;
> -	}
> -}
> -
> -static struct platform_driver amd_hsmp_driver = {
> -	.probe		= hsmp_pltdrv_probe,
> -	.remove_new	= hsmp_pltdrv_remove,
> -	.driver		= {
> -		.name	= DRIVER_NAME,
> -		.acpi_match_table = amd_hsmp_acpi_ids,
> -	},
> -};
> -
> -static struct platform_device *amd_hsmp_platdev;
> -
> -static int hsmp_plat_dev_register(void)
> -{
> -	int ret;
> -
> -	amd_hsmp_platdev = platform_device_alloc(DRIVER_NAME, PLATFORM_DEVID_NONE);
> -	if (!amd_hsmp_platdev)
> -		return -ENOMEM;
> -
> -	ret = platform_device_add(amd_hsmp_platdev);
> -	if (ret)
> -		platform_device_put(amd_hsmp_platdev);
> -
> -	return ret;
> -}
> -
> -/*
> - * This check is only needed for backward compatibility of previous platforms.
> - * All new platforms are expected to support ACPI based probing.
> - */
> -static bool legacy_hsmp_support(void)
> -{
> -	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
> -		return false;
> -
> -	switch (boot_cpu_data.x86) {
> -	case 0x19:
> -		switch (boot_cpu_data.x86_model) {
> -		case 0x00 ... 0x1F:
> -		case 0x30 ... 0x3F:
> -		case 0x90 ... 0x9F:
> -		case 0xA0 ... 0xAF:
> -			return true;
> -		default:
> -			return false;
> -		}
> -	case 0x1A:
> -		switch (boot_cpu_data.x86_model) {
> -		case 0x00 ... 0x1F:
> -			return true;
> -		default:
> -			return false;
> -		}
> -	default:
> -		return false;
> -	}
> -
> -	return false;
> -}
> -
> -static int __init hsmp_plt_init(void)
> -{
> -	int ret = -ENODEV;
> -
> -	/*
> -	 * amd_nb_num() returns number of SMN/DF interfaces present in the system
> -	 * if we have N SMN/DF interfaces that ideally means N sockets
> -	 */
> -	plat_dev.num_sockets = amd_nb_num();
> -	if (plat_dev.num_sockets == 0 || plat_dev.num_sockets > MAX_AMD_SOCKETS)
> -		return ret;
> -
> -	ret = platform_driver_register(&amd_hsmp_driver);
> -	if (ret)
> -		return ret;
> -
> -	if (!plat_dev.is_acpi_device) {
> -		if (legacy_hsmp_support()) {
> -			/* Not ACPI device, but supports HSMP, register a plat_dev */
> -			ret = hsmp_plat_dev_register();
> -		} else {
> -			/* Not ACPI, Does not support HSMP */
> -			pr_info("HSMP is not supported on Family:%x model:%x\n",
> -				boot_cpu_data.x86, boot_cpu_data.x86_model);
> -			ret = -ENODEV;
> -		}
> -		if (ret)
> -			platform_driver_unregister(&amd_hsmp_driver);
> -	}
> -
> -	return ret;
> -}
> -
> -static void __exit hsmp_plt_exit(void)
> -{
> -	platform_device_unregister(amd_hsmp_platdev);
> -	platform_driver_unregister(&amd_hsmp_driver);
> -}
> -
> -device_initcall(hsmp_plt_init);
> -module_exit(hsmp_plt_exit);
> -
> -MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver");
> -MODULE_VERSION(DRIVER_VERSION);
> -MODULE_LICENSE("GPL v2");
> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.h b/drivers/platform/x86/amd/hsmp/hsmp.h
> index 5afc7167fac1..1aa33c5633d0 100644
> --- a/drivers/platform/x86/amd/hsmp/hsmp.h
> +++ b/drivers/platform/x86/amd/hsmp/hsmp.h
> @@ -51,4 +51,21 @@ struct hsmp_plat_device {
>  	bool is_acpi_device;
>  	bool is_probed;
>  };
> +
> +extern struct hsmp_plat_device plat_dev;
> +
> +int init_acpi(struct device *dev);
> +ssize_t hsmp_metric_tbl_read(struct file *filp, struct kobject *kobj,
> +			     struct bin_attribute *bin_attr, char *buf,
> +			     loff_t off, size_t count);
> +int hsmp_create_acpi_sysfs_if(struct device *dev);
> +int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
> +		      u32 *value, bool write);
> +int hsmp_cache_proto_ver(u16 sock_ind);
> +long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
> +umode_t hsmp_is_sock_attr_visible(struct kobject *kobj,
> +				  struct bin_attribute *battr, int id);
> +int hsmp_create_attr_list(struct attribute_group *attr_grp,
> +			  struct device *dev, u16 sock_ind);
> +int hsmp_test(u16 sock_ind, u32 value);
>  #endif /* HSMP_H */
> diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
> new file mode 100644
> index 000000000000..2ed5a9452244
> --- /dev/null
> +++ b/drivers/platform/x86/amd/hsmp/plat.c
> @@ -0,0 +1,338 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * AMD HSMP Platform Driver
> + * Copyright (c) 2024, AMD.
> + * All Rights Reserved.
> + *
> + * This file provides platform device implementations.
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include "hsmp.h"
> +
> +#include <asm/amd_nb.h>
> +
> +#include <linux/acpi.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/pci.h>
> +#include <linux/platform_device.h>

The usual convention is to put "" ones last.

> +
> +#define DRIVER_NAME		"amd_hsmp"
> +#define DRIVER_VERSION		"2.2"
> +#define ACPI_HSMP_DEVICE_HID	"AMDI0097"
> +
> +/*
> + * To access specific HSMP mailbox register, s/w writes the SMN address of HSMP mailbox
> + * register into the SMN_INDEX register, and reads/writes the SMN_DATA reg.
> + * Below are required SMN address for HSMP Mailbox register offsets in SMU address space
> + */
> +#define SMN_HSMP_BASE		0x3B00000
> +#define SMN_HSMP_MSG_ID		0x0010534
> +#define SMN_HSMP_MSG_ID_F1A_M0H	0x0010934
> +#define SMN_HSMP_MSG_RESP	0x0010980
> +#define SMN_HSMP_MSG_DATA	0x00109E0
> +
> +#define HSMP_INDEX_REG		0xc4
> +#define HSMP_DATA_REG		0xc8
> +
> +int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
> +		      u32 *value, bool write)
> +{
> +	int ret;
> +
> +	if (!sock->root)
> +		return -ENODEV;
> +
> +	ret = pci_write_config_dword(sock->root, HSMP_INDEX_REG,
> +				     sock->mbinfo.base_addr + offset);
> +	if (ret)
> +		return ret;
> +
> +	ret = (write ? pci_write_config_dword(sock->root, HSMP_DATA_REG, *value)
> +		     : pci_read_config_dword(sock->root, HSMP_DATA_REG, value));
> +
> +	return ret;
> +}
> +
> +static const struct file_operations hsmp_fops = {
> +	.owner		= THIS_MODULE,
> +	.unlocked_ioctl	= hsmp_ioctl,
> +	.compat_ioctl	= hsmp_ioctl,
> +};
> +
> +static int hsmp_create_non_acpi_sysfs_if(struct device *dev)
> +{
> +	const struct attribute_group **hsmp_attr_grps;
> +	struct attribute_group *attr_grp;
> +	u16 i;
> +
> +	hsmp_attr_grps = devm_kcalloc(dev, plat_dev.num_sockets + 1,
> +				      sizeof(*hsmp_attr_grps),
> +				      GFP_KERNEL);
> +	if (!hsmp_attr_grps)
> +		return -ENOMEM;
> +
> +	/* Create a sysfs directory for each socket */
> +	for (i = 0; i < plat_dev.num_sockets; i++) {
> +		attr_grp = devm_kzalloc(dev, sizeof(struct attribute_group),
> +					GFP_KERNEL);
> +		if (!attr_grp)
> +			return -ENOMEM;
> +
> +		snprintf(plat_dev.sock[i].name, HSMP_ATTR_GRP_NAME_SIZE, "socket%u", (u8)i);
> +		attr_grp->name			= plat_dev.sock[i].name;
> +		attr_grp->is_bin_visible	= hsmp_is_sock_attr_visible;
> +		hsmp_attr_grps[i]		= attr_grp;
> +
> +		hsmp_create_attr_list(attr_grp, dev, i);
> +	}
> +
> +	return device_add_groups(dev, hsmp_attr_grps);
> +}
> +
> +static inline bool is_f1a_m0h(void)
> +{
> +	if (boot_cpu_data.x86 == 0x1A && boot_cpu_data.x86_model <= 0x0F)
> +		return true;
> +
> +	return false;
> +}
> +
> +static int init_platform_device(struct device *dev)
> +{
> +	struct hsmp_socket *sock;
> +	int ret, i;
> +
> +	for (i = 0; i < plat_dev.num_sockets; i++) {
> +		if (!node_to_amd_nb(i))
> +			return -ENODEV;
> +		sock = &plat_dev.sock[i];
> +		sock->root			= node_to_amd_nb(i)->root;
> +		sock->sock_ind			= i;
> +		sock->dev			= dev;
> +		sock->mbinfo.base_addr		= SMN_HSMP_BASE;
> +
> +		/*
> +		 * This is a transitional change from non-ACPI to ACPI, only
> +		 * family 0x1A, model 0x00 platform is supported for both ACPI and non-ACPI.
> +		 */
> +		if (is_f1a_m0h())
> +			sock->mbinfo.msg_id_off	= SMN_HSMP_MSG_ID_F1A_M0H;
> +		else
> +			sock->mbinfo.msg_id_off	= SMN_HSMP_MSG_ID;
> +
> +		sock->mbinfo.msg_resp_off	= SMN_HSMP_MSG_RESP;
> +		sock->mbinfo.msg_arg_off	= SMN_HSMP_MSG_DATA;
> +		sema_init(&sock->hsmp_sem, 1);
> +
> +		/* Test the hsmp interface on each socket */
> +		ret = hsmp_test(i, 0xDEADBEEF);
> +		if (ret) {
> +			dev_err(dev, "HSMP test message failed on Fam:%x model:%x\n",
> +				boot_cpu_data.x86, boot_cpu_data.x86_model);
> +			dev_err(dev, "Is HSMP disabled in BIOS ?\n");
> +			return ret;
> +		}
> +
> +		ret = hsmp_cache_proto_ver(i);
> +		if (ret) {
> +			dev_err(dev, "Failed to read HSMP protocol version\n");
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct acpi_device_id amd_hsmp_acpi_ids[] = {
> +	{ACPI_HSMP_DEVICE_HID, 0},
> +	{}
> +};
> +MODULE_DEVICE_TABLE(acpi, amd_hsmp_acpi_ids);
> +
> +static bool check_acpi_support(struct device *dev)
> +{
> +	struct acpi_device *adev = ACPI_COMPANION(dev);
> +
> +	if (adev && !acpi_match_device_ids(adev, amd_hsmp_acpi_ids))
> +		return true;
> +
> +	return false;
> +}
> +
> +static int hsmp_pltdrv_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +
> +	/*
> +	 * On ACPI supported BIOS, there is an ACPI HSMP device added for
> +	 * each socket, so the per socket probing, but the memory allocated for
> +	 * sockets should be contiguous to access it as an array,
> +	 * Hence allocate memory for all the sockets at once instead of allocating
> +	 * on each probe.
> +	 */
> +	if (!plat_dev.is_probed) {
> +		plat_dev.sock = devm_kcalloc(&pdev->dev, plat_dev.num_sockets,
> +					     sizeof(*plat_dev.sock),
> +					     GFP_KERNEL);
> +		if (!plat_dev.sock)
> +			return -ENOMEM;
> +	}
> +
> +	if (check_acpi_support(&pdev->dev)) {
> +		ret = init_acpi(&pdev->dev);
> +		if (ret) {
> +			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
> +			return ret;
> +		}
> +		ret = hsmp_create_acpi_sysfs_if(&pdev->dev);
> +		if (ret)
> +			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");

This now moves ACPI stuff into plat.c and that seems unnecessary.
It can be avoided by starting to construct the final probe functions 
differently within the series.

Effectively, you initially move just the code in these two if branches
into the per-probe mechanism probe functions and keep the common probe 
parts in hsmp.c until the actual split into two drivers.

-- 
 i.

> +	} else {
> +		ret = init_platform_device(&pdev->dev);
> +		if (ret) {
> +			dev_err(&pdev->dev, "Failed to init HSMP mailbox\n");
> +			return ret;
> +		}
> +		ret = hsmp_create_non_acpi_sysfs_if(&pdev->dev);
> +		if (ret)
> +			dev_err(&pdev->dev, "Failed to create HSMP sysfs interface\n");
> +	}
> +
> +	if (!plat_dev.is_probed) {
> +		plat_dev.hsmp_device.name	= HSMP_CDEV_NAME;
> +		plat_dev.hsmp_device.minor	= MISC_DYNAMIC_MINOR;
> +		plat_dev.hsmp_device.fops	= &hsmp_fops;
> +		plat_dev.hsmp_device.parent	= &pdev->dev;
> +		plat_dev.hsmp_device.nodename	= HSMP_DEVNODE_NAME;
> +		plat_dev.hsmp_device.mode	= 0644;
> +
> +		ret = misc_register(&plat_dev.hsmp_device);
> +		if (ret)
> +			return ret;
> +
> +		plat_dev.is_probed = true;
> +	}
> +
> +	return 0;
> +}
> +
> +static void hsmp_pltdrv_remove(struct platform_device *pdev)
> +{
> +	/*
> +	 * We register only one misc_device even on multi socket system.
> +	 * So, deregister should happen only once.
> +	 */
> +	if (plat_dev.is_probed) {
> +		misc_deregister(&plat_dev.hsmp_device);
> +		plat_dev.is_probed = false;
> +	}
> +}
> +
> +static struct platform_driver amd_hsmp_driver = {
> +	.probe		= hsmp_pltdrv_probe,
> +	.remove_new	= hsmp_pltdrv_remove,
> +	.driver		= {
> +		.name	= DRIVER_NAME,
> +		.acpi_match_table = amd_hsmp_acpi_ids,
> +	},
> +};
> +
> +static struct platform_device *amd_hsmp_platdev;
> +
> +static int hsmp_plat_dev_register(void)
> +{
> +	int ret;
> +
> +	amd_hsmp_platdev = platform_device_alloc(DRIVER_NAME, PLATFORM_DEVID_NONE);
> +	if (!amd_hsmp_platdev)
> +		return -ENOMEM;
> +
> +	ret = platform_device_add(amd_hsmp_platdev);
> +	if (ret)
> +		platform_device_put(amd_hsmp_platdev);
> +
> +	return ret;
> +}
> +
> +/*
> + * This check is only needed for backward compatibility of previous platforms.
> + * All new platforms are expected to support ACPI based probing.
> + */
> +static bool legacy_hsmp_support(void)
> +{
> +	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
> +		return false;
> +
> +	switch (boot_cpu_data.x86) {
> +	case 0x19:
> +		switch (boot_cpu_data.x86_model) {
> +		case 0x00 ... 0x1F:
> +		case 0x30 ... 0x3F:
> +		case 0x90 ... 0x9F:
> +		case 0xA0 ... 0xAF:
> +			return true;
> +		default:
> +			return false;
> +		}
> +	case 0x1A:
> +		switch (boot_cpu_data.x86_model) {
> +		case 0x00 ... 0x1F:
> +			return true;
> +		default:
> +			return false;
> +		}
> +	default:
> +		return false;
> +	}
> +
> +	return false;
> +}
> +
> +static int __init hsmp_plt_init(void)
> +{
> +	int ret = -ENODEV;
> +
> +	/*
> +	 * amd_nb_num() returns number of SMN/DF interfaces present in the system
> +	 * if we have N SMN/DF interfaces that ideally means N sockets
> +	 */
> +	plat_dev.num_sockets = amd_nb_num();
> +	if (plat_dev.num_sockets == 0 || plat_dev.num_sockets > MAX_AMD_SOCKETS)
> +		return ret;
> +
> +	ret = platform_driver_register(&amd_hsmp_driver);
> +	if (ret)
> +		return ret;
> +
> +	if (!plat_dev.is_acpi_device) {
> +		if (legacy_hsmp_support()) {
> +			/* Not ACPI device, but supports HSMP, register a plat_dev */
> +			ret = hsmp_plat_dev_register();
> +		} else {
> +			/* Not ACPI, Does not support HSMP */
> +			pr_info("HSMP is not supported on Family:%x model:%x\n",
> +				boot_cpu_data.x86, boot_cpu_data.x86_model);
> +			ret = -ENODEV;
> +		}
> +		if (ret)
> +			platform_driver_unregister(&amd_hsmp_driver);
> +	}
> +
> +	return ret;
> +}
> +
> +static void __exit hsmp_plt_exit(void)
> +{
> +	platform_device_unregister(amd_hsmp_platdev);
> +	platform_driver_unregister(&amd_hsmp_driver);
> +}
> +
> +device_initcall(hsmp_plt_init);
> +module_exit(hsmp_plt_exit);
> +
> +MODULE_DESCRIPTION("AMD HSMP Platform Interface Driver");
> +MODULE_VERSION(DRIVER_VERSION);
> +MODULE_LICENSE("GPL v2");
> 


^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [v3 07/11] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers
  2024-07-20 17:45 ` [v3 07/11] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers Suma Hegde
  2024-07-30  6:16   ` Suma Hegde
  2024-08-07 12:31   ` Ilpo Järvinen
@ 2024-08-07 14:17   ` Ilpo Järvinen
  2 siblings, 0 replies; 21+ messages in thread
From: Ilpo Järvinen @ 2024-08-07 14:17 UTC (permalink / raw)
  To: Suma Hegde; +Cc: platform-driver-x86, Hans de Goede, Naveen Krishna Chatradhi

On Sat, 20 Jul 2024, Suma Hegde wrote:

> Separate the probes for ACPI and platform device drivers.
> Provide a Kconfig option to select either the
> ACPI or the platform device based driver.
> 
> Signed-off-by: Suma Hegde <suma.hegde@amd.com>
> Reviewed-by: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
> ---
> Changes since v2:
> Following files are modified to add new symbol
>  - drivers/platform/x86/amd/hsmp/Kconfig, 
>  - drivers/platform/x86/amd/hsmp/Makefile
>  - drivers/platform/x86/amd/Makefile
> AMD_HSMP is used as common symbol and new AMD_HSMP_PLAT symbol is added
> 
> Changes since v1:
> Rename "plat_dev" to "hsmp_pdev"
> 
>  arch/x86/include/asm/amd_hsmp.h        |   2 +-
>  drivers/platform/x86/amd/Makefile      |   2 +-
>  drivers/platform/x86/amd/hsmp/Kconfig  |  33 ++++++-
>  drivers/platform/x86/amd/hsmp/Makefile |   6 +-
>  drivers/platform/x86/amd/hsmp/acpi.c   | 119 ++++++++++++++++++++++--
>  drivers/platform/x86/amd/hsmp/hsmp.c   |  25 ++---
>  drivers/platform/x86/amd/hsmp/hsmp.h   |   8 +-
>  drivers/platform/x86/amd/hsmp/plat.c   | 122 +++++++------------------
>  8 files changed, 188 insertions(+), 129 deletions(-)
> 
> diff --git a/arch/x86/include/asm/amd_hsmp.h b/arch/x86/include/asm/amd_hsmp.h
> index 03c2ce3edaf5..ada14e55f9f4 100644
> --- a/arch/x86/include/asm/amd_hsmp.h
> +++ b/arch/x86/include/asm/amd_hsmp.h
> @@ -5,7 +5,7 @@
>  
>  #include <uapi/asm/amd_hsmp.h>
>  
> -#if IS_ENABLED(CONFIG_AMD_HSMP)
> +#if IS_ENABLED(CONFIG_AMD_HSMP) || IS_ENABLED(CONFIG_AMD_HSMP_ACPI)
>  int hsmp_send_message(struct hsmp_message *msg);
>  #else
>  static inline int hsmp_send_message(struct hsmp_message *msg)
> diff --git a/drivers/platform/x86/amd/Makefile b/drivers/platform/x86/amd/Makefile
> index 96ec24c8701b..f0b2fe81c685 100644
> --- a/drivers/platform/x86/amd/Makefile
> +++ b/drivers/platform/x86/amd/Makefile
> @@ -5,6 +5,6 @@
>  #
>  
>  obj-$(CONFIG_AMD_PMC)		+= pmc/
> -obj-y				+= hsmp/
> +obj-$(CONFIG_AMD_HSMP)		+= hsmp/
>  obj-$(CONFIG_AMD_PMF)		+= pmf/
>  obj-$(CONFIG_AMD_WBRF)		+= wbrf.o
> diff --git a/drivers/platform/x86/amd/hsmp/Kconfig b/drivers/platform/x86/amd/hsmp/Kconfig
> index b55d4ed9bceb..23fb98066225 100644
> --- a/drivers/platform/x86/amd/hsmp/Kconfig
> +++ b/drivers/platform/x86/amd/hsmp/Kconfig
> @@ -4,14 +4,39 @@
>  #
>  
>  config AMD_HSMP
> -	tristate "AMD HSMP Driver"
> -	depends on AMD_NB && X86_64 && ACPI
> +	tristate "AMD Host System Management Port driver"
> +	depends on AMD_NB
>  	help
> +	  Host System Management Port (HSMP) interface is a mailbox interface
> +	  between the x86 core and the System Management Unit (SMU) firmware.
>  	  The driver provides a way for user space tools to monitor and manage
>  	  system management functionality on EPYC server CPUs from AMD.
>  
> -	  Host System Management Port (HSMP) interface is a mailbox interface
> -	  between the x86 core and the System Management Unit (SMU) firmware.
> +menu "AMD HSMP Probe"
> +	depends on AMD_HSMP
> +
> +config AMD_HSMP_ACPI
> +	tristate "ACPI based probe"
> +	depends on ACPI
> +	help
> +	  This driver supports ACPI based probing.
> +
> +	  You may enable this, if your platform bios provides an ACPI object
> +	  as described in the documentation.
>  
>  	  If you choose to compile this driver as a module the module will be
>  	  called amd_hsmp.
> +
> +config AMD_HSMP_PLAT
> +	tristate "Platform device based probe"
> +	depends on AMD_HSMP_ACPI=n
> +	help
> +	  This driver supports platform device based probing.
> +
> +	  You may enable this, if your platform bios does not provide
> +	  HSMP ACPI object.
> +
> +	  If you choose to compile this driver as a module the module will be
> +	  called amd_hsmp.
> +

One additional point, please also make sure it gets compiled if 
COMPILE_TEST is set regardless of e.g. AMD_NB to get better 
compile coverage.

-- 
 i.


^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2024-08-07 14:17 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-20 17:45 [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Suma Hegde
2024-07-20 17:45 ` [v3 02/11] platform/x86/amd/hsmp: Create wrapper function init_acpi() Suma Hegde
2024-07-20 17:45 ` [v3 03/11] platform/x86/amd/hsmp: Move structure and macros to header file Suma Hegde
2024-08-07 11:39   ` Ilpo Järvinen
2024-07-20 17:45 ` [v3 04/11] platform/x86/amd/hsmp: Move platform device specific code to plat.c Suma Hegde
2024-08-07 12:50   ` Ilpo Järvinen
2024-07-20 17:45 ` [v3 05/11] platform/x86/amd/hsmp: Move ACPI code to acpi.c Suma Hegde
2024-07-20 17:45 ` [v3 06/11] platform/x86/amd/hsmp: Change generic plat_dev name to hsmp_pdev Suma Hegde
2024-08-07 12:31   ` Ilpo Järvinen
2024-07-20 17:45 ` [v3 07/11] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers Suma Hegde
2024-07-30  6:16   ` Suma Hegde
2024-07-30 13:20     ` Ilpo Järvinen
2024-08-06 11:40       ` Suma Hegde
2024-08-07 12:31   ` Ilpo Järvinen
2024-08-07 14:17   ` Ilpo Järvinen
2024-07-20 17:45 ` [v3 08/11] platform/x86/amd/hsmp: Use name space while exporting module symbols Suma Hegde
2024-07-20 17:45 ` [v3 09/11] platform/x86/amd/hsmp: Move read() and is_bin_visible() to respective files Suma Hegde
2024-08-07 12:37   ` Ilpo Järvinen
2024-07-20 17:45 ` [v3 10/11] platform/x86/amd/hsmp: Use dev_groups in the driver structure Suma Hegde
2024-07-20 17:45 ` [v3 11/11] platform/x86/amd/hsmp: Fix potential spectre issue Suma Hegde
2024-08-07 11:33 ` [v3 01/11] platform/x86/amd/hsmp: Create hsmp/ directory Ilpo Järvinen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.