148fe583fSCorentin Labbe // SPDX-License-Identifier: GPL-2.0
248fe583fSCorentin Labbe /*
348fe583fSCorentin Labbe  * amlgoic-core.c - hardware cryptographic offloader for Amlogic GXL SoC
448fe583fSCorentin Labbe  *
548fe583fSCorentin Labbe  * Copyright (C) 2018-2019 Corentin Labbe <clabbe@baylibre.com>
648fe583fSCorentin Labbe  *
748fe583fSCorentin Labbe  * Core file which registers crypto algorithms supported by the hardware.
848fe583fSCorentin Labbe  */
9*4dd4d5e4SHerbert Xu 
10*4dd4d5e4SHerbert Xu #include <crypto/engine.h>
11*4dd4d5e4SHerbert Xu #include <crypto/internal/skcipher.h>
1248fe583fSCorentin Labbe #include <linux/clk.h>
13*4dd4d5e4SHerbert Xu #include <linux/dma-mapping.h>
14*4dd4d5e4SHerbert Xu #include <linux/err.h>
1548fe583fSCorentin Labbe #include <linux/interrupt.h>
16*4dd4d5e4SHerbert Xu #include <linux/io.h>
1748fe583fSCorentin Labbe #include <linux/irq.h>
18*4dd4d5e4SHerbert Xu #include <linux/kernel.h>
1948fe583fSCorentin Labbe #include <linux/module.h>
2048fe583fSCorentin Labbe #include <linux/of.h>
2148fe583fSCorentin Labbe #include <linux/platform_device.h>
2248fe583fSCorentin Labbe 
2348fe583fSCorentin Labbe #include "amlogic-gxl.h"
2448fe583fSCorentin Labbe 
meson_irq_handler(int irq,void * data)2548fe583fSCorentin Labbe static irqreturn_t meson_irq_handler(int irq, void *data)
2648fe583fSCorentin Labbe {
2748fe583fSCorentin Labbe 	struct meson_dev *mc = (struct meson_dev *)data;
2848fe583fSCorentin Labbe 	int flow;
2948fe583fSCorentin Labbe 	u32 p;
3048fe583fSCorentin Labbe 
3148fe583fSCorentin Labbe 	for (flow = 0; flow < MAXFLOW; flow++) {
3248fe583fSCorentin Labbe 		if (mc->irqs[flow] == irq) {
3348fe583fSCorentin Labbe 			p = readl(mc->base + ((0x04 + flow) << 2));
3448fe583fSCorentin Labbe 			if (p) {
3548fe583fSCorentin Labbe 				writel_relaxed(0xF, mc->base + ((0x4 + flow) << 2));
3648fe583fSCorentin Labbe 				mc->chanlist[flow].status = 1;
3748fe583fSCorentin Labbe 				complete(&mc->chanlist[flow].complete);
3848fe583fSCorentin Labbe 				return IRQ_HANDLED;
3948fe583fSCorentin Labbe 			}
4048fe583fSCorentin Labbe 			dev_err(mc->dev, "%s %d Got irq for flow %d but ctrl is empty\n", __func__, irq, flow);
4148fe583fSCorentin Labbe 		}
4248fe583fSCorentin Labbe 	}
4348fe583fSCorentin Labbe 
4448fe583fSCorentin Labbe 	dev_err(mc->dev, "%s %d from unknown irq\n", __func__, irq);
4548fe583fSCorentin Labbe 	return IRQ_HANDLED;
4648fe583fSCorentin Labbe }
4748fe583fSCorentin Labbe 
4848fe583fSCorentin Labbe static struct meson_alg_template mc_algs[] = {
4948fe583fSCorentin Labbe {
5048fe583fSCorentin Labbe 	.type = CRYPTO_ALG_TYPE_SKCIPHER,
5148fe583fSCorentin Labbe 	.blockmode = MESON_OPMODE_CBC,
52*4dd4d5e4SHerbert Xu 	.alg.skcipher.base = {
5348fe583fSCorentin Labbe 		.base = {
5448fe583fSCorentin Labbe 			.cra_name = "cbc(aes)",
5548fe583fSCorentin Labbe 			.cra_driver_name = "cbc-aes-gxl",
5648fe583fSCorentin Labbe 			.cra_priority = 400,
5748fe583fSCorentin Labbe 			.cra_blocksize = AES_BLOCK_SIZE,
5848fe583fSCorentin Labbe 			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
59b8aa7dc5SMikulas Patocka 				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
60b8aa7dc5SMikulas Patocka 				CRYPTO_ALG_NEED_FALLBACK,
6148fe583fSCorentin Labbe 			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
6248fe583fSCorentin Labbe 			.cra_module = THIS_MODULE,
6348fe583fSCorentin Labbe 			.cra_alignmask = 0xf,
6448fe583fSCorentin Labbe 			.cra_init = meson_cipher_init,
6548fe583fSCorentin Labbe 			.cra_exit = meson_cipher_exit,
6648fe583fSCorentin Labbe 		},
6748fe583fSCorentin Labbe 		.min_keysize	= AES_MIN_KEY_SIZE,
6848fe583fSCorentin Labbe 		.max_keysize	= AES_MAX_KEY_SIZE,
6948fe583fSCorentin Labbe 		.ivsize		= AES_BLOCK_SIZE,
7048fe583fSCorentin Labbe 		.setkey		= meson_aes_setkey,
7148fe583fSCorentin Labbe 		.encrypt	= meson_skencrypt,
7248fe583fSCorentin Labbe 		.decrypt	= meson_skdecrypt,
73*4dd4d5e4SHerbert Xu 	},
74*4dd4d5e4SHerbert Xu 	.alg.skcipher.op = {
75*4dd4d5e4SHerbert Xu 		.do_one_request = meson_handle_cipher_request,
76*4dd4d5e4SHerbert Xu 	},
7748fe583fSCorentin Labbe },
7848fe583fSCorentin Labbe {
7948fe583fSCorentin Labbe 	.type = CRYPTO_ALG_TYPE_SKCIPHER,
8048fe583fSCorentin Labbe 	.blockmode = MESON_OPMODE_ECB,
81*4dd4d5e4SHerbert Xu 	.alg.skcipher.base = {
8248fe583fSCorentin Labbe 		.base = {
8348fe583fSCorentin Labbe 			.cra_name = "ecb(aes)",
8448fe583fSCorentin Labbe 			.cra_driver_name = "ecb-aes-gxl",
8548fe583fSCorentin Labbe 			.cra_priority = 400,
8648fe583fSCorentin Labbe 			.cra_blocksize = AES_BLOCK_SIZE,
8748fe583fSCorentin Labbe 			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
88b8aa7dc5SMikulas Patocka 				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
89b8aa7dc5SMikulas Patocka 				CRYPTO_ALG_NEED_FALLBACK,
9048fe583fSCorentin Labbe 			.cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
9148fe583fSCorentin Labbe 			.cra_module = THIS_MODULE,
9248fe583fSCorentin Labbe 			.cra_alignmask = 0xf,
9348fe583fSCorentin Labbe 			.cra_init = meson_cipher_init,
9448fe583fSCorentin Labbe 			.cra_exit = meson_cipher_exit,
9548fe583fSCorentin Labbe 		},
9648fe583fSCorentin Labbe 		.min_keysize	= AES_MIN_KEY_SIZE,
9748fe583fSCorentin Labbe 		.max_keysize	= AES_MAX_KEY_SIZE,
9848fe583fSCorentin Labbe 		.setkey		= meson_aes_setkey,
9948fe583fSCorentin Labbe 		.encrypt	= meson_skencrypt,
10048fe583fSCorentin Labbe 		.decrypt	= meson_skdecrypt,
101*4dd4d5e4SHerbert Xu 	},
102*4dd4d5e4SHerbert Xu 	.alg.skcipher.op = {
103*4dd4d5e4SHerbert Xu 		.do_one_request = meson_handle_cipher_request,
104*4dd4d5e4SHerbert Xu 	},
10548fe583fSCorentin Labbe },
10648fe583fSCorentin Labbe };
10748fe583fSCorentin Labbe 
meson_debugfs_show(struct seq_file * seq,void * v)108b11d9063SQinglang Miao static int meson_debugfs_show(struct seq_file *seq, void *v)
10948fe583fSCorentin Labbe {
110*4dd4d5e4SHerbert Xu 	struct meson_dev *mc __maybe_unused = seq->private;
11148fe583fSCorentin Labbe 	int i;
11248fe583fSCorentin Labbe 
11348fe583fSCorentin Labbe 	for (i = 0; i < MAXFLOW; i++)
114*4dd4d5e4SHerbert Xu 		seq_printf(seq, "Channel %d: nreq %lu\n", i,
115*4dd4d5e4SHerbert Xu #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
116*4dd4d5e4SHerbert Xu 			   mc->chanlist[i].stat_req);
117*4dd4d5e4SHerbert Xu #else
118*4dd4d5e4SHerbert Xu 			   0ul);
119*4dd4d5e4SHerbert Xu #endif
12048fe583fSCorentin Labbe 
12148fe583fSCorentin Labbe 	for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
12248fe583fSCorentin Labbe 		switch (mc_algs[i].type) {
12348fe583fSCorentin Labbe 		case CRYPTO_ALG_TYPE_SKCIPHER:
12448fe583fSCorentin Labbe 			seq_printf(seq, "%s %s %lu %lu\n",
125*4dd4d5e4SHerbert Xu 				   mc_algs[i].alg.skcipher.base.base.cra_driver_name,
126*4dd4d5e4SHerbert Xu 				   mc_algs[i].alg.skcipher.base.base.cra_name,
127*4dd4d5e4SHerbert Xu #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
12848fe583fSCorentin Labbe 				   mc_algs[i].stat_req, mc_algs[i].stat_fb);
129*4dd4d5e4SHerbert Xu #else
130*4dd4d5e4SHerbert Xu 				   0ul, 0ul);
131*4dd4d5e4SHerbert Xu #endif
13248fe583fSCorentin Labbe 			break;
13348fe583fSCorentin Labbe 		}
13448fe583fSCorentin Labbe 	}
13548fe583fSCorentin Labbe 	return 0;
13648fe583fSCorentin Labbe }
137b11d9063SQinglang Miao DEFINE_SHOW_ATTRIBUTE(meson_debugfs);
13848fe583fSCorentin Labbe 
meson_free_chanlist(struct meson_dev * mc,int i)13948fe583fSCorentin Labbe static void meson_free_chanlist(struct meson_dev *mc, int i)
14048fe583fSCorentin Labbe {
14148fe583fSCorentin Labbe 	while (i >= 0) {
14248fe583fSCorentin Labbe 		crypto_engine_exit(mc->chanlist[i].engine);
14348fe583fSCorentin Labbe 		if (mc->chanlist[i].tl)
14448fe583fSCorentin Labbe 			dma_free_coherent(mc->dev, sizeof(struct meson_desc) * MAXDESC,
14548fe583fSCorentin Labbe 					  mc->chanlist[i].tl,
14648fe583fSCorentin Labbe 					  mc->chanlist[i].t_phy);
14748fe583fSCorentin Labbe 		i--;
14848fe583fSCorentin Labbe 	}
14948fe583fSCorentin Labbe }
15048fe583fSCorentin Labbe 
15148fe583fSCorentin Labbe /*
15248fe583fSCorentin Labbe  * Allocate the channel list structure
15348fe583fSCorentin Labbe  */
meson_allocate_chanlist(struct meson_dev * mc)15448fe583fSCorentin Labbe static int meson_allocate_chanlist(struct meson_dev *mc)
15548fe583fSCorentin Labbe {
15648fe583fSCorentin Labbe 	int i, err;
15748fe583fSCorentin Labbe 
15848fe583fSCorentin Labbe 	mc->chanlist = devm_kcalloc(mc->dev, MAXFLOW,
15948fe583fSCorentin Labbe 				    sizeof(struct meson_flow), GFP_KERNEL);
16048fe583fSCorentin Labbe 	if (!mc->chanlist)
16148fe583fSCorentin Labbe 		return -ENOMEM;
16248fe583fSCorentin Labbe 
16348fe583fSCorentin Labbe 	for (i = 0; i < MAXFLOW; i++) {
16448fe583fSCorentin Labbe 		init_completion(&mc->chanlist[i].complete);
16548fe583fSCorentin Labbe 
16648fe583fSCorentin Labbe 		mc->chanlist[i].engine = crypto_engine_alloc_init(mc->dev, true);
16748fe583fSCorentin Labbe 		if (!mc->chanlist[i].engine) {
16848fe583fSCorentin Labbe 			dev_err(mc->dev, "Cannot allocate engine\n");
16948fe583fSCorentin Labbe 			i--;
170a9704293SColin Ian King 			err = -ENOMEM;
17148fe583fSCorentin Labbe 			goto error_engine;
17248fe583fSCorentin Labbe 		}
17348fe583fSCorentin Labbe 		err = crypto_engine_start(mc->chanlist[i].engine);
17448fe583fSCorentin Labbe 		if (err) {
17548fe583fSCorentin Labbe 			dev_err(mc->dev, "Cannot start engine\n");
17648fe583fSCorentin Labbe 			goto error_engine;
17748fe583fSCorentin Labbe 		}
17848fe583fSCorentin Labbe 		mc->chanlist[i].tl = dma_alloc_coherent(mc->dev,
17948fe583fSCorentin Labbe 							sizeof(struct meson_desc) * MAXDESC,
18048fe583fSCorentin Labbe 							&mc->chanlist[i].t_phy,
18148fe583fSCorentin Labbe 							GFP_KERNEL);
18248fe583fSCorentin Labbe 		if (!mc->chanlist[i].tl) {
18348fe583fSCorentin Labbe 			err = -ENOMEM;
18448fe583fSCorentin Labbe 			goto error_engine;
18548fe583fSCorentin Labbe 		}
18648fe583fSCorentin Labbe 	}
18748fe583fSCorentin Labbe 	return 0;
18848fe583fSCorentin Labbe error_engine:
18948fe583fSCorentin Labbe 	meson_free_chanlist(mc, i);
19048fe583fSCorentin Labbe 	return err;
19148fe583fSCorentin Labbe }
19248fe583fSCorentin Labbe 
meson_register_algs(struct meson_dev * mc)19348fe583fSCorentin Labbe static int meson_register_algs(struct meson_dev *mc)
19448fe583fSCorentin Labbe {
19548fe583fSCorentin Labbe 	int err, i;
19648fe583fSCorentin Labbe 
19748fe583fSCorentin Labbe 	for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
19848fe583fSCorentin Labbe 		mc_algs[i].mc = mc;
19948fe583fSCorentin Labbe 		switch (mc_algs[i].type) {
20048fe583fSCorentin Labbe 		case CRYPTO_ALG_TYPE_SKCIPHER:
201*4dd4d5e4SHerbert Xu 			err = crypto_engine_register_skcipher(&mc_algs[i].alg.skcipher);
20248fe583fSCorentin Labbe 			if (err) {
20348fe583fSCorentin Labbe 				dev_err(mc->dev, "Fail to register %s\n",
204*4dd4d5e4SHerbert Xu 					mc_algs[i].alg.skcipher.base.base.cra_name);
20548fe583fSCorentin Labbe 				mc_algs[i].mc = NULL;
20648fe583fSCorentin Labbe 				return err;
20748fe583fSCorentin Labbe 			}
20848fe583fSCorentin Labbe 			break;
20948fe583fSCorentin Labbe 		}
21048fe583fSCorentin Labbe 	}
21148fe583fSCorentin Labbe 
21248fe583fSCorentin Labbe 	return 0;
21348fe583fSCorentin Labbe }
21448fe583fSCorentin Labbe 
meson_unregister_algs(struct meson_dev * mc)21548fe583fSCorentin Labbe static void meson_unregister_algs(struct meson_dev *mc)
21648fe583fSCorentin Labbe {
21748fe583fSCorentin Labbe 	int i;
21848fe583fSCorentin Labbe 
21948fe583fSCorentin Labbe 	for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
22048fe583fSCorentin Labbe 		if (!mc_algs[i].mc)
22148fe583fSCorentin Labbe 			continue;
22248fe583fSCorentin Labbe 		switch (mc_algs[i].type) {
22348fe583fSCorentin Labbe 		case CRYPTO_ALG_TYPE_SKCIPHER:
224*4dd4d5e4SHerbert Xu 			crypto_engine_unregister_skcipher(&mc_algs[i].alg.skcipher);
22548fe583fSCorentin Labbe 			break;
22648fe583fSCorentin Labbe 		}
22748fe583fSCorentin Labbe 	}
22848fe583fSCorentin Labbe }
22948fe583fSCorentin Labbe 
meson_crypto_probe(struct platform_device * pdev)23048fe583fSCorentin Labbe static int meson_crypto_probe(struct platform_device *pdev)
23148fe583fSCorentin Labbe {
23248fe583fSCorentin Labbe 	struct meson_dev *mc;
23348fe583fSCorentin Labbe 	int err, i;
23448fe583fSCorentin Labbe 
23548fe583fSCorentin Labbe 	mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
23648fe583fSCorentin Labbe 	if (!mc)
23748fe583fSCorentin Labbe 		return -ENOMEM;
23848fe583fSCorentin Labbe 
23948fe583fSCorentin Labbe 	mc->dev = &pdev->dev;
24048fe583fSCorentin Labbe 	platform_set_drvdata(pdev, mc);
24148fe583fSCorentin Labbe 
24248fe583fSCorentin Labbe 	mc->base = devm_platform_ioremap_resource(pdev, 0);
24348fe583fSCorentin Labbe 	if (IS_ERR(mc->base)) {
24448fe583fSCorentin Labbe 		err = PTR_ERR(mc->base);
24548fe583fSCorentin Labbe 		dev_err(&pdev->dev, "Cannot request MMIO err=%d\n", err);
24648fe583fSCorentin Labbe 		return err;
24748fe583fSCorentin Labbe 	}
24848fe583fSCorentin Labbe 	mc->busclk = devm_clk_get(&pdev->dev, "blkmv");
24948fe583fSCorentin Labbe 	if (IS_ERR(mc->busclk)) {
25048fe583fSCorentin Labbe 		err = PTR_ERR(mc->busclk);
25148fe583fSCorentin Labbe 		dev_err(&pdev->dev, "Cannot get core clock err=%d\n", err);
25248fe583fSCorentin Labbe 		return err;
25348fe583fSCorentin Labbe 	}
25448fe583fSCorentin Labbe 
25548fe583fSCorentin Labbe 	for (i = 0; i < MAXFLOW; i++) {
25648fe583fSCorentin Labbe 		mc->irqs[i] = platform_get_irq(pdev, i);
25756e0b627STang Bin 		if (mc->irqs[i] < 0)
25848fe583fSCorentin Labbe 			return mc->irqs[i];
25948fe583fSCorentin Labbe 
26048fe583fSCorentin Labbe 		err = devm_request_irq(&pdev->dev, mc->irqs[i], meson_irq_handler, 0,
26148fe583fSCorentin Labbe 				       "gxl-crypto", mc);
26248fe583fSCorentin Labbe 		if (err < 0) {
26348fe583fSCorentin Labbe 			dev_err(mc->dev, "Cannot request IRQ for flow %d\n", i);
26448fe583fSCorentin Labbe 			return err;
26548fe583fSCorentin Labbe 		}
26648fe583fSCorentin Labbe 	}
26748fe583fSCorentin Labbe 
26848fe583fSCorentin Labbe 	err = clk_prepare_enable(mc->busclk);
26948fe583fSCorentin Labbe 	if (err != 0) {
27048fe583fSCorentin Labbe 		dev_err(&pdev->dev, "Cannot prepare_enable busclk\n");
27148fe583fSCorentin Labbe 		return err;
27248fe583fSCorentin Labbe 	}
27348fe583fSCorentin Labbe 
27448fe583fSCorentin Labbe 	err = meson_allocate_chanlist(mc);
27548fe583fSCorentin Labbe 	if (err)
27648fe583fSCorentin Labbe 		goto error_flow;
27748fe583fSCorentin Labbe 
27848fe583fSCorentin Labbe 	err = meson_register_algs(mc);
27948fe583fSCorentin Labbe 	if (err)
28048fe583fSCorentin Labbe 		goto error_alg;
28148fe583fSCorentin Labbe 
282*4dd4d5e4SHerbert Xu 	if (IS_ENABLED(CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG)) {
283*4dd4d5e4SHerbert Xu 		struct dentry *dbgfs_dir;
284*4dd4d5e4SHerbert Xu 
285*4dd4d5e4SHerbert Xu 		dbgfs_dir = debugfs_create_dir("gxl-crypto", NULL);
286*4dd4d5e4SHerbert Xu 		debugfs_create_file("stats", 0444, dbgfs_dir, mc, &meson_debugfs_fops);
287*4dd4d5e4SHerbert Xu 
28848fe583fSCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
289*4dd4d5e4SHerbert Xu 		mc->dbgfs_dir = dbgfs_dir;
29048fe583fSCorentin Labbe #endif
291*4dd4d5e4SHerbert Xu 	}
29248fe583fSCorentin Labbe 
29348fe583fSCorentin Labbe 	return 0;
29448fe583fSCorentin Labbe error_alg:
29548fe583fSCorentin Labbe 	meson_unregister_algs(mc);
29648fe583fSCorentin Labbe error_flow:
29724775ac2SCorentin Labbe 	meson_free_chanlist(mc, MAXFLOW - 1);
29848fe583fSCorentin Labbe 	clk_disable_unprepare(mc->busclk);
29948fe583fSCorentin Labbe 	return err;
30048fe583fSCorentin Labbe }
30148fe583fSCorentin Labbe 
meson_crypto_remove(struct platform_device * pdev)30248fe583fSCorentin Labbe static int meson_crypto_remove(struct platform_device *pdev)
30348fe583fSCorentin Labbe {
30448fe583fSCorentin Labbe 	struct meson_dev *mc = platform_get_drvdata(pdev);
30548fe583fSCorentin Labbe 
30648fe583fSCorentin Labbe #ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
30748fe583fSCorentin Labbe 	debugfs_remove_recursive(mc->dbgfs_dir);
30848fe583fSCorentin Labbe #endif
30948fe583fSCorentin Labbe 
31048fe583fSCorentin Labbe 	meson_unregister_algs(mc);
31148fe583fSCorentin Labbe 
31224775ac2SCorentin Labbe 	meson_free_chanlist(mc, MAXFLOW - 1);
31348fe583fSCorentin Labbe 
31448fe583fSCorentin Labbe 	clk_disable_unprepare(mc->busclk);
31548fe583fSCorentin Labbe 	return 0;
31648fe583fSCorentin Labbe }
31748fe583fSCorentin Labbe 
31848fe583fSCorentin Labbe static const struct of_device_id meson_crypto_of_match_table[] = {
31948fe583fSCorentin Labbe 	{ .compatible = "amlogic,gxl-crypto", },
32048fe583fSCorentin Labbe 	{}
32148fe583fSCorentin Labbe };
32248fe583fSCorentin Labbe MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
32348fe583fSCorentin Labbe 
32448fe583fSCorentin Labbe static struct platform_driver meson_crypto_driver = {
32548fe583fSCorentin Labbe 	.probe		 = meson_crypto_probe,
32648fe583fSCorentin Labbe 	.remove		 = meson_crypto_remove,
32748fe583fSCorentin Labbe 	.driver		 = {
32848fe583fSCorentin Labbe 		.name		   = "gxl-crypto",
32948fe583fSCorentin Labbe 		.of_match_table	= meson_crypto_of_match_table,
33048fe583fSCorentin Labbe 	},
33148fe583fSCorentin Labbe };
33248fe583fSCorentin Labbe 
33348fe583fSCorentin Labbe module_platform_driver(meson_crypto_driver);
33448fe583fSCorentin Labbe 
33548fe583fSCorentin Labbe MODULE_DESCRIPTION("Amlogic GXL cryptographic offloader");
33648fe583fSCorentin Labbe MODULE_LICENSE("GPL");
33748fe583fSCorentin Labbe MODULE_AUTHOR("Corentin Labbe <clabbe@baylibre.com>");
338