blob: 2ad66f1e5590c9842a7c10582bf4c86de298be85 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001#include <linux/kernel.h>
2#include <linux/module.h>
3#include <linux/slab.h>
4#include <linux/err.h>
5#include <linux/clk-provider.h>
6#include <linux/clk.h>
7#include <linux/io.h>
8#include <linux/hw_random.h>
9#include <linux/platform_device.h>
10#include <linux/device.h>
11#include <linux/init.h>
12#include <linux/errno.h>
13#include <linux/interrupt.h>
14#include <linux/irq.h>
15#include <linux/scatterlist.h>
16#include <linux/dma-mapping.h>
17#include <linux/of_device.h>
18#include <linux/delay.h>
19#include <linux/crypto.h>
20#include <crypto/scatterwalk.h>
21#include <crypto/algapi.h>
22#include <linux/tee_drv.h>
23
24#include "asr-bcm-optee.h"
25
26static void asrbcm_uuid_to_octets(uint8_t d[TEE_IOCTL_UUID_LEN], struct teec_uuid *s)
27{
28 d[0] = s->timeLow >> 24;
29 d[1] = s->timeLow >> 16;
30 d[2] = s->timeLow >> 8;
31 d[3] = s->timeLow;
32 d[4] = s->timeMid >> 8;
33 d[5] = s->timeMid;
34 d[6] = s->timeHiAndVersion >> 8;
35 d[7] = s->timeHiAndVersion;
36 memcpy(d + 8, s->clockSeqAndNode, sizeof(s->clockSeqAndNode));
37}
38
39static int asrbcm_tee_match_cb(struct tee_ioctl_version_data *ver, const void *data)
40{
41 return 1;
42}
43
44int asrbcm_optee_open_ta(struct asrbcm_tee_context *ctx, struct teec_uuid *uuid)
45{
46 struct tee_ioctl_open_session_arg open_session_arg;
47 int ret;
48
49 if (ctx == NULL)
50 return -EINVAL;
51
52 ctx->session = 0;
53 ctx->tee_ctx = tee_client_open_context(NULL, asrbcm_tee_match_cb, NULL, NULL);
54 if (IS_ERR(ctx->tee_ctx)) {
55 ret = PTR_ERR(ctx->tee_ctx);
56 ctx->tee_ctx = NULL;
57 return ret;
58 }
59
60 memset(&open_session_arg, 0x0, sizeof(struct tee_ioctl_open_session_arg));
61 asrbcm_uuid_to_octets(open_session_arg.uuid, uuid);
62 open_session_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC;
63 open_session_arg.num_params = 0;
64 ret = tee_client_open_session(ctx->tee_ctx, &open_session_arg, NULL);
65 if (ret != 0) {
66 goto err_exit;
67 } else if (open_session_arg.ret != 0) {
68 ret = -EIO;
69 goto err_exit;
70 }
71
72 ctx->session = open_session_arg.session;
73
74 return ret;
75err_exit:
76 tee_client_close_context(ctx->tee_ctx);
77 ctx->tee_ctx = NULL;
78 return ret;
79}
80
81int asrbcm_optee_close_ta(struct asrbcm_tee_context *ctx)
82{
83 int ret;
84
85 if (ctx == NULL)
86 return -EINVAL;
87
88 ret = tee_client_close_session(ctx->tee_ctx, ctx->session);
89
90 tee_client_close_context(ctx->tee_ctx);
91
92 return ret;
93}
94
95#if defined(CONFIG_OF)
96static const struct of_device_id asr_bcm_dt_ids[] = {
97 { .compatible = "asr,asr-bcm" },
98 { /* sentinel */ }
99};
100MODULE_DEVICE_TABLE(of, asr_bcm_dt_ids);
101#endif
102
103static int asr_bcm_probe(struct platform_device *pdev)
104{
105 struct asr_bcm_dev *bcm_dd;
106 struct device *dev = &pdev->dev;
107 struct device_node *np = NULL;
108 int err = 0, devnum = 0;
109
110 bcm_dd = devm_kzalloc(&pdev->dev, sizeof(*bcm_dd), GFP_KERNEL);
111 if (bcm_dd == NULL) {
112 err = -ENOMEM;
113 goto no_mem_err;
114 }
115
116 np = dev->of_node;
117 bcm_dd->dev = dev;
118
119 platform_set_drvdata(pdev, bcm_dd);
120
121#ifdef CONFIG_ASR_BCM_CIPHER
122 if (of_get_property(np, "asr,asr-cipher", NULL)) {
123 err = asr_bcm_cipher_register(bcm_dd);
124 if (err)
125 goto res_err;
126 dev_info(dev, "CIPHER engine is initialized\n");
127 devnum ++;
128 }
129#endif
130
131#ifdef CONFIG_ASR_BCM_SHA
132 if (of_get_property(np, "asr,asr-sha", NULL)) {
133 err = asr_bcm_sha_register(bcm_dd);
134 if (err)
135 goto sha_err;
136 dev_info(dev, "SHA engine is initialized\n");
137 devnum ++;
138 }
139#endif
140
141 if (!devnum) {
142 dev_err(dev, "No BCM device enabled\n");
143 err = -ENODEV;
144 goto res_err;
145 }
146
147 return 0;
148
149#ifdef CONFIG_ASR_BCM_SHA
150sha_err:
151#ifdef CONFIG_ASR_BCM_CIPHER
152 asr_bcm_cipher_unregister(bcm_dd);
153#endif
154#endif
155
156res_err:
157 devm_kfree(dev, bcm_dd);
158no_mem_err:
159 dev_err(dev, "initialization failed.\n");
160
161 return err;
162}
163
164static int asr_bcm_remove(struct platform_device *pdev)
165{
166 struct asr_bcm_dev *bcm_dd;
167
168 bcm_dd = platform_get_drvdata(pdev);
169 if (!bcm_dd)
170 return -ENODEV;
171
172#ifdef CONFIG_ASR_BCM_CIPHER
173 asr_bcm_cipher_unregister(bcm_dd);
174#endif
175
176#ifdef CONFIG_ASR_BCM_SHA
177 asr_bcm_sha_unregister(bcm_dd);
178#endif
179
180 devm_kfree(bcm_dd->dev, bcm_dd);
181
182 return 0;
183}
184
185static struct platform_driver asr_bcm_driver = {
186 .probe = asr_bcm_probe,
187 .remove = asr_bcm_remove,
188 .driver = {
189 .name = "asr_bcm",
190 .of_match_table = of_match_ptr(asr_bcm_dt_ids),
191 },
192};
193
194static int __init asr_bcm_init(void)
195{
196 int ret;
197
198 ret = platform_driver_register(&asr_bcm_driver);
199
200 return ret;
201}
202
203device_initcall_sync(asr_bcm_init);
204
205MODULE_DESCRIPTION("BCM: ASR Trust Engine support.");
206MODULE_LICENSE("GPL v2");
207MODULE_AUTHOR("Yonggan Wang");