1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Driver for Qualcomm Secure Execution Environment (SEE) interface (QSEECOM).
4 * Responsible for setting up and managing QSEECOM client devices.
6 * Copyright (C) 2023 Maximilian Luz <luzmaximilian@gmail.com>
8 #include <linux/auxiliary_bus.h>
9 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include <linux/slab.h>
12 #include <linux/types.h>
14 #include <linux/firmware/qcom/qcom_qseecom.h>
15 #include <linux/firmware/qcom/qcom_scm.h>
17 struct qseecom_app_desc
{
22 static void qseecom_client_release(struct device
*dev
)
24 struct qseecom_client
*client
;
26 client
= container_of(dev
, struct qseecom_client
, aux_dev
.dev
);
30 static void qseecom_client_remove(void *data
)
32 struct qseecom_client
*client
= data
;
34 auxiliary_device_delete(&client
->aux_dev
);
35 auxiliary_device_uninit(&client
->aux_dev
);
38 static int qseecom_client_register(struct platform_device
*qseecom_dev
,
39 const struct qseecom_app_desc
*desc
)
41 struct qseecom_client
*client
;
45 /* Try to find the app ID, skip device if not found */
46 ret
= qcom_scm_qseecom_app_get_id(desc
->app_name
, &app_id
);
48 return ret
== -ENOENT
? 0 : ret
;
50 dev_info(&qseecom_dev
->dev
, "setting up client for %s\n", desc
->app_name
);
52 /* Allocate and set-up the client device */
53 client
= kzalloc(sizeof(*client
), GFP_KERNEL
);
57 client
->aux_dev
.name
= desc
->dev_name
;
58 client
->aux_dev
.dev
.parent
= &qseecom_dev
->dev
;
59 client
->aux_dev
.dev
.release
= qseecom_client_release
;
60 client
->app_id
= app_id
;
62 ret
= auxiliary_device_init(&client
->aux_dev
);
68 ret
= auxiliary_device_add(&client
->aux_dev
);
70 auxiliary_device_uninit(&client
->aux_dev
);
74 ret
= devm_add_action_or_reset(&qseecom_dev
->dev
, qseecom_client_remove
, client
);
82 * List of supported applications. One client device will be created per entry,
83 * assuming the app has already been loaded (usually by firmware bootloaders)
84 * and its ID can be queried successfully.
86 static const struct qseecom_app_desc qcom_qseecom_apps
[] = {
87 { "qcom.tz.uefisecapp", "uefisecapp" },
90 static int qcom_qseecom_probe(struct platform_device
*qseecom_dev
)
95 /* Set up client devices for each base application */
96 for (i
= 0; i
< ARRAY_SIZE(qcom_qseecom_apps
); i
++) {
97 ret
= qseecom_client_register(qseecom_dev
, &qcom_qseecom_apps
[i
]);
105 static struct platform_driver qcom_qseecom_driver
= {
107 .name
= "qcom_qseecom",
109 .probe
= qcom_qseecom_probe
,
112 static int __init
qcom_qseecom_init(void)
114 return platform_driver_register(&qcom_qseecom_driver
);
116 subsys_initcall(qcom_qseecom_init
);
118 MODULE_AUTHOR("Maximilian Luz <luzmaximilian@gmail.com>");
119 MODULE_DESCRIPTION("Driver for the Qualcomm SEE (QSEECOM) interface");
120 MODULE_LICENSE("GPL");