mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
crypto: fix and enable aes dma on G12B [1/1]
PD# SWPL-4823 Problem: 1. After stack optimization, stack memory cannot be mapped as dma buffers and thus causing crypto dma failed to generate correct result. 2. crypto dma was not enabled on G12B Solution: 1. Move key_iv buffer from stack to memory provided by kzalloc 2. Enable crypto dma on G12B 3. Replace module_param with debugfs 4. Replace pr_err with dev_err Verify: verified on G12B Change-Id: I6de682e3d1fc141f8c6179c7d91f9b4bff165eae Signed-off-by: Matthew Shyu <matthew.shyu@amlogic.com> Signed-off-by: Mingyen Hung <mingyen.hung@amlogic.com>
This commit is contained in:
@@ -2,10 +2,12 @@
|
||||
|
||||
These are the HW cryptographic accelerators found on Amlogic products.
|
||||
|
||||
*For S805 series and S905 series
|
||||
|
||||
* Advanced Encryption Standard (AES)
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "amlogic,aes" for aes-128/192/256 or "amlogic,aes_g12a_dma" for aes-128/256
|
||||
- compatible : Should be "amlogic,aes" for aes-128/192/256
|
||||
- dev_name : Should be "aml_aes"
|
||||
- interrupts: Should contain the IRQ line for the AES.
|
||||
- resets: Should contain the clock to enable the module
|
||||
@@ -25,10 +27,10 @@ aml_aes{
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "amlogic,des,tdes".
|
||||
- dev_name : Should be "aml_aes"
|
||||
- dev_name : Should be "aml_tdes"
|
||||
- interrupts: Should contain the IRQ line for the TDES.
|
||||
- resets: Should contain the clock to enable the module
|
||||
- reg: Should contain the base address of regs
|
||||
- reg: Should contain the base address of regs
|
||||
|
||||
Example:
|
||||
aml_tdes{
|
||||
@@ -40,29 +42,16 @@ aml_tdes{
|
||||
0x0 0xda832000 0x0 0xe4>;
|
||||
};
|
||||
|
||||
* Secure Hash Algorithm (SHA1/SHA224/SHA256)
|
||||
********************************************************************************
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "amlogic,sha".
|
||||
- dev_name : Should be "aml_sha"
|
||||
- interrupts: Should contain the IRQ line for the SHA.
|
||||
- resets: Should contain the clock to enable the module
|
||||
- reg: Should contain the base address of regs
|
||||
* For S905X series and beyond
|
||||
* S905X series use gxl
|
||||
* T962X series use txlx
|
||||
* S905X2 series use g12a
|
||||
|
||||
Example:
|
||||
aml_sha{
|
||||
compatible = "amlogic,sha";
|
||||
dev_name = "aml_sha";
|
||||
interrupts = <0 36 1>;
|
||||
resets = <&clock GCLK_IDX_BLK_MOV>;
|
||||
reg = <0x0 0xc8832000 0x0 0x2c4
|
||||
0x0 0xda832000 0x0 0xe4>;
|
||||
};
|
||||
|
||||
* New DMA for GXL and beyond
|
||||
* Dma engine for crypto operations
|
||||
Required properties:
|
||||
- compatible : Should be "amlogic,aml_gxl_dma" or "amlogic,aml_txlx_dma".
|
||||
- compatible : Should be "amlogic,aml_gxl_dma" or "amlogic,aml_txlx_dma"
|
||||
- reg: Should contain the base address of regs
|
||||
- interrupts: Should contain the IRQ line for DMA.
|
||||
|
||||
@@ -76,8 +65,9 @@ aml_dma {
|
||||
* Advanced Encryption Standard (AES)
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "amlogic,aes".
|
||||
- dev_name : Should be "aml_aes"
|
||||
- compatible : Should be "amlogic,aes_dma" for aes-128/192/256
|
||||
or "amlogic,aes_g12a_dma" for aes-128/256
|
||||
- dev_name : Should be "aml_aes_dma"
|
||||
|
||||
Example:
|
||||
aml_aes{
|
||||
@@ -89,8 +79,9 @@ aml_aes{
|
||||
* Triple Data Encryption Standard (Triple DES)
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "amlogic,des,tdes".
|
||||
- dev_name : Should be "aml_aes"
|
||||
- compatible : Should be "amlogic,des_dma,tdes_dma" for gxl
|
||||
or "amlogic,tdes_dma" for other series.
|
||||
- dev_name : Should be "aml_tdes_dma"
|
||||
|
||||
Example:
|
||||
aml_tdes{
|
||||
@@ -100,8 +91,8 @@ aml_tdes{
|
||||
* Secure Hash Algorithm (SHA1/SHA224/SHA256/HMAC)
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "amlogic,sha".
|
||||
- dev_name : Should be "aml_sha"
|
||||
- compatible : Should be "amlogic,sha_dma".
|
||||
- dev_name : Should be "aml_sha_dma"
|
||||
|
||||
Example:
|
||||
aml_sha{
|
||||
|
||||
@@ -1813,6 +1813,12 @@
|
||||
dev_name = "aml_sha_dma";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
aml_tdes {
|
||||
compatible = "amlogic,tdes_dma";
|
||||
dev_name = "aml_tdes_dma";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
rng {
|
||||
|
||||
@@ -864,6 +864,29 @@
|
||||
};
|
||||
};/* end of audiobus*/
|
||||
|
||||
aml_dma {
|
||||
compatible = "amlogic,aml_txlx_dma";
|
||||
reg = <0xff63e000 0x48>;
|
||||
interrupts = <0 180 1>;
|
||||
|
||||
aml_aes {
|
||||
compatible = "amlogic,aes_g12a_dma";
|
||||
dev_name = "aml_aes_dma";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
aml_sha {
|
||||
compatible = "amlogic,sha_dma";
|
||||
dev_name = "aml_sha_dma";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
aml_tdes {
|
||||
compatible = "amlogic,tdes_dma";
|
||||
dev_name = "aml_tdes_dma";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
}; /* end of soc*/
|
||||
|
||||
remote:rc@0xff808040 {
|
||||
|
||||
@@ -1813,6 +1813,12 @@
|
||||
dev_name = "aml_sha_dma";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
aml_tdes {
|
||||
compatible = "amlogic,tdes_dma";
|
||||
dev_name = "aml_tdes_dma";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
rng {
|
||||
|
||||
@@ -864,6 +864,29 @@
|
||||
};
|
||||
};/* end of audiobus*/
|
||||
|
||||
aml_dma {
|
||||
compatible = "amlogic,aml_txlx_dma";
|
||||
reg = <0x0 0xff63e000 0x0 0x48>;
|
||||
interrupts = <0 180 1>;
|
||||
|
||||
aml_aes {
|
||||
compatible = "amlogic,aes_g12a_dma";
|
||||
dev_name = "aml_aes_dma";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
aml_sha {
|
||||
compatible = "amlogic,sha_dma";
|
||||
dev_name = "aml_sha_dma";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
aml_tdes {
|
||||
compatible = "amlogic,tdes_dma";
|
||||
dev_name = "aml_tdes_dma";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
}; /* end of soc*/
|
||||
|
||||
remote:rc@0xff808040 {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/hw_random.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
@@ -39,7 +40,6 @@
|
||||
#include <crypto/aes.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/amlogic/iomap.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <crypto/skcipher.h>
|
||||
#include "aml-crypto-dma.h"
|
||||
@@ -135,14 +135,18 @@ static struct aml_aes_drv aml_aes = {
|
||||
static int set_aes_key_iv(struct aml_aes_dev *dd, u32 *key,
|
||||
uint32_t keylen, u32 *iv, uint8_t swap)
|
||||
{
|
||||
struct device *dev = dd->dev;
|
||||
struct dma_dsc *dsc = dd->descriptor;
|
||||
uint32_t key_iv[12];
|
||||
uint32_t *key_iv = kzalloc(DMA_KEY_IV_BUF_SIZE, GFP_ATOMIC);
|
||||
uint32_t *piv = key_iv + 8;
|
||||
int32_t len = keylen;
|
||||
dma_addr_t dma_addr_key = 0;
|
||||
uint32_t i = 0;
|
||||
|
||||
memset(key_iv, 0, sizeof(key_iv));
|
||||
if (!key_iv) {
|
||||
dev_err(dev, "error allocating key_iv buffer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(key_iv, key, keylen);
|
||||
if (iv) {
|
||||
if (swap) {
|
||||
@@ -153,17 +157,16 @@ static int set_aes_key_iv(struct aml_aes_dev *dd, u32 *key,
|
||||
} else {
|
||||
memcpy(piv, iv, 16);
|
||||
}
|
||||
len = 48; /* full key storage */
|
||||
}
|
||||
|
||||
if (!len)
|
||||
return -EPERM;
|
||||
len = DMA_KEY_IV_BUF_SIZE; /* full key storage */
|
||||
|
||||
dma_addr_key = dma_map_single(dd->dev, key_iv,
|
||||
sizeof(key_iv), DMA_TO_DEVICE);
|
||||
DMA_KEY_IV_BUF_SIZE, DMA_TO_DEVICE);
|
||||
|
||||
if (dma_mapping_error(dd->dev, dma_addr_key)) {
|
||||
dev_err(dd->dev, "error mapping dma_addr_key\n");
|
||||
dev_err(dev, "error mapping dma_addr_key\n");
|
||||
kfree(key_iv);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -189,8 +192,9 @@ static int set_aes_key_iv(struct aml_aes_dev *dd, u32 *key,
|
||||
;
|
||||
aml_write_crypto_reg(dd->status, 0xf);
|
||||
dma_unmap_single(dd->dev, dma_addr_key,
|
||||
sizeof(key_iv), DMA_TO_DEVICE);
|
||||
DMA_KEY_IV_BUF_SIZE, DMA_TO_DEVICE);
|
||||
|
||||
kfree(key_iv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -228,6 +232,7 @@ static size_t aml_aes_sg_copy(struct scatterlist **sg, size_t *offset,
|
||||
static size_t aml_aes_sg_dma(struct aml_aes_dev *dd, struct dma_dsc *dsc,
|
||||
uint32_t *nents, size_t total)
|
||||
{
|
||||
struct device *dev = dd->dev;
|
||||
size_t count = 0;
|
||||
size_t process = 0;
|
||||
size_t count_total = 0;
|
||||
@@ -253,14 +258,14 @@ static size_t aml_aes_sg_dma(struct aml_aes_dev *dd, struct dma_dsc *dsc,
|
||||
if (dd->in_sg != dd->out_sg) {
|
||||
err = dma_map_sg(dd->dev, dd->in_sg, *nents, DMA_TO_DEVICE);
|
||||
if (!err) {
|
||||
dev_err(dd->dev, "dma_map_sg() error\n");
|
||||
dev_err(dev, "dma_map_sg() error\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = dma_map_sg(dd->dev, dd->out_sg, *nents,
|
||||
DMA_FROM_DEVICE);
|
||||
if (!err) {
|
||||
dev_err(dd->dev, "dma_map_sg() error\n");
|
||||
dev_err(dev, "dma_map_sg() error\n");
|
||||
dma_unmap_sg(dd->dev, dd->in_sg, *nents,
|
||||
DMA_TO_DEVICE);
|
||||
return 0;
|
||||
@@ -269,7 +274,7 @@ static size_t aml_aes_sg_dma(struct aml_aes_dev *dd, struct dma_dsc *dsc,
|
||||
err = dma_map_sg(dd->dev, dd->in_sg, *nents,
|
||||
DMA_BIDIRECTIONAL);
|
||||
if (!err) {
|
||||
dev_err(dd->dev, "dma_map_sg() error\n");
|
||||
dev_err(dev, "dma_map_sg() error\n");
|
||||
return 0;
|
||||
}
|
||||
dma_sync_sg_for_device(dd->dev, dd->in_sg,
|
||||
@@ -465,6 +470,7 @@ static int aml_aes_write_ctrl(struct aml_aes_dev *dd)
|
||||
static int aml_aes_handle_queue(struct aml_aes_dev *dd,
|
||||
struct ablkcipher_request *req)
|
||||
{
|
||||
struct device *dev = dd->dev;
|
||||
struct crypto_async_request *async_req, *backlog;
|
||||
struct aml_aes_ctx *ctx;
|
||||
struct aml_aes_reqctx *rctx;
|
||||
@@ -516,7 +522,7 @@ static int aml_aes_handle_queue(struct aml_aes_dev *dd,
|
||||
(dd->flags & AES_FLAGS_CTR))
|
||||
err = aml_aes_crypt_dma_start(dd);
|
||||
else {
|
||||
pr_err("size %zd is not multiple of %d",
|
||||
dev_err(dev, "size %zd is not multiple of %d",
|
||||
dd->total, AML_AES_DMA_THRESHOLD);
|
||||
err = -EINVAL;
|
||||
}
|
||||
@@ -532,6 +538,7 @@ static int aml_aes_handle_queue(struct aml_aes_dev *dd,
|
||||
|
||||
static int aml_aes_crypt_dma_stop(struct aml_aes_dev *dd)
|
||||
{
|
||||
struct device *dev = dd->dev;
|
||||
int err = -EINVAL;
|
||||
size_t count;
|
||||
|
||||
@@ -567,7 +574,8 @@ static int aml_aes_crypt_dma_stop(struct aml_aes_dev *dd)
|
||||
dd->dma_size, 1);
|
||||
if (count != dd->dma_size) {
|
||||
err = -EINVAL;
|
||||
pr_err("not all data converted: %zu\n", count);
|
||||
dev_err(dev, "not all data converted: %zu\n",
|
||||
count);
|
||||
}
|
||||
/* install IV for CBC */
|
||||
if (dd->flags & AES_FLAGS_CBC) {
|
||||
@@ -584,6 +592,7 @@ static int aml_aes_crypt_dma_stop(struct aml_aes_dev *dd)
|
||||
|
||||
static int aml_aes_buff_init(struct aml_aes_dev *dd)
|
||||
{
|
||||
struct device *dev = dd->dev;
|
||||
int err = -ENOMEM;
|
||||
|
||||
dd->buf_in = (void *)__get_free_pages(GFP_KERNEL, 0);
|
||||
@@ -593,7 +602,7 @@ static int aml_aes_buff_init(struct aml_aes_dev *dd)
|
||||
dd->buflen &= ~(AES_BLOCK_SIZE - 1);
|
||||
|
||||
if (!dd->buf_in || !dd->buf_out || !dd->descriptor) {
|
||||
dev_err(dd->dev, "unable to alloc pages.\n");
|
||||
dev_err(dev, "unable to alloc pages.\n");
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
@@ -601,7 +610,7 @@ static int aml_aes_buff_init(struct aml_aes_dev *dd)
|
||||
dd->dma_addr_in = dma_map_single(dd->dev, dd->buf_in,
|
||||
dd->buflen, DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(dd->dev, dd->dma_addr_in)) {
|
||||
dev_err(dd->dev, "dma %zd bytes error\n", dd->buflen);
|
||||
dev_err(dev, "dma %zd bytes error\n", dd->buflen);
|
||||
err = -EINVAL;
|
||||
goto err_map_in;
|
||||
}
|
||||
@@ -609,7 +618,7 @@ static int aml_aes_buff_init(struct aml_aes_dev *dd)
|
||||
dd->dma_addr_out = dma_map_single(dd->dev, dd->buf_out,
|
||||
dd->buflen, DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(dd->dev, dd->dma_addr_out)) {
|
||||
dev_err(dd->dev, "dma %zd bytes error\n", dd->buflen);
|
||||
dev_err(dev, "dma %zd bytes error\n", dd->buflen);
|
||||
err = -EINVAL;
|
||||
goto err_map_out;
|
||||
}
|
||||
@@ -618,7 +627,7 @@ static int aml_aes_buff_init(struct aml_aes_dev *dd)
|
||||
PAGE_SIZE, DMA_TO_DEVICE);
|
||||
|
||||
if (dma_mapping_error(dd->dev, dd->dma_descript_tab)) {
|
||||
dev_err(dd->dev, "dma descriptor error\n");
|
||||
dev_err(dev, "dma descriptor error\n");
|
||||
err = -EINVAL;
|
||||
goto err_map_descriptor;
|
||||
}
|
||||
@@ -638,7 +647,7 @@ err_map_in:
|
||||
free_page((uintptr_t)dd->descriptor);
|
||||
err_alloc:
|
||||
if (err)
|
||||
pr_err("error: %d\n", err);
|
||||
dev_err(dev, "error: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -911,7 +920,6 @@ static struct crypto_alg aes_lite_algs[] = {
|
||||
.cra_u.ablkcipher = {
|
||||
.min_keysize = AES_MIN_KEY_SIZE,
|
||||
.max_keysize = AES_MAX_KEY_SIZE,
|
||||
.ivsize = AES_BLOCK_SIZE,
|
||||
.setkey = aml_aes_lite_setkey,
|
||||
.encrypt = aml_aes_ecb_encrypt,
|
||||
.decrypt = aml_aes_ecb_decrypt,
|
||||
@@ -997,6 +1005,7 @@ static void aml_aes_queue_task(unsigned long data)
|
||||
static void aml_aes_done_task(unsigned long data)
|
||||
{
|
||||
struct aml_aes_dev *dd = (struct aml_aes_dev *) data;
|
||||
struct device *dev = dd->dev;
|
||||
int err;
|
||||
|
||||
err = aml_aes_crypt_dma_stop(dd);
|
||||
@@ -1014,7 +1023,7 @@ static void aml_aes_done_task(unsigned long data)
|
||||
dd->in_sg = sg_next(dd->in_sg);
|
||||
dd->out_sg = sg_next(dd->out_sg);
|
||||
if (!dd->in_sg || !dd->out_sg) {
|
||||
pr_err("aml-aes: sg invalid\n");
|
||||
dev_err(dev, "aml-aes: sg invalid\n");
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
@@ -1034,11 +1043,12 @@ static void aml_aes_done_task(unsigned long data)
|
||||
static irqreturn_t aml_aes_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct aml_aes_dev *aes_dd = dev_id;
|
||||
struct device *dev = aes_dd->dev;
|
||||
uint8_t status = aml_read_crypto_reg(aes_dd->status);
|
||||
|
||||
if (status) {
|
||||
if (status == 0x1)
|
||||
pr_err("irq overwrite\n");
|
||||
dev_err(dev, "irq overwrite\n");
|
||||
if (aes_dd->dma->dma_busy == DMA_FLAG_MAY_OCCUPY)
|
||||
return IRQ_HANDLED;
|
||||
if ((aes_dd->flags & AES_FLAGS_DMA) &&
|
||||
@@ -1079,7 +1089,7 @@ static int aml_aes_register_algs(struct aml_aes_dev *dd,
|
||||
|
||||
err_aes_algs:
|
||||
for (j = 0; j < i; j++)
|
||||
crypto_unregister_alg(&aes_algs[j]);
|
||||
crypto_unregister_alg(&(aes_info->algs[j]));
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -1092,7 +1102,7 @@ static int aml_aes_probe(struct platform_device *pdev)
|
||||
int err = -EPERM;
|
||||
const struct aml_aes_info *aes_info = NULL;
|
||||
|
||||
aes_dd = kzalloc(sizeof(struct aml_aes_dev), GFP_KERNEL);
|
||||
aes_dd = devm_kzalloc(dev, sizeof(struct aml_aes_dev), GFP_KERNEL);
|
||||
if (aes_dd == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto aes_dd_err;
|
||||
@@ -1100,9 +1110,8 @@ static int aml_aes_probe(struct platform_device *pdev)
|
||||
|
||||
match = of_match_device(aml_aes_dt_match, &pdev->dev);
|
||||
if (!match) {
|
||||
pr_err("%s: cannot find match dt\n", __func__);
|
||||
dev_err(dev, "%s: cannot find match dt\n", __func__);
|
||||
err = -EINVAL;
|
||||
kfree(aes_dd);
|
||||
goto aes_dd_err;
|
||||
}
|
||||
aes_info = match->data;
|
||||
@@ -1121,8 +1130,8 @@ static int aml_aes_probe(struct platform_device *pdev)
|
||||
(unsigned long)aes_dd);
|
||||
|
||||
crypto_init_queue(&aes_dd->queue, AML_AES_QUEUE_LENGTH);
|
||||
err = request_irq(aes_dd->irq, aml_aes_irq, IRQF_SHARED, "aml-aes",
|
||||
aes_dd);
|
||||
err = devm_request_irq(dev, aes_dd->irq, aml_aes_irq, IRQF_SHARED,
|
||||
"aml-aes", aes_dd);
|
||||
if (err) {
|
||||
dev_err(dev, "unable to request aes irq.\n");
|
||||
goto aes_irq_err;
|
||||
@@ -1154,13 +1163,9 @@ err_algs:
|
||||
spin_unlock(&aml_aes.lock);
|
||||
aml_aes_buff_cleanup(aes_dd);
|
||||
err_aes_buff:
|
||||
free_irq(aes_dd->irq, aes_dd);
|
||||
aes_irq_err:
|
||||
|
||||
tasklet_kill(&aes_dd->done_task);
|
||||
tasklet_kill(&aes_dd->queue_task);
|
||||
kfree(aes_dd);
|
||||
aes_dd = NULL;
|
||||
aes_dd_err:
|
||||
dev_err(dev, "initialization failed.\n");
|
||||
|
||||
@@ -1169,6 +1174,7 @@ aes_dd_err:
|
||||
|
||||
static int aml_aes_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
static struct aml_aes_dev *aes_dd;
|
||||
const struct of_device_id *match;
|
||||
const struct aml_aes_info *aes_info = NULL;
|
||||
@@ -1178,7 +1184,7 @@ static int aml_aes_remove(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
match = of_match_device(aml_aes_dt_match, &pdev->dev);
|
||||
if (!match) {
|
||||
pr_err("%s: cannot find match dt\n", __func__);
|
||||
dev_err(dev, "%s: cannot find match dt\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
aes_info = match->data;
|
||||
@@ -1191,12 +1197,6 @@ static int aml_aes_remove(struct platform_device *pdev)
|
||||
tasklet_kill(&aes_dd->done_task);
|
||||
tasklet_kill(&aes_dd->queue_task);
|
||||
|
||||
if (aes_dd->irq > 0)
|
||||
free_irq(aes_dd->irq, aes_dd);
|
||||
|
||||
kfree(aes_dd);
|
||||
aes_dd = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,8 +37,6 @@
|
||||
#include <crypto/scatterwalk.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/amlogic/iomap.h>
|
||||
#include <linux/amlogic/cpu_version.h>
|
||||
#include "aml-crypto-dma.h"
|
||||
|
||||
u32 swap_ulong32(u32 val)
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
#define _AML_CRYPTO_H_
|
||||
#include <linux/io.h>
|
||||
|
||||
/* #define CRYPTO_DEBUG */
|
||||
|
||||
/* Reserved 4096 bytes and table is 12 bytes each */
|
||||
#define MAX_NUM_TABLES 341
|
||||
|
||||
@@ -117,6 +115,7 @@ struct dma_dsc {
|
||||
#define DMA_FLAG_AES_IN_USE BIT(2)
|
||||
#define DMA_FLAG_SHA_IN_USE BIT(3)
|
||||
|
||||
#define DMA_KEY_IV_BUF_SIZE (48)
|
||||
struct aml_dma_dev {
|
||||
spinlock_t dma_lock;
|
||||
uint32_t thread;
|
||||
@@ -136,17 +135,13 @@ u32 get_dma_sts0_offset(void);
|
||||
|
||||
extern void __iomem *cryptoreg;
|
||||
|
||||
extern int debug;
|
||||
#ifndef CRYPTO_DEBUG
|
||||
#define dbgp(level, fmt, arg...)
|
||||
#else
|
||||
extern u32 debug;
|
||||
#define dbgp(level, fmt, arg...) \
|
||||
do { \
|
||||
if (likely(debug >= level)) \
|
||||
if (likely(debug > level)) \
|
||||
pr_debug("%s: " fmt, __func__, ## arg);\
|
||||
else \
|
||||
pr_info("%s: " fmt, __func__, ## arg); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/clk.h>
|
||||
@@ -42,10 +43,8 @@
|
||||
#include <linux/of_platform.h>
|
||||
#include "aml-crypto-dma.h"
|
||||
|
||||
int debug = 2;
|
||||
#ifdef CRYPTO_DEBUG
|
||||
module_param(debug, int, 0644);
|
||||
#endif
|
||||
static struct dentry *aml_dma_debug_dent;
|
||||
u32 debug = 3;
|
||||
|
||||
void __iomem *cryptoreg;
|
||||
|
||||
@@ -78,6 +77,27 @@ MODULE_DEVICE_TABLE(of, aml_dma_dt_match);
|
||||
#define aml_aes_dt_match NULL
|
||||
#endif
|
||||
|
||||
static int aml_dma_init_dbgfs(struct device *dev)
|
||||
{
|
||||
struct dentry *file = NULL;
|
||||
|
||||
if (!aml_dma_debug_dent) {
|
||||
aml_dma_debug_dent = debugfs_create_dir("aml_dma", NULL);
|
||||
if (!aml_dma_debug_dent) {
|
||||
dev_err(dev, "can not create debugfs directory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
file = debugfs_create_u32("debug", 0644,
|
||||
aml_dma_debug_dent, &debug);
|
||||
if (!file) {
|
||||
dev_err(dev, "can not create entry in debugfs directory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int aml_dma_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct aml_dma_dev *dma_dd;
|
||||
@@ -89,7 +109,7 @@ static int aml_dma_probe(struct platform_device *pdev)
|
||||
int err = -EPERM;
|
||||
const struct meson_dma_data *priv_data;
|
||||
|
||||
dma_dd = kzalloc(sizeof(struct aml_dma_dev), GFP_KERNEL);
|
||||
dma_dd = devm_kzalloc(dev, sizeof(struct aml_dma_dev), GFP_KERNEL);
|
||||
if (dma_dd == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto dma_err;
|
||||
@@ -106,8 +126,7 @@ static int aml_dma_probe(struct platform_device *pdev)
|
||||
dev_err(dev, "error to get normal IORESOURCE_MEM.\n");
|
||||
goto dma_err;
|
||||
} else {
|
||||
cryptoreg = ioremap(res_base->start,
|
||||
resource_size(res_base));
|
||||
cryptoreg = devm_ioremap_resource(dev, res_base);
|
||||
if (!cryptoreg) {
|
||||
dev_err(dev, "failed to remap crypto reg\n");
|
||||
goto dma_err;
|
||||
@@ -118,17 +137,21 @@ static int aml_dma_probe(struct platform_device *pdev)
|
||||
dma_dd->irq = res_irq->start;
|
||||
dma_dd->dma_busy = 0;
|
||||
platform_set_drvdata(pdev, dma_dd);
|
||||
|
||||
err = aml_dma_init_dbgfs(dev);
|
||||
if (err)
|
||||
goto dma_err;
|
||||
|
||||
dev_info(dev, "Aml dma\n");
|
||||
|
||||
err = of_platform_populate(np, NULL, NULL, dev);
|
||||
|
||||
if (err != 0)
|
||||
iounmap(cryptoreg);
|
||||
goto dma_err;
|
||||
|
||||
return err;
|
||||
|
||||
dma_err:
|
||||
kfree(dma_dd);
|
||||
debugfs_remove_recursive(aml_dma_debug_dent);
|
||||
dev_err(dev, "initialization failed.\n");
|
||||
|
||||
return err;
|
||||
@@ -142,8 +165,7 @@ static int aml_dma_remove(struct platform_device *pdev)
|
||||
if (!dma_dd)
|
||||
return -ENODEV;
|
||||
|
||||
iounmap(cryptoreg);
|
||||
kfree(dma_dd);
|
||||
debugfs_remove_recursive(aml_dma_debug_dent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <crypto/sha.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/amlogic/iomap.h>
|
||||
#include "aml-crypto-dma.h"
|
||||
|
||||
/* SHA flags */
|
||||
@@ -459,9 +458,7 @@ static int aml_sha_update_dma_stop(struct aml_sha_dev *dd)
|
||||
static int aml_sha_update_req(struct aml_sha_dev *dd, struct ahash_request *req)
|
||||
{
|
||||
int err;
|
||||
#ifdef CRYPTO_DEBUG
|
||||
struct aml_sha_reqctx *ctx = ahash_request_ctx(req);
|
||||
#endif
|
||||
|
||||
dbgp(1, "update_req: ctx: %p, total: %u, digcnt: 0x%llx 0x%llx\n",
|
||||
ctx, ctx->total, ctx->digcnt[1], ctx->digcnt[0]);
|
||||
@@ -474,9 +471,7 @@ static int aml_sha_update_req(struct aml_sha_dev *dd, struct ahash_request *req)
|
||||
static int aml_sha_final_req(struct aml_sha_dev *dd, struct ahash_request *req)
|
||||
{
|
||||
int err = 0;
|
||||
#ifdef CRYPTO_DEBUG
|
||||
struct aml_sha_reqctx *ctx = ahash_request_ctx(req);
|
||||
#endif
|
||||
|
||||
err = aml_sha_update_dma_slow(dd, req);
|
||||
|
||||
@@ -1092,7 +1087,7 @@ static struct ahash_alg sha_algs[] = {
|
||||
.base = {
|
||||
.cra_name = "sha1",
|
||||
.cra_driver_name = "aml-sha1",
|
||||
.cra_priority = 200,
|
||||
.cra_priority = 150,
|
||||
.cra_flags = CRYPTO_ALG_ASYNC,
|
||||
.cra_blocksize = SHA1_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct aml_sha_ctx),
|
||||
@@ -1118,7 +1113,7 @@ static struct ahash_alg sha_algs[] = {
|
||||
.base = {
|
||||
.cra_name = "sha256",
|
||||
.cra_driver_name = "aml-sha256",
|
||||
.cra_priority = 200,
|
||||
.cra_priority = 150,
|
||||
.cra_flags = CRYPTO_ALG_ASYNC,
|
||||
.cra_blocksize = SHA256_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct aml_sha_ctx),
|
||||
@@ -1144,7 +1139,7 @@ static struct ahash_alg sha_algs[] = {
|
||||
.base = {
|
||||
.cra_name = "sha224",
|
||||
.cra_driver_name = "aml-sha224",
|
||||
.cra_priority = 200,
|
||||
.cra_priority = 150,
|
||||
.cra_flags = CRYPTO_ALG_ASYNC,
|
||||
.cra_blocksize = SHA224_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct aml_sha_ctx),
|
||||
@@ -1171,7 +1166,7 @@ static struct ahash_alg sha_algs[] = {
|
||||
.base = {
|
||||
.cra_name = "hmac(sha1)",
|
||||
.cra_driver_name = "aml-hmac-sha1",
|
||||
.cra_priority = 200,
|
||||
.cra_priority = 150,
|
||||
.cra_flags = CRYPTO_ALG_ASYNC |
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = SHA1_BLOCK_SIZE,
|
||||
@@ -1199,7 +1194,7 @@ static struct ahash_alg sha_algs[] = {
|
||||
.base = {
|
||||
.cra_name = "hmac(sha224)",
|
||||
.cra_driver_name = "aml-hmac-sha224",
|
||||
.cra_priority = 200,
|
||||
.cra_priority = 150,
|
||||
.cra_flags = CRYPTO_ALG_ASYNC |
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = SHA224_BLOCK_SIZE,
|
||||
@@ -1227,7 +1222,7 @@ static struct ahash_alg sha_algs[] = {
|
||||
.base = {
|
||||
.cra_name = "hmac(sha256)",
|
||||
.cra_driver_name = "aml-hmac-sha256",
|
||||
.cra_priority = 200,
|
||||
.cra_priority = 150,
|
||||
.cra_flags = CRYPTO_ALG_ASYNC |
|
||||
CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = SHA256_BLOCK_SIZE,
|
||||
@@ -1285,7 +1280,7 @@ static irqreturn_t aml_sha_irq(int irq, void *dev_id)
|
||||
|
||||
if (status) {
|
||||
if (status == 0x1)
|
||||
pr_err("irq overwrite\n");
|
||||
dev_err(sha_dd->dev, "irq overwrite\n");
|
||||
if (sha_dd->dma->dma_busy == DMA_FLAG_MAY_OCCUPY)
|
||||
return IRQ_HANDLED;
|
||||
if (sha_dd->flags & SHA_FLAGS_DMA_ACTIVE &&
|
||||
@@ -1335,7 +1330,7 @@ static int aml_sha_probe(struct platform_device *pdev)
|
||||
struct device *dev = &pdev->dev;
|
||||
int err = -EPERM;
|
||||
|
||||
sha_dd = kzalloc(sizeof(struct aml_sha_dev), GFP_KERNEL);
|
||||
sha_dd = devm_kzalloc(dev, sizeof(struct aml_sha_dev), GFP_KERNEL);
|
||||
if (sha_dd == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto sha_dd_err;
|
||||
@@ -1355,8 +1350,8 @@ static int aml_sha_probe(struct platform_device *pdev)
|
||||
(unsigned long)sha_dd);
|
||||
|
||||
crypto_init_queue(&sha_dd->queue, AML_SHA_QUEUE_LENGTH);
|
||||
err = request_irq(sha_dd->irq, aml_sha_irq, IRQF_SHARED, "aml-sha",
|
||||
sha_dd);
|
||||
err = devm_request_irq(dev, sha_dd->irq, aml_sha_irq, IRQF_SHARED,
|
||||
"aml-sha", sha_dd);
|
||||
if (err) {
|
||||
dev_err(dev, "unable to request sha irq.\n");
|
||||
goto res_err;
|
||||
@@ -1364,7 +1359,6 @@ static int aml_sha_probe(struct platform_device *pdev)
|
||||
|
||||
aml_sha_hw_init(sha_dd);
|
||||
|
||||
|
||||
spin_lock(&aml_sha.lock);
|
||||
list_add_tail(&sha_dd->list, &aml_sha.dev_list);
|
||||
spin_unlock(&aml_sha.lock);
|
||||
@@ -1381,12 +1375,8 @@ err_algs:
|
||||
spin_lock(&aml_sha.lock);
|
||||
list_del(&sha_dd->list);
|
||||
spin_unlock(&aml_sha.lock);
|
||||
|
||||
free_irq(sha_dd->irq, sha_dd);
|
||||
res_err:
|
||||
tasklet_kill(&sha_dd->done_task);
|
||||
kfree(sha_dd);
|
||||
sha_dd = NULL;
|
||||
sha_dd_err:
|
||||
dev_err(dev, "initialization failed.\n");
|
||||
|
||||
@@ -1408,12 +1398,6 @@ static int aml_sha_remove(struct platform_device *pdev)
|
||||
|
||||
tasklet_kill(&sha_dd->done_task);
|
||||
|
||||
if (sha_dd->irq >= 0)
|
||||
free_irq(sha_dd->irq, sha_dd);
|
||||
|
||||
kfree(sha_dd);
|
||||
sha_dd = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/hw_random.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/device.h>
|
||||
@@ -39,7 +40,8 @@
|
||||
#include <crypto/des.h>
|
||||
#include <crypto/hash.h>
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/amlogic/iomap.h>
|
||||
//#include <linux/amlogic/iomap.h>
|
||||
#include <crypto/skcipher.h>
|
||||
#include "aml-crypto-dma.h"
|
||||
|
||||
/* TDES flags */
|
||||
@@ -54,6 +56,7 @@
|
||||
|
||||
#define AML_TDES_QUEUE_LENGTH 50
|
||||
|
||||
#define SUPPORT_FAST_DMA 0
|
||||
struct aml_tdes_dev;
|
||||
|
||||
struct aml_tdes_ctx {
|
||||
@@ -63,6 +66,8 @@ struct aml_tdes_ctx {
|
||||
u32 key[3*DES_KEY_SIZE / sizeof(u32)];
|
||||
|
||||
u16 block_size;
|
||||
struct crypto_skcipher *fallback;
|
||||
u16 same_key;
|
||||
};
|
||||
|
||||
struct aml_tdes_reqctx {
|
||||
@@ -115,6 +120,11 @@ struct aml_tdes_drv {
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
struct aml_tdes_info {
|
||||
struct crypto_alg *algs;
|
||||
uint32_t num_algs;
|
||||
};
|
||||
|
||||
static struct aml_tdes_drv aml_tdes = {
|
||||
.dev_list = LIST_HEAD_INIT(aml_tdes.dev_list),
|
||||
.lock = __SPIN_LOCK_UNLOCKED(aml_tdes.lock),
|
||||
@@ -124,42 +134,43 @@ static int set_tdes_key_iv(struct aml_tdes_dev *dd,
|
||||
u32 *key, u32 keylen, u32 *iv)
|
||||
{
|
||||
struct dma_dsc *dsc = dd->descriptor;
|
||||
uint32_t key_iv[12];
|
||||
struct device *dev = dd->dev;
|
||||
uint32_t *key_iv = kzalloc(DMA_KEY_IV_BUF_SIZE, GFP_ATOMIC);
|
||||
uint32_t *piv = key_iv + 8;
|
||||
uint32_t len = keylen;
|
||||
uint32_t processed = 0;
|
||||
dma_addr_t dma_addr_key;
|
||||
uint32_t i = 0;
|
||||
|
||||
memset(key_iv, 0, sizeof(key_iv));
|
||||
if (!key_iv) {
|
||||
dev_err(dev, "error allocating key_iv buffer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
memcpy(key_iv, key, keylen);
|
||||
if (iv) {
|
||||
memcpy(piv, iv, 8);
|
||||
len = 48; /* full key storage */
|
||||
}
|
||||
|
||||
if (!len)
|
||||
return -EPERM;
|
||||
len = DMA_KEY_IV_BUF_SIZE; /* full key storage */
|
||||
|
||||
dma_addr_key = dma_map_single(dd->dev, key_iv,
|
||||
sizeof(key_iv), DMA_TO_DEVICE);
|
||||
DMA_KEY_IV_BUF_SIZE, DMA_TO_DEVICE);
|
||||
|
||||
if (dma_mapping_error(dd->dev, dma_addr_key)) {
|
||||
dev_err(dd->dev, "error mapping dma_addr_key\n");
|
||||
dev_err(dev, "error mapping dma_addr_key\n");
|
||||
kfree(key_iv);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
processed = len > 16 ? 16 : len;
|
||||
dsc[i].src_addr = (uint32_t)dma_addr_key + i * 16;
|
||||
dsc[i].tgt_addr = i * 16;
|
||||
dsc[i].dsc_cfg.d32 = 0;
|
||||
dsc[i].dsc_cfg.b.length = processed;
|
||||
dsc[i].dsc_cfg.b.length = len > 16 ? 16 : len;
|
||||
dsc[i].dsc_cfg.b.mode = MODE_KEY;
|
||||
dsc[i].dsc_cfg.b.eoc = 0;
|
||||
dsc[i].dsc_cfg.b.owner = 1;
|
||||
i++;
|
||||
len -= processed;
|
||||
len -= 16;
|
||||
}
|
||||
dsc[i - 1].dsc_cfg.b.eoc = 1;
|
||||
|
||||
@@ -172,8 +183,9 @@ static int set_tdes_key_iv(struct aml_tdes_dev *dd,
|
||||
;
|
||||
aml_write_crypto_reg(dd->status, 0xf);
|
||||
dma_unmap_single(dd->dev, dma_addr_key,
|
||||
sizeof(key_iv), DMA_TO_DEVICE);
|
||||
DMA_KEY_IV_BUF_SIZE, DMA_TO_DEVICE);
|
||||
|
||||
kfree(key_iv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -209,11 +221,15 @@ static size_t aml_tdes_sg_copy(struct scatterlist **sg, size_t *offset,
|
||||
return off;
|
||||
}
|
||||
|
||||
#if SUPPORT_FAST_DMA
|
||||
static size_t aml_tdes_sg_dma(struct aml_tdes_dev *dd, struct dma_dsc *dsc,
|
||||
uint32_t *nents, size_t total)
|
||||
{
|
||||
struct device *dev = dd->dev;
|
||||
size_t count = 0;
|
||||
size_t process = 0;
|
||||
size_t count_total = 0;
|
||||
size_t count_sg = 0;
|
||||
uint32_t i = 0;
|
||||
int err = 0;
|
||||
struct scatterlist *in_sg = dd->in_sg;
|
||||
@@ -221,44 +237,62 @@ static size_t aml_tdes_sg_dma(struct aml_tdes_dev *dd, struct dma_dsc *dsc,
|
||||
dma_addr_t addr_in, addr_out;
|
||||
|
||||
while (total && in_sg && out_sg && (in_sg->length == out_sg->length)
|
||||
&& IS_ALIGNED(in_sg->length, DES_BLOCK_SIZE)
|
||||
&& *nents < MAX_NUM_TABLES) {
|
||||
process = min_t(unsigned int, total, in_sg->length);
|
||||
count += process;
|
||||
*nents += 1;
|
||||
if (process != in_sg->length)
|
||||
dd->out_offset = dd->in_offset = in_sg->length;
|
||||
total -= process;
|
||||
in_sg = sg_next(in_sg);
|
||||
out_sg = sg_next(out_sg);
|
||||
}
|
||||
err = dma_map_sg(dd->dev, dd->in_sg, *nents, DMA_TO_DEVICE);
|
||||
if (!err) {
|
||||
dev_err(dd->dev, "dma_map_sg() error\n");
|
||||
return 0;
|
||||
}
|
||||
if (dd->in_sg != dd->out_sg) {
|
||||
err = dma_map_sg(dd->dev, dd->in_sg, *nents, DMA_TO_DEVICE);
|
||||
if (!err) {
|
||||
dev_err(dev, "dma_map_sg() error\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = dma_map_sg(dd->dev, dd->out_sg, *nents,
|
||||
DMA_FROM_DEVICE);
|
||||
if (!err) {
|
||||
dev_err(dd->dev, "dma_map_sg() error\n");
|
||||
dma_unmap_sg(dd->dev, dd->in_sg, *nents,
|
||||
DMA_TO_DEVICE);
|
||||
return 0;
|
||||
err = dma_map_sg(dd->dev, dd->out_sg, *nents,
|
||||
DMA_FROM_DEVICE);
|
||||
if (!err) {
|
||||
dev_err(dev, "dma_map_sg() error\n");
|
||||
dma_unmap_sg(dd->dev, dd->in_sg, *nents,
|
||||
DMA_TO_DEVICE);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
err = dma_map_sg(dd->dev, dd->in_sg, *nents,
|
||||
DMA_BIDIRECTIONAL);
|
||||
if (!err) {
|
||||
dev_err(dev, "dma_map_sg() error\n");
|
||||
return 0;
|
||||
}
|
||||
dma_sync_sg_for_device(dd->dev, dd->in_sg,
|
||||
*nents, DMA_TO_DEVICE);
|
||||
}
|
||||
|
||||
in_sg = dd->in_sg;
|
||||
out_sg = dd->out_sg;
|
||||
count_total = count;
|
||||
for (i = 0; i < *nents; i++) {
|
||||
count_sg = count_total > sg_dma_len(in_sg) ?
|
||||
sg_dma_len(in_sg) : count_total;
|
||||
addr_in = sg_dma_address(in_sg);
|
||||
addr_out = sg_dma_address(out_sg);
|
||||
dsc[i].src_addr = (uintptr_t)addr_in;
|
||||
dsc[i].tgt_addr = (uintptr_t)addr_out;
|
||||
dsc[i].dsc_cfg.d32 = 0;
|
||||
dsc[i].dsc_cfg.b.length = sg_dma_len(in_sg);
|
||||
dsc[i].dsc_cfg.b.length = count_sg;
|
||||
in_sg = sg_next(in_sg);
|
||||
out_sg = sg_next(out_sg);
|
||||
count_total -= count_sg;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
static struct aml_tdes_dev *aml_tdes_find_dev(struct aml_tdes_ctx *ctx)
|
||||
{
|
||||
struct aml_tdes_dev *tdes_dd = NULL;
|
||||
@@ -362,11 +396,14 @@ static int aml_tdes_crypt_dma_start(struct aml_tdes_dev *dd)
|
||||
dd->fast_nents = 0;
|
||||
}
|
||||
|
||||
#if SUPPORT_FAST_DMA
|
||||
if (fast) {
|
||||
count = aml_tdes_sg_dma(dd, dsc, &dd->fast_nents, dd->total);
|
||||
dd->flags |= TDES_FLAGS_FAST;
|
||||
nents = dd->fast_nents;
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* slow dma */
|
||||
/* use cache buffers */
|
||||
count = aml_tdes_sg_copy(&dd->in_sg, &dd->in_offset,
|
||||
@@ -472,6 +509,7 @@ static int aml_tdes_handle_queue(struct aml_tdes_dev *dd,
|
||||
|
||||
static int aml_tdes_crypt_dma_stop(struct aml_tdes_dev *dd)
|
||||
{
|
||||
struct device *dev = dd->dev;
|
||||
int err = -EINVAL;
|
||||
size_t count;
|
||||
|
||||
@@ -480,10 +518,17 @@ static int aml_tdes_crypt_dma_stop(struct aml_tdes_dev *dd)
|
||||
dma_sync_single_for_cpu(dd->dev, dd->dma_descript_tab,
|
||||
PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
if (dd->flags & TDES_FLAGS_FAST) {
|
||||
dma_unmap_sg(dd->dev, dd->out_sg,
|
||||
if (dd->in_sg != dd->out_sg) {
|
||||
dma_unmap_sg(dd->dev, dd->out_sg,
|
||||
dd->fast_nents, DMA_FROM_DEVICE);
|
||||
dma_unmap_sg(dd->dev, dd->in_sg,
|
||||
dma_unmap_sg(dd->dev, dd->in_sg,
|
||||
dd->fast_nents, DMA_TO_DEVICE);
|
||||
} else {
|
||||
dma_sync_sg_for_cpu(dd->dev, dd->in_sg,
|
||||
dd->fast_nents, DMA_FROM_DEVICE);
|
||||
dma_unmap_sg(dd->dev, dd->in_sg,
|
||||
dd->fast_nents, DMA_BIDIRECTIONAL);
|
||||
}
|
||||
} else {
|
||||
dma_sync_single_for_cpu(dd->dev, dd->dma_addr_out,
|
||||
dd->dma_size, DMA_FROM_DEVICE);
|
||||
@@ -494,7 +539,8 @@ static int aml_tdes_crypt_dma_stop(struct aml_tdes_dev *dd)
|
||||
dd->dma_size, 1);
|
||||
if (count != dd->dma_size) {
|
||||
err = -EINVAL;
|
||||
pr_err("not all data converted: %zu\n", count);
|
||||
dev_err(dev, "not all data converted: %zu\n",
|
||||
count);
|
||||
}
|
||||
}
|
||||
dd->flags &= ~TDES_FLAGS_DMA;
|
||||
@@ -506,6 +552,7 @@ static int aml_tdes_crypt_dma_stop(struct aml_tdes_dev *dd)
|
||||
|
||||
static int aml_tdes_buff_init(struct aml_tdes_dev *dd)
|
||||
{
|
||||
struct device *dev = dd->dev;
|
||||
int err = -ENOMEM;
|
||||
|
||||
dd->buf_in = (void *)__get_free_pages(GFP_KERNEL, 0);
|
||||
@@ -515,7 +562,7 @@ static int aml_tdes_buff_init(struct aml_tdes_dev *dd)
|
||||
dd->buflen &= ~(DES_BLOCK_SIZE - 1);
|
||||
|
||||
if (!dd->buf_in || !dd->buf_out || !dd->descriptor) {
|
||||
dev_err(dd->dev, "unable to alloc pages.\n");
|
||||
dev_err(dev, "unable to alloc pages.\n");
|
||||
goto err_alloc;
|
||||
}
|
||||
|
||||
@@ -523,7 +570,7 @@ static int aml_tdes_buff_init(struct aml_tdes_dev *dd)
|
||||
dd->dma_addr_in = dma_map_single(dd->dev, dd->buf_in,
|
||||
dd->buflen, DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(dd->dev, dd->dma_addr_in)) {
|
||||
dev_err(dd->dev, "dma %zd bytes error\n", dd->buflen);
|
||||
dev_err(dev, "dma %zd bytes error\n", dd->buflen);
|
||||
err = -EINVAL;
|
||||
goto err_map_in;
|
||||
}
|
||||
@@ -531,7 +578,7 @@ static int aml_tdes_buff_init(struct aml_tdes_dev *dd)
|
||||
dd->dma_addr_out = dma_map_single(dd->dev, dd->buf_out,
|
||||
dd->buflen, DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(dd->dev, dd->dma_addr_out)) {
|
||||
dev_err(dd->dev, "dma %zd bytes error\n", dd->buflen);
|
||||
dev_err(dev, "dma %zd bytes error\n", dd->buflen);
|
||||
err = -EINVAL;
|
||||
goto err_map_out;
|
||||
}
|
||||
@@ -540,7 +587,7 @@ static int aml_tdes_buff_init(struct aml_tdes_dev *dd)
|
||||
PAGE_SIZE, DMA_TO_DEVICE);
|
||||
|
||||
if (dma_mapping_error(dd->dev, dd->dma_descript_tab)) {
|
||||
dev_err(dd->dev, "dma descriptor error\n");
|
||||
dev_err(dev, "dma descriptor error\n");
|
||||
err = -EINVAL;
|
||||
goto err_map_descriptor;
|
||||
}
|
||||
@@ -561,7 +608,7 @@ err_map_in:
|
||||
free_page((uintptr_t)dd->descriptor);
|
||||
err_alloc:
|
||||
if (err)
|
||||
pr_err("error: %d\n", err);
|
||||
dev_err(dev, "error: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -591,6 +638,31 @@ static int aml_tdes_crypt(struct ablkcipher_request *req, unsigned long mode)
|
||||
}
|
||||
ctx->block_size = DES_BLOCK_SIZE;
|
||||
|
||||
if (ctx->fallback && ctx->same_key) {
|
||||
char *__subreq_desc = kzalloc(sizeof(struct skcipher_request) +
|
||||
crypto_skcipher_reqsize(ctx->fallback),
|
||||
GFP_ATOMIC);
|
||||
struct skcipher_request *subreq = (void *)__subreq_desc;
|
||||
int ret = 0;
|
||||
|
||||
if (!subreq)
|
||||
return -ENOMEM;
|
||||
|
||||
skcipher_request_set_tfm(subreq, ctx->fallback);
|
||||
skcipher_request_set_callback(subreq, req->base.flags, NULL,
|
||||
NULL);
|
||||
skcipher_request_set_crypt(subreq, req->src, req->dst,
|
||||
req->nbytes, req->info);
|
||||
|
||||
if (mode & TDES_FLAGS_ENCRYPT)
|
||||
ret = crypto_skcipher_encrypt(subreq);
|
||||
else
|
||||
ret = crypto_skcipher_decrypt(subreq);
|
||||
|
||||
skcipher_request_free(subreq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dd = aml_tdes_find_dev(ctx);
|
||||
if (!dd)
|
||||
return -ENODEV;
|
||||
@@ -667,7 +739,10 @@ static int aml_tdes_cbc_decrypt(struct ablkcipher_request *req)
|
||||
|
||||
static int aml_tdes_cra_init(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct aml_tdes_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
tfm->crt_ablkcipher.reqsize = sizeof(struct aml_tdes_reqctx);
|
||||
ctx->fallback = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -676,7 +751,7 @@ static void aml_tdes_cra_exit(struct crypto_tfm *tfm)
|
||||
{
|
||||
}
|
||||
|
||||
static struct crypto_alg des_algs[] = {
|
||||
static struct crypto_alg des_tdes_algs[] = {
|
||||
{
|
||||
.cra_name = "ecb(des)",
|
||||
.cra_driver_name = "ecb-des-aml",
|
||||
@@ -718,9 +793,6 @@ static struct crypto_alg des_algs[] = {
|
||||
.decrypt = aml_tdes_cbc_decrypt,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static struct crypto_alg tdes_algs[] = {
|
||||
{
|
||||
.cra_name = "ecb(des3_ede)",
|
||||
.cra_driver_name = "ecb-tdes-aml",
|
||||
@@ -764,6 +836,114 @@ static struct crypto_alg tdes_algs[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static int aml_tdes_lite_cra_init(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct aml_tdes_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
const char *alg_name = crypto_tfm_alg_name(tfm);
|
||||
const u32 flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK;
|
||||
|
||||
tfm->crt_ablkcipher.reqsize = sizeof(struct aml_tdes_reqctx);
|
||||
|
||||
/* Allocate a fallback and abort if it failed. */
|
||||
ctx->fallback = crypto_alloc_skcipher(alg_name, 0,
|
||||
flags);
|
||||
if (IS_ERR(ctx->fallback)) {
|
||||
pr_err("aml-tdes: fallback '%s' could not be loaded.\n",
|
||||
alg_name);
|
||||
return PTR_ERR(ctx->fallback);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void aml_tdes_lite_cra_exit(struct crypto_tfm *tfm)
|
||||
{
|
||||
struct aml_tdes_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||
|
||||
if (ctx->fallback)
|
||||
crypto_free_skcipher(ctx->fallback);
|
||||
|
||||
ctx->fallback = NULL;
|
||||
}
|
||||
|
||||
static int aml_tdes_lite_setkey(struct crypto_ablkcipher *tfm, const u8 *key,
|
||||
unsigned int keylen)
|
||||
{
|
||||
struct aml_tdes_ctx *ctx = crypto_ablkcipher_ctx(tfm);
|
||||
int ret = 0;
|
||||
u64 *tmp = NULL;
|
||||
|
||||
if ((keylen != 2 * DES_KEY_SIZE) && (keylen != 3 * DES_KEY_SIZE)) {
|
||||
crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(ctx->key, key, keylen);
|
||||
ctx->keylen = keylen;
|
||||
|
||||
tmp = (u64 *)ctx->key;
|
||||
if (keylen == 2 * DES_KEY_SIZE)
|
||||
ctx->same_key = !(tmp[0] ^ tmp[1]);
|
||||
else
|
||||
ctx->same_key = !((tmp[0] ^ tmp[1]) | (tmp[0] ^ tmp[2]));
|
||||
|
||||
if (ctx->same_key) {
|
||||
crypto_skcipher_clear_flags(ctx->fallback, CRYPTO_TFM_REQ_MASK);
|
||||
crypto_skcipher_set_flags(ctx->fallback, tfm->base.crt_flags &
|
||||
CRYPTO_TFM_REQ_MASK);
|
||||
ret = crypto_skcipher_setkey(ctx->fallback, key, keylen);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static struct crypto_alg tdes_lite_algs[] = {
|
||||
{
|
||||
.cra_name = "ecb(des3_ede)",
|
||||
.cra_driver_name = "ecb-tdes-lite-aml",
|
||||
.cra_priority = 200,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
|
||||
CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = DES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct aml_tdes_ctx),
|
||||
.cra_alignmask = 0,
|
||||
.cra_type = &crypto_ablkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_init = aml_tdes_lite_cra_init,
|
||||
.cra_exit = aml_tdes_lite_cra_exit,
|
||||
.cra_u.ablkcipher = {
|
||||
.min_keysize = 2 * DES_KEY_SIZE,
|
||||
.max_keysize = 3 * DES_KEY_SIZE,
|
||||
.setkey = aml_tdes_lite_setkey,
|
||||
.encrypt = aml_tdes_ecb_encrypt,
|
||||
.decrypt = aml_tdes_ecb_decrypt,
|
||||
}
|
||||
},
|
||||
{
|
||||
.cra_name = "cbc(des3_ede)",
|
||||
.cra_driver_name = "cbc-tdes-lite-aml",
|
||||
.cra_priority = 200,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
|
||||
CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_blocksize = DES_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct aml_tdes_ctx),
|
||||
.cra_alignmask = 0,
|
||||
.cra_type = &crypto_ablkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_init = aml_tdes_lite_cra_init,
|
||||
.cra_exit = aml_tdes_lite_cra_exit,
|
||||
.cra_u.ablkcipher = {
|
||||
.min_keysize = 2 * DES_KEY_SIZE,
|
||||
.max_keysize = 3 * DES_KEY_SIZE,
|
||||
.ivsize = DES_BLOCK_SIZE,
|
||||
.setkey = aml_tdes_lite_setkey,
|
||||
.encrypt = aml_tdes_cbc_encrypt,
|
||||
.decrypt = aml_tdes_cbc_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void aml_tdes_queue_task(unsigned long data)
|
||||
{
|
||||
struct aml_tdes_dev *dd = (struct aml_tdes_dev *)data;
|
||||
@@ -774,6 +954,7 @@ static void aml_tdes_queue_task(unsigned long data)
|
||||
static void aml_tdes_done_task(unsigned long data)
|
||||
{
|
||||
struct aml_tdes_dev *dd = (struct aml_tdes_dev *) data;
|
||||
struct device *dev = dd->dev;
|
||||
int err;
|
||||
|
||||
err = aml_tdes_crypt_dma_stop(dd);
|
||||
@@ -790,7 +971,7 @@ static void aml_tdes_done_task(unsigned long data)
|
||||
dd->in_sg = sg_next(dd->in_sg);
|
||||
dd->out_sg = sg_next(dd->out_sg);
|
||||
if (!dd->in_sg || !dd->out_sg) {
|
||||
pr_err("aml-tdes: sg invalid\n");
|
||||
dev_err(dev, "aml-tdes: sg invalid\n");
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
@@ -810,11 +991,12 @@ static void aml_tdes_done_task(unsigned long data)
|
||||
static irqreturn_t aml_tdes_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct aml_tdes_dev *tdes_dd = dev_id;
|
||||
struct device *dev = tdes_dd->dev;
|
||||
uint8_t status = aml_read_crypto_reg(tdes_dd->status);
|
||||
|
||||
if (status) {
|
||||
if (status == 0x1)
|
||||
pr_err("irq overwrite\n");
|
||||
dev_err(dev, "irq overwrite\n");
|
||||
if (tdes_dd->dma->dma_busy == DMA_FLAG_MAY_OCCUPY)
|
||||
return IRQ_HANDLED;
|
||||
if ((tdes_dd->dma->dma_busy & DMA_FLAG_TDES_IN_USE) &&
|
||||
@@ -831,29 +1013,22 @@ static irqreturn_t aml_tdes_irq(int irq, void *dev_id)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
static void aml_tdes_unregister_algs(struct aml_tdes_dev *dd)
|
||||
static void aml_tdes_unregister_algs(struct aml_tdes_dev *dd,
|
||||
const struct aml_tdes_info *tdes_info)
|
||||
{
|
||||
int i = 0;
|
||||
int i;
|
||||
|
||||
for (; i < ARRAY_SIZE(des_algs); i++)
|
||||
crypto_unregister_alg(&des_algs[i]);
|
||||
|
||||
for (; i < ARRAY_SIZE(tdes_algs); i++)
|
||||
crypto_unregister_alg(&tdes_algs[i]);
|
||||
for (i = 0; i < tdes_info->num_algs; i++)
|
||||
crypto_unregister_alg(&(tdes_info->algs[i]));
|
||||
}
|
||||
|
||||
static int aml_tdes_register_algs(struct aml_tdes_dev *dd)
|
||||
static int aml_tdes_register_algs(struct aml_tdes_dev *dd,
|
||||
const struct aml_tdes_info *tdes_info)
|
||||
{
|
||||
int err = 0, i = 0, j = 0, k = 0;
|
||||
int err, i, j;
|
||||
|
||||
for (; i < ARRAY_SIZE(des_algs); i++) {
|
||||
err = crypto_register_alg(&des_algs[i]);
|
||||
if (err)
|
||||
goto err_des_algs;
|
||||
}
|
||||
|
||||
for (; k < ARRAY_SIZE(tdes_algs); k++) {
|
||||
err = crypto_register_alg(&tdes_algs[k]);
|
||||
for (i = 0; i < tdes_info->num_algs; i++) {
|
||||
err = crypto_register_alg(&(tdes_info->algs[i]));
|
||||
if (err)
|
||||
goto err_tdes_algs;
|
||||
}
|
||||
@@ -861,28 +1036,58 @@ static int aml_tdes_register_algs(struct aml_tdes_dev *dd)
|
||||
return 0;
|
||||
|
||||
err_tdes_algs:
|
||||
for (j = 0; j < k; j++)
|
||||
crypto_unregister_alg(&tdes_algs[j]);
|
||||
|
||||
err_des_algs:
|
||||
for (j = 0; j < i; j++)
|
||||
crypto_unregister_alg(&des_algs[j]);
|
||||
crypto_unregister_alg(&(tdes_info->algs[j]));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
struct aml_tdes_info aml_des_tdes = {
|
||||
.algs = des_tdes_algs,
|
||||
.num_algs = ARRAY_SIZE(des_tdes_algs),
|
||||
};
|
||||
|
||||
struct aml_tdes_info aml_tdes_lite = {
|
||||
.algs = tdes_lite_algs,
|
||||
.num_algs = ARRAY_SIZE(tdes_lite_algs),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id aml_tdes_dt_match[] = {
|
||||
{ .compatible = "amlogic,des_dma,tdes_dma",
|
||||
.data = &aml_des_tdes,
|
||||
},
|
||||
{ .compatible = "amlogic,tdes_dma",
|
||||
.data = &aml_tdes_lite,
|
||||
},
|
||||
{},
|
||||
};
|
||||
#else
|
||||
#define aml_tdes_dt_match NULL
|
||||
#endif
|
||||
|
||||
static int aml_tdes_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct aml_tdes_dev *tdes_dd;
|
||||
struct device *dev = &pdev->dev;
|
||||
int err = -EPERM;
|
||||
const struct of_device_id *match;
|
||||
const struct aml_tdes_info *tdes_info = NULL;
|
||||
|
||||
tdes_dd = kzalloc(sizeof(struct aml_tdes_dev), GFP_KERNEL);
|
||||
tdes_dd = devm_kzalloc(dev, sizeof(struct aml_tdes_dev), GFP_KERNEL);
|
||||
if (tdes_dd == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto tdes_dd_err;
|
||||
}
|
||||
|
||||
match = of_match_device(aml_tdes_dt_match, &pdev->dev);
|
||||
if (!match) {
|
||||
dev_err(dev, "%s: cannot find match dt\n", __func__);
|
||||
err = -EINVAL;
|
||||
goto tdes_dd_err;
|
||||
}
|
||||
|
||||
tdes_info = match->data;
|
||||
tdes_dd->dev = dev;
|
||||
tdes_dd->dma = dev_get_drvdata(dev->parent);
|
||||
tdes_dd->thread = tdes_dd->dma->thread;
|
||||
@@ -899,8 +1104,8 @@ static int aml_tdes_probe(struct platform_device *pdev)
|
||||
(unsigned long)tdes_dd);
|
||||
|
||||
crypto_init_queue(&tdes_dd->queue, AML_TDES_QUEUE_LENGTH);
|
||||
err = request_irq(tdes_dd->irq, aml_tdes_irq, IRQF_SHARED, "aml-tdes",
|
||||
tdes_dd);
|
||||
err = devm_request_irq(dev, tdes_dd->irq, aml_tdes_irq, IRQF_SHARED,
|
||||
"aml-tdes", tdes_dd);
|
||||
if (err) {
|
||||
dev_err(dev, "unable to request tdes irq.\n");
|
||||
goto tdes_irq_err;
|
||||
@@ -918,7 +1123,7 @@ static int aml_tdes_probe(struct platform_device *pdev)
|
||||
list_add_tail(&tdes_dd->list, &aml_tdes.dev_list);
|
||||
spin_unlock(&aml_tdes.lock);
|
||||
|
||||
err = aml_tdes_register_algs(tdes_dd);
|
||||
err = aml_tdes_register_algs(tdes_dd, tdes_info);
|
||||
if (err)
|
||||
goto err_algs;
|
||||
|
||||
@@ -932,13 +1137,9 @@ err_algs:
|
||||
spin_unlock(&aml_tdes.lock);
|
||||
aml_tdes_buff_cleanup(tdes_dd);
|
||||
err_tdes_buff:
|
||||
free_irq(tdes_dd->irq, tdes_dd);
|
||||
tdes_irq_err:
|
||||
|
||||
tasklet_kill(&tdes_dd->done_task);
|
||||
tasklet_kill(&tdes_dd->queue_task);
|
||||
kfree(tdes_dd);
|
||||
tdes_dd = NULL;
|
||||
tdes_dd_err:
|
||||
dev_err(dev, "initialization failed.\n");
|
||||
|
||||
@@ -948,38 +1149,33 @@ tdes_dd_err:
|
||||
static int aml_tdes_remove(struct platform_device *pdev)
|
||||
{
|
||||
static struct aml_tdes_dev *tdes_dd;
|
||||
struct device *dev = &pdev->dev;
|
||||
const struct of_device_id *match;
|
||||
const struct aml_tdes_info *tdes_info = NULL;
|
||||
|
||||
tdes_dd = platform_get_drvdata(pdev);
|
||||
if (!tdes_dd)
|
||||
return -ENODEV;
|
||||
|
||||
match = of_match_device(aml_tdes_dt_match, &pdev->dev);
|
||||
if (!match) {
|
||||
dev_err(dev, "%s: cannot find match dt\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tdes_info = match->data;
|
||||
spin_lock(&aml_tdes.lock);
|
||||
list_del(&tdes_dd->list);
|
||||
spin_unlock(&aml_tdes.lock);
|
||||
|
||||
aml_tdes_unregister_algs(tdes_dd);
|
||||
aml_tdes_unregister_algs(tdes_dd, tdes_info);
|
||||
|
||||
tasklet_kill(&tdes_dd->done_task);
|
||||
tasklet_kill(&tdes_dd->queue_task);
|
||||
|
||||
if (tdes_dd->irq > 0)
|
||||
free_irq(tdes_dd->irq, tdes_dd);
|
||||
|
||||
kfree(tdes_dd);
|
||||
tdes_dd = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id aml_tdes_dt_match[] = {
|
||||
{ .compatible = "amlogic,des_dma,tdes_dma",
|
||||
},
|
||||
{},
|
||||
};
|
||||
#else
|
||||
#define aml_tdes_dt_match NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver aml_tdes_driver = {
|
||||
.probe = aml_tdes_probe,
|
||||
.remove = aml_tdes_remove,
|
||||
|
||||
Reference in New Issue
Block a user