1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * sun8i-ce-core.c - hardware cryptographic offloader for
4  * Allwinner H3/A64/H5/H2+/H6/R40 SoC
5  *
6  * Copyright (C) 2015-2019 Corentin Labbe <clabbe.montjoie@gmail.com>
7  *
8  * Core file which registers crypto algorithms supported by the CryptoEngine.
9  *
10  * You could find a link for the datasheet in Documentation/arm/sunxi/README
11  */
12 #include <linux/clk.h>
13 #include <linux/crypto.h>
14 #include <linux/delay.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/interrupt.h>
17 #include <linux/io.h>
18 #include <linux/irq.h>
19 #include <linux/module.h>
20 #include <linux/of.h>
21 #include <linux/of_device.h>
22 #include <linux/platform_device.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/reset.h>
25 #include <crypto/internal/skcipher.h>
26 
27 #include "sun8i-ce.h"
28 
29 /*
30  * mod clock is lower on H3 than other SoC due to some DMA timeout occurring
31  * with high value.
32  * If you want to tune mod clock, loading driver and passing selftest is
33  * insufficient, you need to test with some LUKS test (mount and write to it)
34  */
35 static const struct ce_variant ce_h3_variant = {
36 	.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
37 	},
38 	.op_mode = { CE_OP_ECB, CE_OP_CBC
39 	},
40 	.ce_clks = {
41 		{ "bus", 0, 200000000 },
42 		{ "mod", 50000000, 0 },
43 		}
44 };
45 
46 static const struct ce_variant ce_h5_variant = {
47 	.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
48 	},
49 	.op_mode = { CE_OP_ECB, CE_OP_CBC
50 	},
51 	.ce_clks = {
52 		{ "bus", 0, 200000000 },
53 		{ "mod", 300000000, 0 },
54 		}
55 };
56 
57 static const struct ce_variant ce_h6_variant = {
58 	.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
59 	},
60 	.op_mode = { CE_OP_ECB, CE_OP_CBC
61 	},
62 	.has_t_dlen_in_bytes = true,
63 	.ce_clks = {
64 		{ "bus", 0, 200000000 },
65 		{ "mod", 300000000, 0 },
66 		{ "ram", 0, 400000000 },
67 		}
68 };
69 
70 static const struct ce_variant ce_a64_variant = {
71 	.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
72 	},
73 	.op_mode = { CE_OP_ECB, CE_OP_CBC
74 	},
75 	.ce_clks = {
76 		{ "bus", 0, 200000000 },
77 		{ "mod", 300000000, 0 },
78 		}
79 };
80 
81 static const struct ce_variant ce_r40_variant = {
82 	.alg_cipher = { CE_ALG_AES, CE_ALG_DES, CE_ALG_3DES,
83 	},
84 	.op_mode = { CE_OP_ECB, CE_OP_CBC
85 	},
86 	.ce_clks = {
87 		{ "bus", 0, 200000000 },
88 		{ "mod", 300000000, 0 },
89 		}
90 };
91 
92 /*
93  * sun8i_ce_get_engine_number() get the next channel slot
94  * This is a simple round-robin way of getting the next channel
95  */
96 int sun8i_ce_get_engine_number(struct sun8i_ce_dev *ce)
97 {
98 	return atomic_inc_return(&ce->flow) % MAXFLOW;
99 }
100 
101 int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name)
102 {
103 	u32 v;
104 	int err = 0;
105 
106 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
107 	ce->chanlist[flow].stat_req++;
108 #endif
109 
110 	mutex_lock(&ce->mlock);
111 
112 	v = readl(ce->base + CE_ICR);
113 	v |= 1 << flow;
114 	writel(v, ce->base + CE_ICR);
115 
116 	reinit_completion(&ce->chanlist[flow].complete);
117 	writel(ce->chanlist[flow].t_phy, ce->base + CE_TDQ);
118 
119 	ce->chanlist[flow].status = 0;
120 	/* Be sure all data is written before enabling the task */
121 	wmb();
122 
123 	v = 1 | (ce->chanlist[flow].tl->t_common_ctl & 0x7F) << 8;
124 	writel(v, ce->base + CE_TLR);
125 	mutex_unlock(&ce->mlock);
126 
127 	wait_for_completion_interruptible_timeout(&ce->chanlist[flow].complete,
128 			msecs_to_jiffies(ce->chanlist[flow].timeout));
129 
130 	if (ce->chanlist[flow].status == 0) {
131 		dev_err(ce->dev, "DMA timeout for %s\n", name);
132 		err = -EFAULT;
133 	}
134 	/* No need to lock for this read, the channel is locked so
135 	 * nothing could modify the error value for this channel
136 	 */
137 	v = readl(ce->base + CE_ESR);
138 	if (v) {
139 		v >>= (flow * 4);
140 		v &= 0xFF;
141 		if (v) {
142 			dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow);
143 			err = -EFAULT;
144 		}
145 		if (v & CE_ERR_ALGO_NOTSUP)
146 			dev_err(ce->dev, "CE ERROR: algorithm not supported\n");
147 		if (v & CE_ERR_DATALEN)
148 			dev_err(ce->dev, "CE ERROR: data length error\n");
149 		if (v & CE_ERR_KEYSRAM)
150 			dev_err(ce->dev, "CE ERROR: keysram access error for AES\n");
151 		if (v & CE_ERR_ADDR_INVALID)
152 			dev_err(ce->dev, "CE ERROR: address invalid\n");
153 		}
154 
155 	return err;
156 }
157 
158 static irqreturn_t ce_irq_handler(int irq, void *data)
159 {
160 	struct sun8i_ce_dev *ce = (struct sun8i_ce_dev *)data;
161 	int flow = 0;
162 	u32 p;
163 
164 	p = readl(ce->base + CE_ISR);
165 	for (flow = 0; flow < MAXFLOW; flow++) {
166 		if (p & (BIT(flow))) {
167 			writel(BIT(flow), ce->base + CE_ISR);
168 			ce->chanlist[flow].status = 1;
169 			complete(&ce->chanlist[flow].complete);
170 		}
171 	}
172 
173 	return IRQ_HANDLED;
174 }
175 
176 static struct sun8i_ce_alg_template ce_algs[] = {
177 {
178 	.type = CRYPTO_ALG_TYPE_SKCIPHER,
179 	.ce_algo_id = CE_ID_CIPHER_AES,
180 	.ce_blockmode = CE_ID_OP_CBC,
181 	.alg.skcipher = {
182 		.base = {
183 			.cra_name = "cbc(aes)",
184 			.cra_driver_name = "cbc-aes-sun8i-ce",
185 			.cra_priority = 400,
186 			.cra_blocksize = AES_BLOCK_SIZE,
187 			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
188 				CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
189 			.cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx),
190 			.cra_module = THIS_MODULE,
191 			.cra_alignmask = 0xf,
192 			.cra_init = sun8i_ce_cipher_init,
193 			.cra_exit = sun8i_ce_cipher_exit,
194 		},
195 		.min_keysize	= AES_MIN_KEY_SIZE,
196 		.max_keysize	= AES_MAX_KEY_SIZE,
197 		.ivsize		= AES_BLOCK_SIZE,
198 		.setkey		= sun8i_ce_aes_setkey,
199 		.encrypt	= sun8i_ce_skencrypt,
200 		.decrypt	= sun8i_ce_skdecrypt,
201 	}
202 },
203 {
204 	.type = CRYPTO_ALG_TYPE_SKCIPHER,
205 	.ce_algo_id = CE_ID_CIPHER_AES,
206 	.ce_blockmode = CE_ID_OP_ECB,
207 	.alg.skcipher = {
208 		.base = {
209 			.cra_name = "ecb(aes)",
210 			.cra_driver_name = "ecb-aes-sun8i-ce",
211 			.cra_priority = 400,
212 			.cra_blocksize = AES_BLOCK_SIZE,
213 			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
214 				CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
215 			.cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx),
216 			.cra_module = THIS_MODULE,
217 			.cra_alignmask = 0xf,
218 			.cra_init = sun8i_ce_cipher_init,
219 			.cra_exit = sun8i_ce_cipher_exit,
220 		},
221 		.min_keysize	= AES_MIN_KEY_SIZE,
222 		.max_keysize	= AES_MAX_KEY_SIZE,
223 		.setkey		= sun8i_ce_aes_setkey,
224 		.encrypt	= sun8i_ce_skencrypt,
225 		.decrypt	= sun8i_ce_skdecrypt,
226 	}
227 },
228 {
229 	.type = CRYPTO_ALG_TYPE_SKCIPHER,
230 	.ce_algo_id = CE_ID_CIPHER_DES3,
231 	.ce_blockmode = CE_ID_OP_CBC,
232 	.alg.skcipher = {
233 		.base = {
234 			.cra_name = "cbc(des3_ede)",
235 			.cra_driver_name = "cbc-des3-sun8i-ce",
236 			.cra_priority = 400,
237 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
238 			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
239 				CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
240 			.cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx),
241 			.cra_module = THIS_MODULE,
242 			.cra_alignmask = 0xf,
243 			.cra_init = sun8i_ce_cipher_init,
244 			.cra_exit = sun8i_ce_cipher_exit,
245 		},
246 		.min_keysize	= DES3_EDE_KEY_SIZE,
247 		.max_keysize	= DES3_EDE_KEY_SIZE,
248 		.ivsize		= DES3_EDE_BLOCK_SIZE,
249 		.setkey		= sun8i_ce_des3_setkey,
250 		.encrypt	= sun8i_ce_skencrypt,
251 		.decrypt	= sun8i_ce_skdecrypt,
252 	}
253 },
254 {
255 	.type = CRYPTO_ALG_TYPE_SKCIPHER,
256 	.ce_algo_id = CE_ID_CIPHER_DES3,
257 	.ce_blockmode = CE_ID_OP_ECB,
258 	.alg.skcipher = {
259 		.base = {
260 			.cra_name = "ecb(des3_ede)",
261 			.cra_driver_name = "ecb-des3-sun8i-ce",
262 			.cra_priority = 400,
263 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
264 			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
265 				CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
266 			.cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx),
267 			.cra_module = THIS_MODULE,
268 			.cra_alignmask = 0xf,
269 			.cra_init = sun8i_ce_cipher_init,
270 			.cra_exit = sun8i_ce_cipher_exit,
271 		},
272 		.min_keysize	= DES3_EDE_KEY_SIZE,
273 		.max_keysize	= DES3_EDE_KEY_SIZE,
274 		.setkey		= sun8i_ce_des3_setkey,
275 		.encrypt	= sun8i_ce_skencrypt,
276 		.decrypt	= sun8i_ce_skdecrypt,
277 	}
278 },
279 };
280 
281 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
282 static int sun8i_ce_dbgfs_read(struct seq_file *seq, void *v)
283 {
284 	struct sun8i_ce_dev *ce = seq->private;
285 	int i;
286 
287 	for (i = 0; i < MAXFLOW; i++)
288 		seq_printf(seq, "Channel %d: nreq %lu\n", i, ce->chanlist[i].stat_req);
289 
290 	for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
291 		if (!ce_algs[i].ce)
292 			continue;
293 		switch (ce_algs[i].type) {
294 		case CRYPTO_ALG_TYPE_SKCIPHER:
295 			seq_printf(seq, "%s %s %lu %lu\n",
296 				   ce_algs[i].alg.skcipher.base.cra_driver_name,
297 				   ce_algs[i].alg.skcipher.base.cra_name,
298 				   ce_algs[i].stat_req, ce_algs[i].stat_fb);
299 			break;
300 		}
301 	}
302 	return 0;
303 }
304 
305 static int sun8i_ce_dbgfs_open(struct inode *inode, struct file *file)
306 {
307 	return single_open(file, sun8i_ce_dbgfs_read, inode->i_private);
308 }
309 
310 static const struct file_operations sun8i_ce_debugfs_fops = {
311 	.owner = THIS_MODULE,
312 	.open = sun8i_ce_dbgfs_open,
313 	.read = seq_read,
314 	.llseek = seq_lseek,
315 	.release = single_release,
316 };
317 #endif
318 
319 static void sun8i_ce_free_chanlist(struct sun8i_ce_dev *ce, int i)
320 {
321 	while (i >= 0) {
322 		crypto_engine_exit(ce->chanlist[i].engine);
323 		if (ce->chanlist[i].tl)
324 			dma_free_coherent(ce->dev, sizeof(struct ce_task),
325 					  ce->chanlist[i].tl,
326 					  ce->chanlist[i].t_phy);
327 		i--;
328 	}
329 }
330 
331 /*
332  * Allocate the channel list structure
333  */
334 static int sun8i_ce_allocate_chanlist(struct sun8i_ce_dev *ce)
335 {
336 	int i, err;
337 
338 	ce->chanlist = devm_kcalloc(ce->dev, MAXFLOW,
339 				    sizeof(struct sun8i_ce_flow), GFP_KERNEL);
340 	if (!ce->chanlist)
341 		return -ENOMEM;
342 
343 	for (i = 0; i < MAXFLOW; i++) {
344 		init_completion(&ce->chanlist[i].complete);
345 
346 		ce->chanlist[i].engine = crypto_engine_alloc_init(ce->dev, true);
347 		if (!ce->chanlist[i].engine) {
348 			dev_err(ce->dev, "Cannot allocate engine\n");
349 			i--;
350 			err = -ENOMEM;
351 			goto error_engine;
352 		}
353 		err = crypto_engine_start(ce->chanlist[i].engine);
354 		if (err) {
355 			dev_err(ce->dev, "Cannot start engine\n");
356 			goto error_engine;
357 		}
358 		ce->chanlist[i].tl = dma_alloc_coherent(ce->dev,
359 							sizeof(struct ce_task),
360 							&ce->chanlist[i].t_phy,
361 							GFP_KERNEL);
362 		if (!ce->chanlist[i].tl) {
363 			dev_err(ce->dev, "Cannot get DMA memory for task %d\n",
364 				i);
365 			err = -ENOMEM;
366 			goto error_engine;
367 		}
368 	}
369 	return 0;
370 error_engine:
371 	sun8i_ce_free_chanlist(ce, i);
372 	return err;
373 }
374 
375 /*
376  * Power management strategy: The device is suspended unless a TFM exists for
377  * one of the algorithms proposed by this driver.
378  */
379 static int sun8i_ce_pm_suspend(struct device *dev)
380 {
381 	struct sun8i_ce_dev *ce = dev_get_drvdata(dev);
382 	int i;
383 
384 	reset_control_assert(ce->reset);
385 	for (i = 0; i < CE_MAX_CLOCKS; i++)
386 		clk_disable_unprepare(ce->ceclks[i]);
387 	return 0;
388 }
389 
390 static int sun8i_ce_pm_resume(struct device *dev)
391 {
392 	struct sun8i_ce_dev *ce = dev_get_drvdata(dev);
393 	int err, i;
394 
395 	for (i = 0; i < CE_MAX_CLOCKS; i++) {
396 		if (!ce->variant->ce_clks[i].name)
397 			continue;
398 		err = clk_prepare_enable(ce->ceclks[i]);
399 		if (err) {
400 			dev_err(ce->dev, "Cannot prepare_enable %s\n",
401 				ce->variant->ce_clks[i].name);
402 			goto error;
403 		}
404 	}
405 	err = reset_control_deassert(ce->reset);
406 	if (err) {
407 		dev_err(ce->dev, "Cannot deassert reset control\n");
408 		goto error;
409 	}
410 	return 0;
411 error:
412 	sun8i_ce_pm_suspend(dev);
413 	return err;
414 }
415 
416 static const struct dev_pm_ops sun8i_ce_pm_ops = {
417 	SET_RUNTIME_PM_OPS(sun8i_ce_pm_suspend, sun8i_ce_pm_resume, NULL)
418 };
419 
420 static int sun8i_ce_pm_init(struct sun8i_ce_dev *ce)
421 {
422 	int err;
423 
424 	pm_runtime_use_autosuspend(ce->dev);
425 	pm_runtime_set_autosuspend_delay(ce->dev, 2000);
426 
427 	err = pm_runtime_set_suspended(ce->dev);
428 	if (err)
429 		return err;
430 	pm_runtime_enable(ce->dev);
431 	return err;
432 }
433 
434 static void sun8i_ce_pm_exit(struct sun8i_ce_dev *ce)
435 {
436 	pm_runtime_disable(ce->dev);
437 }
438 
439 static int sun8i_ce_get_clks(struct sun8i_ce_dev *ce)
440 {
441 	unsigned long cr;
442 	int err, i;
443 
444 	for (i = 0; i < CE_MAX_CLOCKS; i++) {
445 		if (!ce->variant->ce_clks[i].name)
446 			continue;
447 		ce->ceclks[i] = devm_clk_get(ce->dev, ce->variant->ce_clks[i].name);
448 		if (IS_ERR(ce->ceclks[i])) {
449 			err = PTR_ERR(ce->ceclks[i]);
450 			dev_err(ce->dev, "Cannot get %s CE clock err=%d\n",
451 				ce->variant->ce_clks[i].name, err);
452 			return err;
453 		}
454 		cr = clk_get_rate(ce->ceclks[i]);
455 		if (!cr)
456 			return -EINVAL;
457 		if (ce->variant->ce_clks[i].freq > 0 &&
458 		    cr != ce->variant->ce_clks[i].freq) {
459 			dev_info(ce->dev, "Set %s clock to %lu (%lu Mhz) from %lu (%lu Mhz)\n",
460 				 ce->variant->ce_clks[i].name,
461 				 ce->variant->ce_clks[i].freq,
462 				 ce->variant->ce_clks[i].freq / 1000000,
463 				 cr, cr / 1000000);
464 			err = clk_set_rate(ce->ceclks[i], ce->variant->ce_clks[i].freq);
465 			if (err)
466 				dev_err(ce->dev, "Fail to set %s clk speed to %lu hz\n",
467 					ce->variant->ce_clks[i].name,
468 					ce->variant->ce_clks[i].freq);
469 		}
470 		if (ce->variant->ce_clks[i].max_freq > 0 &&
471 		    cr > ce->variant->ce_clks[i].max_freq)
472 			dev_warn(ce->dev, "Frequency for %s (%lu hz) is higher than datasheet's recommendation (%lu hz)",
473 				 ce->variant->ce_clks[i].name, cr,
474 				 ce->variant->ce_clks[i].max_freq);
475 	}
476 	return 0;
477 }
478 
479 static int sun8i_ce_register_algs(struct sun8i_ce_dev *ce)
480 {
481 	int ce_method, err, id, i;
482 
483 	for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
484 		ce_algs[i].ce = ce;
485 		switch (ce_algs[i].type) {
486 		case CRYPTO_ALG_TYPE_SKCIPHER:
487 			id = ce_algs[i].ce_algo_id;
488 			ce_method = ce->variant->alg_cipher[id];
489 			if (ce_method == CE_ID_NOTSUPP) {
490 				dev_dbg(ce->dev,
491 					"DEBUG: Algo of %s not supported\n",
492 					ce_algs[i].alg.skcipher.base.cra_name);
493 				ce_algs[i].ce = NULL;
494 				break;
495 			}
496 			id = ce_algs[i].ce_blockmode;
497 			ce_method = ce->variant->op_mode[id];
498 			if (ce_method == CE_ID_NOTSUPP) {
499 				dev_dbg(ce->dev, "DEBUG: Blockmode of %s not supported\n",
500 					ce_algs[i].alg.skcipher.base.cra_name);
501 				ce_algs[i].ce = NULL;
502 				break;
503 			}
504 			dev_info(ce->dev, "Register %s\n",
505 				 ce_algs[i].alg.skcipher.base.cra_name);
506 			err = crypto_register_skcipher(&ce_algs[i].alg.skcipher);
507 			if (err) {
508 				dev_err(ce->dev, "ERROR: Fail to register %s\n",
509 					ce_algs[i].alg.skcipher.base.cra_name);
510 				ce_algs[i].ce = NULL;
511 				return err;
512 			}
513 			break;
514 		default:
515 			ce_algs[i].ce = NULL;
516 			dev_err(ce->dev, "ERROR: tried to register an unknown algo\n");
517 		}
518 	}
519 	return 0;
520 }
521 
522 static void sun8i_ce_unregister_algs(struct sun8i_ce_dev *ce)
523 {
524 	int i;
525 
526 	for (i = 0; i < ARRAY_SIZE(ce_algs); i++) {
527 		if (!ce_algs[i].ce)
528 			continue;
529 		switch (ce_algs[i].type) {
530 		case CRYPTO_ALG_TYPE_SKCIPHER:
531 			dev_info(ce->dev, "Unregister %d %s\n", i,
532 				 ce_algs[i].alg.skcipher.base.cra_name);
533 			crypto_unregister_skcipher(&ce_algs[i].alg.skcipher);
534 			break;
535 		}
536 	}
537 }
538 
539 static int sun8i_ce_probe(struct platform_device *pdev)
540 {
541 	struct sun8i_ce_dev *ce;
542 	int err, irq;
543 	u32 v;
544 
545 	ce = devm_kzalloc(&pdev->dev, sizeof(*ce), GFP_KERNEL);
546 	if (!ce)
547 		return -ENOMEM;
548 
549 	ce->dev = &pdev->dev;
550 	platform_set_drvdata(pdev, ce);
551 
552 	ce->variant = of_device_get_match_data(&pdev->dev);
553 	if (!ce->variant) {
554 		dev_err(&pdev->dev, "Missing Crypto Engine variant\n");
555 		return -EINVAL;
556 	}
557 
558 	ce->base = devm_platform_ioremap_resource(pdev, 0);
559 	if (IS_ERR(ce->base))
560 		return PTR_ERR(ce->base);
561 
562 	err = sun8i_ce_get_clks(ce);
563 	if (err)
564 		return err;
565 
566 	/* Get Non Secure IRQ */
567 	irq = platform_get_irq(pdev, 0);
568 	if (irq < 0)
569 		return irq;
570 
571 	ce->reset = devm_reset_control_get(&pdev->dev, NULL);
572 	if (IS_ERR(ce->reset)) {
573 		if (PTR_ERR(ce->reset) == -EPROBE_DEFER)
574 			return PTR_ERR(ce->reset);
575 		dev_err(&pdev->dev, "No reset control found\n");
576 		return PTR_ERR(ce->reset);
577 	}
578 
579 	mutex_init(&ce->mlock);
580 
581 	err = sun8i_ce_allocate_chanlist(ce);
582 	if (err)
583 		return err;
584 
585 	err = sun8i_ce_pm_init(ce);
586 	if (err)
587 		goto error_pm;
588 
589 	err = devm_request_irq(&pdev->dev, irq, ce_irq_handler, 0,
590 			       "sun8i-ce-ns", ce);
591 	if (err) {
592 		dev_err(ce->dev, "Cannot request CryptoEngine Non-secure IRQ (err=%d)\n", err);
593 		goto error_irq;
594 	}
595 
596 	err = sun8i_ce_register_algs(ce);
597 	if (err)
598 		goto error_alg;
599 
600 	err = pm_runtime_get_sync(ce->dev);
601 	if (err < 0)
602 		goto error_alg;
603 
604 	v = readl(ce->base + CE_CTR);
605 	v >>= CE_DIE_ID_SHIFT;
606 	v &= CE_DIE_ID_MASK;
607 	dev_info(&pdev->dev, "CryptoEngine Die ID %x\n", v);
608 
609 	pm_runtime_put_sync(ce->dev);
610 
611 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
612 	/* Ignore error of debugfs */
613 	ce->dbgfs_dir = debugfs_create_dir("sun8i-ce", NULL);
614 	ce->dbgfs_stats = debugfs_create_file("stats", 0444,
615 					      ce->dbgfs_dir, ce,
616 					      &sun8i_ce_debugfs_fops);
617 #endif
618 
619 	return 0;
620 error_alg:
621 	sun8i_ce_unregister_algs(ce);
622 error_irq:
623 	sun8i_ce_pm_exit(ce);
624 error_pm:
625 	sun8i_ce_free_chanlist(ce, MAXFLOW - 1);
626 	return err;
627 }
628 
629 static int sun8i_ce_remove(struct platform_device *pdev)
630 {
631 	struct sun8i_ce_dev *ce = platform_get_drvdata(pdev);
632 
633 	sun8i_ce_unregister_algs(ce);
634 
635 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
636 	debugfs_remove_recursive(ce->dbgfs_dir);
637 #endif
638 
639 	sun8i_ce_free_chanlist(ce, MAXFLOW - 1);
640 
641 	sun8i_ce_pm_exit(ce);
642 	return 0;
643 }
644 
645 static const struct of_device_id sun8i_ce_crypto_of_match_table[] = {
646 	{ .compatible = "allwinner,sun8i-h3-crypto",
647 	  .data = &ce_h3_variant },
648 	{ .compatible = "allwinner,sun8i-r40-crypto",
649 	  .data = &ce_r40_variant },
650 	{ .compatible = "allwinner,sun50i-a64-crypto",
651 	  .data = &ce_a64_variant },
652 	{ .compatible = "allwinner,sun50i-h5-crypto",
653 	  .data = &ce_h5_variant },
654 	{ .compatible = "allwinner,sun50i-h6-crypto",
655 	  .data = &ce_h6_variant },
656 	{}
657 };
658 MODULE_DEVICE_TABLE(of, sun8i_ce_crypto_of_match_table);
659 
660 static struct platform_driver sun8i_ce_driver = {
661 	.probe		 = sun8i_ce_probe,
662 	.remove		 = sun8i_ce_remove,
663 	.driver		 = {
664 		.name		= "sun8i-ce",
665 		.pm		= &sun8i_ce_pm_ops,
666 		.of_match_table	= sun8i_ce_crypto_of_match_table,
667 	},
668 };
669 
670 module_platform_driver(sun8i_ce_driver);
671 
672 MODULE_DESCRIPTION("Allwinner Crypto Engine cryptographic offloader");
673 MODULE_LICENSE("GPL");
674 MODULE_AUTHOR("Corentin Labbe <clabbe.montjoie@gmail.com>");
675