firmware: arm_ffa: Register core as a platform driver

Move the FF-A core bring-up and teardown paths into platform driver
probe and remove callbacks, and register a synthetic arm-ffa platform
device to bind the driver.

This makes the FF-A core lifetime follow the driver model while keeping
the device creation internal to the FF-A core. Use normal platform driver
registration so the probe path has standard driver-core semantics.

The synthetic platform device is a temporary bridge until ACPI and
devicetree describe the FF-A core device or object. Once those firmware
description paths are defined, the internal platform device creation can
be dropped and the driver can bind to the firmware-described device
directly.

Since the transport selection now happens from the platform probe path,
drop the __init annotation from ffa_transport_init().

Reviewed-by: Yeoreum Yun <yeoreum.yun@arm.com>
Link: https://patch.msgid.link/20260508-b4-ffa_plat_dev-v1-2-c5a30f8cf7b8@kernel.org
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
This commit is contained in:
Sudeep Holla
2026-05-08 18:54:16 +01:00
parent cc7e8f21b9
commit e659fc8e53
3 changed files with 51 additions and 10 deletions

View File

@@ -18,9 +18,9 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev);
void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid);
#ifdef CONFIG_ARM_FFA_SMCCC
int __init ffa_transport_init(ffa_fn **invoke_ffa_fn);
int ffa_transport_init(ffa_fn **invoke_ffa_fn);
#else
static inline int __init ffa_transport_init(ffa_fn **invoke_ffa_fn)
static inline int ffa_transport_init(ffa_fn **invoke_ffa_fn)
{
return -EOPNOTSUPP;
}

View File

@@ -36,6 +36,7 @@
#include <linux/mm.h>
#include <linux/mutex.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/smp.h>
@@ -46,6 +47,7 @@
#define FFA_DRIVER_VERSION FFA_VERSION_1_2
#define FFA_MIN_VERSION FFA_VERSION_1_0
#define FFA_PLATFORM_NAME "arm-ffa"
#define SENDER_ID_MASK GENMASK(31, 16)
#define RECEIVER_ID_MASK GENMASK(15, 0)
@@ -115,6 +117,7 @@ struct ffa_drv_info {
};
static struct ffa_drv_info *drv_info;
static struct platform_device *ffa_pdev;
/*
* The driver must be able to support all the versions from the earliest
@@ -2086,7 +2089,7 @@ static void ffa_notifications_setup(void)
ffa_notifications_cleanup();
}
static int __init ffa_init(void)
static int ffa_probe(struct platform_device *pdev)
{
int ret;
u32 buf_sz;
@@ -2099,6 +2102,7 @@ static int __init ffa_init(void)
drv_info = kzalloc_obj(*drv_info);
if (!drv_info)
return -ENOMEM;
platform_set_drvdata(pdev, drv_info);
ret = ffa_version_check(&drv_info->version);
if (ret)
@@ -2161,19 +2165,56 @@ static int __init ffa_init(void)
free_pages_exact(drv_info->tx_buffer, rxtx_bufsz);
free_pages_exact(drv_info->rx_buffer, rxtx_bufsz);
free_drv_info:
platform_set_drvdata(pdev, NULL);
kfree(drv_info);
drv_info = NULL;
return ret;
}
static void ffa_remove(struct platform_device *pdev)
{
struct ffa_drv_info *info = platform_get_drvdata(pdev);
ffa_notifications_cleanup();
ffa_partitions_cleanup();
ffa_rxtx_unmap();
free_pages_exact(info->tx_buffer, info->rxtx_bufsz);
free_pages_exact(info->rx_buffer, info->rxtx_bufsz);
kfree(info);
platform_set_drvdata(pdev, NULL);
drv_info = NULL;
}
static struct platform_driver ffa_driver = {
.probe = ffa_probe,
.remove = ffa_remove,
.driver = {
.name = FFA_PLATFORM_NAME,
},
};
static int __init ffa_init(void)
{
int ret;
ffa_pdev = platform_device_register_simple(FFA_PLATFORM_NAME,
PLATFORM_DEVID_NONE,
NULL, 0);
if (IS_ERR(ffa_pdev))
return PTR_ERR(ffa_pdev);
ret = platform_driver_register(&ffa_driver);
if (ret)
platform_device_unregister(ffa_pdev);
return ret;
}
module_init(ffa_init);
static void __exit ffa_exit(void)
{
ffa_notifications_cleanup();
ffa_partitions_cleanup();
ffa_rxtx_unmap();
free_pages_exact(drv_info->tx_buffer, drv_info->rxtx_bufsz);
free_pages_exact(drv_info->rx_buffer, drv_info->rxtx_bufsz);
kfree(drv_info);
platform_device_unregister(ffa_pdev);
platform_driver_unregister(&ffa_driver);
}
module_exit(ffa_exit);

View File

@@ -17,7 +17,7 @@ static void __arm_ffa_fn_hvc(ffa_value_t args, ffa_value_t *res)
arm_smccc_1_2_hvc(&args, res);
}
int __init ffa_transport_init(ffa_fn **invoke_ffa_fn)
int ffa_transport_init(ffa_fn **invoke_ffa_fn)
{
enum arm_smccc_conduit conduit;