mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 03:27:30 -04:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user