From: Suma Hegde <Suma.Hegde@amd.com>
To: Hans de Goede <hdegoede@redhat.com>, platform-driver-x86@vger.kernel.org
Cc: ilpo.jarvinen@linux.intel.com,
Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
Subject: Re: [v7 08/10] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers
Date: Wed, 11 Sep 2024 11:42:47 +0530 [thread overview]
Message-ID: <8108fabf-0a74-40d0-bf60-485e26c9065b@amd.com> (raw)
In-Reply-To: <42307228-7871-4ced-89da-a6612db1c7e4@redhat.com>
Hi Hans,
On 9/5/2024 12:22 AM, Hans de Goede wrote:
> Caution: This message originated from an External Source. Use proper caution when opening attachments, clicking links, or responding.
>
>
> Hi,
>
> On 9/3/24 2:38 PM, Suma Hegde wrote:
>> Separate the probes for HSMP ACPI and platform device drivers.
>>
>> Provide a Kconfig option to choose between
>> ACPI or the platform device based driver.
>> The common code which is the core part of the HSMP driver
>> maintained at hsmp.c is guarded by AMD_HSMP config and is selected by
>> these two driver configs.
> <snip>
>
>> diff --git a/drivers/platform/x86/amd/hsmp/Kconfig b/drivers/platform/x86/amd/hsmp/Kconfig
>> index b55d4ed9bceb..b10ff91e9f5a 100644
>> --- a/drivers/platform/x86/amd/hsmp/Kconfig
>> +++ b/drivers/platform/x86/amd/hsmp/Kconfig
>> @@ -4,14 +4,45 @@
>> #
>>
>> config AMD_HSMP
>> - tristate "AMD HSMP Driver"
>> - depends on AMD_NB && X86_64 && ACPI
>> + tristate
>> +
>> +menu "AMD HSMP Driver"
>> + depends on AMD_NB || COMPILE_TEST
>> +
>> +config AMD_HSMP_ACPI
>> + tristate "AMD HSMP ACPI device driver"
>> + depends on ACPI
>> + select AMD_HSMP
>> 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.
>> + system management functionality on EPYC and MI300A server CPUs
>> + from AMD.
>> +
>> + This option supports ACPI based probing.
>> + You may enable this, if your platform BIOS provides an ACPI object
>> + as described in amd_hsmp.rst document.
>> +
>> + If you choose to compile this driver as a module the module will be
>> + called amd_hsmp.
>>
>> +config AMD_HSMP_PLAT
>> + tristate "AMD HSMP platform device driver"
>> + depends on AMD_HSMP_ACPI=n
> I was about to merge this series, but this is going to cause
> a regression for users running distro kernels which rely on
> the old legacy probing.
>
> So before this we had 1 driver which would auto-load on systems
> which have the new ACPI description of the HSMP and which could
> be manually modprobed on systems which require the legacy enumeration.
>
> But now if linux distributions enable AMD_HSMP_ACPI then there
> will be no way for users with systems which lack the ACPI description
> of the HSMP to still get HSMP support.
>
> I guess what you want here is to avoid the legacy driver loading
> on systems which do have the ACPI description. But the way to do
> that would be to do a runtime check for the ACPI description,
> not disallow building the legacy driver altogether.
>
> E.g. you could do the following in hsmp_plt_init() :
>
> if (acpi_dev_present(ACPI_HSMP_DEVICE_HID, NULL, -1)) {
> pr_err("The legacy HSMP driver cannot load on this system, please use hsmp_acpi instead\n");
> return -ENODEV;
> }
>
> I see that you also build both drivers into a single module,
> yes then you cannot have both because you cannot have 2 init
> functions.
>
> Please split things into 3 modules, one shared hsmp_common.ko +
> a hsmp_acpi.ko + hsmp_legacy.ko
Ok, I will keep Kconfig as is with 3 config symbols, but will remove
"depends on AMD_HSMP_ACPI=n" and modify the Makefile to build 3 modules.
hsmp_common.ko, + amd_hsmp.ko (instead of hsmp_legacy.ko, keeping name
as amd_hsmp.ko to keep legacy name for the legacy module).
+ hsmp_acpi.ko.
Also will add a check acpi_dev_present() as mentioned above in
hsmp_plt_init().
Because of the change in config symbols, Linux distributions have to
enable either AMD_HSMP_ACPI or AMD_HSMP_PLAT or both to get HSMP modules
compiled.
> Regards,
>
> Hans
Thanks and Regards,
Suma
>
>
>
>
>> + select AMD_HSMP
>> + 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 and MI300A server CPUs
>> + from AMD.
>> +
>> + This option 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 6f8e7962266a..766617e6adc7 100644
>> --- a/drivers/platform/x86/amd/hsmp/acpi.c
>> +++ b/drivers/platform/x86/amd/hsmp/acpi.c
>> @@ -9,11 +9,15 @@
>>
>> #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
>>
>> +#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/module.h>
>> +#include <linux/platform_device.h>
>> #include <linux/sysfs.h>
>> #include <linux/uuid.h>
>>
>> @@ -21,6 +25,10 @@
>>
>> #include "hsmp.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"
>> @@ -200,7 +208,6 @@ static int hsmp_parse_acpi_table(struct device *dev, u16 sock_ind)
>> sock->sock_ind = sock_ind;
>> sock->dev = dev;
>> sock->amd_hsmp_rdwr = amd_hsmp_acpi_rdwr;
>> - hsmp_pdev.is_acpi_device = true;
>>
>> sema_init(&sock->hsmp_sem, 1);
>>
>> @@ -213,7 +220,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;
>> @@ -236,7 +243,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;
>> @@ -270,3 +277,72 @@ 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 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;
>> + }
>> +
>> + 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) {
>> + ret = hsmp_misc_register(&pdev->dev);
>> + 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) {
>> + hsmp_misc_deregister();
>> + 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");
>> diff --git a/drivers/platform/x86/amd/hsmp/hsmp.c b/drivers/platform/x86/amd/hsmp/hsmp.c
>> index 78945750d590..5e0c9c36f435 100644
>> --- a/drivers/platform/x86/amd/hsmp/hsmp.c
>> +++ b/drivers/platform/x86/amd/hsmp/hsmp.c
>> @@ -15,17 +15,11 @@
>> #include <linux/acpi.h>
>> #include <linux/delay.h>
>> #include <linux/device.h>
>> -#include <linux/module.h>
>> -#include <linux/platform_device.h>
>> #include <linux/semaphore.h>
>> #include <linux/sysfs.h>
>>
>> #include "hsmp.h"
>>
>> -#define DRIVER_NAME "amd_hsmp"
>> -#define DRIVER_VERSION "2.2"
>> -#define ACPI_HSMP_DEVICE_HID "AMDI0097"
>> -
>> /* HSMP Status / Error codes */
>> #define HSMP_STATUS_NOT_READY 0x00
>> #define HSMP_STATUS_OK 0x01
>> @@ -228,7 +222,7 @@ 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 };
>> @@ -284,12 +278,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,
>> -};
>> -
>> 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)
>> @@ -414,193 +402,25 @@ int hsmp_cache_proto_ver(u16 sock_ind)
>> 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_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;
>> - }
>> - 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 (!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_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;
>> - }
>> -}
>> -
>> -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 const struct file_operations hsmp_fops = {
>> + .owner = THIS_MODULE,
>> + .unlocked_ioctl = hsmp_ioctl,
>> + .compat_ioctl = hsmp_ioctl,
>> };
>>
>> -static struct platform_device *amd_hsmp_platdev;
>> -
>> -static int hsmp_plat_dev_register(void)
>> +int hsmp_misc_register(struct device *dev)
>> {
>> - 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;
>> + hsmp_pdev.mdev.name = HSMP_CDEV_NAME;
>> + hsmp_pdev.mdev.minor = MISC_DYNAMIC_MINOR;
>> + hsmp_pdev.mdev.fops = &hsmp_fops;
>> + hsmp_pdev.mdev.parent = dev;
>> + hsmp_pdev.mdev.nodename = HSMP_DEVNODE_NAME;
>> + hsmp_pdev.mdev.mode = 0644;
>> +
>> + return misc_register(&hsmp_pdev.mdev);
>> }
>>
>> -/*
>> - * 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)
>> +void hsmp_misc_deregister(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;
>> + misc_deregister(&hsmp_pdev.mdev);
>> }
>> -
>> -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
>> - */
>> - 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 (!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);
>> - }
>> -
>> - 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 9c5b9c263fc1..9ab50bc74676 100644
>> --- a/drivers/platform/x86/amd/hsmp/hsmp.h
>> +++ b/drivers/platform/x86/amd/hsmp/hsmp.h
>> @@ -52,7 +52,6 @@ struct hsmp_plat_device {
>> struct hsmp_socket *sock;
>> u32 proto_ver;
>> u16 num_sockets;
>> - bool is_acpi_device;
>> bool is_probed;
>> };
>>
>> @@ -61,14 +60,13 @@ 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_create_non_acpi_sysfs_if(struct device *dev);
>> -int hsmp_create_acpi_sysfs_if(struct device *dev);
>> int hsmp_cache_proto_ver(u16 sock_ind);
>> 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 init_platform_device(struct device *dev);
>> -int init_acpi(struct device *dev);
>> +long hsmp_ioctl(struct file *fp, unsigned int cmd, unsigned long arg);
>> +void hsmp_misc_deregister(void);
>> +int hsmp_misc_register(struct device *dev);
>> #endif /* HSMP_H */
>> diff --git a/drivers/platform/x86/amd/hsmp/plat.c b/drivers/platform/x86/amd/hsmp/plat.c
>> index e18cf82478a0..e49b53f8c5e3 100644
>> --- a/drivers/platform/x86/amd/hsmp/plat.c
>> +++ b/drivers/platform/x86/amd/hsmp/plat.c
>> @@ -12,11 +12,16 @@
>> #include <asm/amd_nb.h>
>>
>> #include <linux/device.h>
>> +#include <linux/module.h>
>> #include <linux/pci.h>
>> +#include <linux/platform_device.h>
>> #include <linux/sysfs.h>
>>
>> #include "hsmp.h"
>>
>> +#define DRIVER_NAME "amd_hsmp"
>> +#define DRIVER_VERSION "2.3"
>> +
>> /*
>> * 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.
>> @@ -50,7 +55,13 @@ static int amd_hsmp_pci_rdwr(struct hsmp_socket *sock, u32 offset,
>> return ret;
>> }
>>
>> -int hsmp_create_non_acpi_sysfs_if(struct device *dev)
>> +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;
>> @@ -88,7 +99,7 @@ static inline bool is_f1a_m0h(void)
>> return false;
>> }
>>
>> -int init_platform_device(struct device *dev)
>> +static int init_platform_device(struct device *dev)
>> {
>> struct hsmp_socket *sock;
>> int ret, i;
>> @@ -134,3 +145,132 @@ int init_platform_device(struct device *dev)
>>
>> return 0;
>> }
>> +
>> +static int hsmp_pltdrv_probe(struct platform_device *pdev)
>> +{
>> + int ret;
>> +
>> + hsmp_pdev.sock = devm_kcalloc(&pdev->dev, hsmp_pdev.num_sockets,
>> + sizeof(*hsmp_pdev.sock),
>> + GFP_KERNEL);
>> + if (!hsmp_pdev.sock)
>> + return -ENOMEM;
>> +
>> + 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");
>> +
>> + return hsmp_misc_register(&pdev->dev);
>> +}
>> +
>> +static void hsmp_pltdrv_remove(struct platform_device *pdev)
>> +{
>> + hsmp_misc_deregister();
>> +}
>> +
>> +static struct platform_driver amd_hsmp_driver = {
>> + .probe = hsmp_pltdrv_probe,
>> + .remove_new = hsmp_pltdrv_remove,
>> + .driver = {
>> + .name = DRIVER_NAME,
>> + },
>> +};
>> +
>> +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;
>> +
>> + 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
>> + */
>> + 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;
>> +
>> + ret = hsmp_plat_dev_register();
>> + 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");
next prev parent reply other threads:[~2024-09-11 6:12 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-03 12:38 [v7 01/10] platform/x86/amd/hsmp: Create hsmp/ directory Suma Hegde
2024-09-03 12:38 ` [v7 02/10] platform/x86/amd/hsmp: Create wrapper function init_acpi() Suma Hegde
2024-09-03 12:38 ` [v7 03/10] platform/x86/amd/hsmp: Convert amd_hsmp_rdwr() to a function pointer Suma Hegde
2024-09-03 12:38 ` [v7 04/10] platform/x86/amd/hsmp: Move structure and macros to header file Suma Hegde
2024-09-03 12:38 ` [v7 05/10] platform/x86/amd/hsmp: Move platform device specific code to plat.c Suma Hegde
2024-09-03 12:38 ` [v7 06/10] platform/x86/amd/hsmp: Move ACPI code to acpi.c Suma Hegde
2024-09-03 12:38 ` [v7 07/10] platform/x86/amd/hsmp: Change generic plat_dev name to hsmp_pdev Suma Hegde
2024-09-03 12:38 ` [v7 08/10] platform/x86/amd/hsmp: Create mutually exclusive ACPI and plat drivers Suma Hegde
2024-09-04 13:30 ` Ilpo Järvinen
2024-09-04 18:52 ` Hans de Goede
2024-09-11 6:12 ` Suma Hegde [this message]
2024-09-11 10:00 ` Hans de Goede
2024-09-03 12:38 ` [v7 09/10] platform/x86/amd/hsmp: Use name space while exporting module symbols Suma Hegde
2024-09-03 12:38 ` [v7 10/10] platform/x86/amd/hsmp: Use dev_groups in the driver structure Suma Hegde
2024-09-04 13:26 ` Ilpo Järvinen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8108fabf-0a74-40d0-bf60-485e26c9065b@amd.com \
--to=suma.hegde@amd.com \
--cc=hdegoede@redhat.com \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=naveenkrishna.chatradhi@amd.com \
--cc=platform-driver-x86@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox