diff options
| author | Olof Johansson <olof@lixom.net> | 2013-12-22 14:42:50 -0500 |
|---|---|---|
| committer | Olof Johansson <olof@lixom.net> | 2013-12-22 14:42:50 -0500 |
| commit | 8f2d751a9e4061f30e10a38ef2da81552239da3e (patch) | |
| tree | cea719ff0474b0b693d59db662102fddfa98be57 | |
| parent | 958c025a2a1de40b8edb615b2d99a962c6c84019 (diff) | |
| parent | 1ca5b7d95315c42cf0b78d33cd316e404a9f137c (diff) | |
Merge tag 'at91-drivers' of git://github.com/at91linux/linux-at91 into next/drivers
From Nicolas Ferre:
AT91 crypto drivers DT support:
- add DT to sha/des/aes existing drivers
- add DMA DT
- all documentation added to crypto/atmel-crypto.txt file
* tag 'at91-drivers' of git://github.com/at91linux/linux-at91:
crypto: atmel-sha - add sha information to the log
crypto: atmel-sha - add support for Device Tree
crypto: atmel-tdes - add support for Device Tree
crypto: atmel-aes - add support for Device Tree
Signed-off-by: Olof Johansson <olof@lixom.net>
| -rw-r--r-- | Documentation/devicetree/bindings/crypto/atmel-crypto.txt | 68 | ||||
| -rw-r--r-- | drivers/crypto/atmel-aes.c | 143 | ||||
| -rw-r--r-- | drivers/crypto/atmel-sha.c | 103 | ||||
| -rw-r--r-- | drivers/crypto/atmel-tdes.c | 143 |
4 files changed, 334 insertions, 123 deletions
diff --git a/Documentation/devicetree/bindings/crypto/atmel-crypto.txt b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt new file mode 100644 index 000000000000..f2aab3dc2b52 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/atmel-crypto.txt | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | * Atmel HW cryptographic accelerators | ||
| 2 | |||
| 3 | These are the HW cryptographic accelerators found on some Atmel products. | ||
| 4 | |||
| 5 | * Advanced Encryption Standard (AES) | ||
| 6 | |||
| 7 | Required properties: | ||
| 8 | - compatible : Should be "atmel,at91sam9g46-aes". | ||
| 9 | - reg: Should contain AES registers location and length. | ||
| 10 | - interrupts: Should contain the IRQ line for the AES. | ||
| 11 | - dmas: List of two DMA specifiers as described in | ||
| 12 | atmel-dma.txt and dma.txt files. | ||
| 13 | - dma-names: Contains one identifier string for each DMA specifier | ||
| 14 | in the dmas property. | ||
| 15 | |||
| 16 | Example: | ||
| 17 | aes@f8038000 { | ||
| 18 | compatible = "atmel,at91sam9g46-aes"; | ||
| 19 | reg = <0xf8038000 0x100>; | ||
| 20 | interrupts = <43 4 0>; | ||
| 21 | dmas = <&dma1 2 18>, | ||
| 22 | <&dma1 2 19>; | ||
| 23 | dma-names = "tx", "rx"; | ||
| 24 | |||
| 25 | * Triple Data Encryption Standard (Triple DES) | ||
| 26 | |||
| 27 | Required properties: | ||
| 28 | - compatible : Should be "atmel,at91sam9g46-tdes". | ||
| 29 | - reg: Should contain TDES registers location and length. | ||
| 30 | - interrupts: Should contain the IRQ line for the TDES. | ||
| 31 | |||
| 32 | Optional properties: | ||
| 33 | - dmas: List of two DMA specifiers as described in | ||
| 34 | atmel-dma.txt and dma.txt files. | ||
| 35 | - dma-names: Contains one identifier string for each DMA specifier | ||
| 36 | in the dmas property. | ||
| 37 | |||
| 38 | Example: | ||
| 39 | tdes@f803c000 { | ||
| 40 | compatible = "atmel,at91sam9g46-tdes"; | ||
| 41 | reg = <0xf803c000 0x100>; | ||
| 42 | interrupts = <44 4 0>; | ||
| 43 | dmas = <&dma1 2 20>, | ||
| 44 | <&dma1 2 21>; | ||
| 45 | dma-names = "tx", "rx"; | ||
| 46 | }; | ||
| 47 | |||
| 48 | * Secure Hash Algorithm (SHA) | ||
| 49 | |||
| 50 | Required properties: | ||
| 51 | - compatible : Should be "atmel,at91sam9g46-sha". | ||
| 52 | - reg: Should contain SHA registers location and length. | ||
| 53 | - interrupts: Should contain the IRQ line for the SHA. | ||
| 54 | |||
| 55 | Optional properties: | ||
| 56 | - dmas: One DMA specifiers as described in | ||
| 57 | atmel-dma.txt and dma.txt files. | ||
| 58 | - dma-names: Contains one identifier string for each DMA specifier | ||
| 59 | in the dmas property. Only one "tx" string needed. | ||
| 60 | |||
| 61 | Example: | ||
| 62 | sha@f8034000 { | ||
| 63 | compatible = "atmel,at91sam9g46-sha"; | ||
| 64 | reg = <0xf8034000 0x100>; | ||
| 65 | interrupts = <42 4 0>; | ||
| 66 | dmas = <&dma1 2 17>; | ||
| 67 | dma-names = "tx"; | ||
| 68 | }; | ||
diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c index c1efd910d97b..d7c9e317423c 100644 --- a/drivers/crypto/atmel-aes.c +++ b/drivers/crypto/atmel-aes.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
| 31 | #include <linux/scatterlist.h> | 31 | #include <linux/scatterlist.h> |
| 32 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
| 33 | #include <linux/of_device.h> | ||
| 33 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
| 34 | #include <linux/crypto.h> | 35 | #include <linux/crypto.h> |
| 35 | #include <linux/cryptohash.h> | 36 | #include <linux/cryptohash.h> |
| @@ -39,6 +40,7 @@ | |||
| 39 | #include <crypto/hash.h> | 40 | #include <crypto/hash.h> |
| 40 | #include <crypto/internal/hash.h> | 41 | #include <crypto/internal/hash.h> |
| 41 | #include <linux/platform_data/crypto-atmel.h> | 42 | #include <linux/platform_data/crypto-atmel.h> |
| 43 | #include <dt-bindings/dma/at91.h> | ||
| 42 | #include "atmel-aes-regs.h" | 44 | #include "atmel-aes-regs.h" |
| 43 | 45 | ||
| 44 | #define CFB8_BLOCK_SIZE 1 | 46 | #define CFB8_BLOCK_SIZE 1 |
| @@ -747,59 +749,50 @@ static int atmel_aes_dma_init(struct atmel_aes_dev *dd, | |||
| 747 | struct crypto_platform_data *pdata) | 749 | struct crypto_platform_data *pdata) |
| 748 | { | 750 | { |
| 749 | int err = -ENOMEM; | 751 | int err = -ENOMEM; |
| 750 | dma_cap_mask_t mask_in, mask_out; | 752 | dma_cap_mask_t mask; |
| 753 | |||
| 754 | dma_cap_zero(mask); | ||
| 755 | dma_cap_set(DMA_SLAVE, mask); | ||
| 756 | |||
| 757 | /* Try to grab 2 DMA channels */ | ||
| 758 | dd->dma_lch_in.chan = dma_request_slave_channel_compat(mask, | ||
| 759 | atmel_aes_filter, &pdata->dma_slave->rxdata, dd->dev, "tx"); | ||
| 760 | if (!dd->dma_lch_in.chan) | ||
| 761 | goto err_dma_in; | ||
| 762 | |||
| 763 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; | ||
| 764 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
| 765 | AES_IDATAR(0); | ||
| 766 | dd->dma_lch_in.dma_conf.src_maxburst = dd->caps.max_burst_size; | ||
| 767 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
| 768 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 769 | dd->dma_lch_in.dma_conf.dst_maxburst = dd->caps.max_burst_size; | ||
| 770 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
| 771 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 772 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
| 773 | |||
| 774 | dd->dma_lch_out.chan = dma_request_slave_channel_compat(mask, | ||
| 775 | atmel_aes_filter, &pdata->dma_slave->txdata, dd->dev, "rx"); | ||
| 776 | if (!dd->dma_lch_out.chan) | ||
| 777 | goto err_dma_out; | ||
| 778 | |||
| 779 | dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM; | ||
| 780 | dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + | ||
| 781 | AES_ODATAR(0); | ||
| 782 | dd->dma_lch_out.dma_conf.src_maxburst = dd->caps.max_burst_size; | ||
| 783 | dd->dma_lch_out.dma_conf.src_addr_width = | ||
| 784 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 785 | dd->dma_lch_out.dma_conf.dst_maxburst = dd->caps.max_burst_size; | ||
| 786 | dd->dma_lch_out.dma_conf.dst_addr_width = | ||
| 787 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 788 | dd->dma_lch_out.dma_conf.device_fc = false; | ||
| 751 | 789 | ||
| 752 | if (pdata && pdata->dma_slave->txdata.dma_dev && | 790 | return 0; |
| 753 | pdata->dma_slave->rxdata.dma_dev) { | ||
| 754 | |||
| 755 | /* Try to grab 2 DMA channels */ | ||
| 756 | dma_cap_zero(mask_in); | ||
| 757 | dma_cap_set(DMA_SLAVE, mask_in); | ||
| 758 | |||
| 759 | dd->dma_lch_in.chan = dma_request_channel(mask_in, | ||
| 760 | atmel_aes_filter, &pdata->dma_slave->rxdata); | ||
| 761 | |||
| 762 | if (!dd->dma_lch_in.chan) | ||
| 763 | goto err_dma_in; | ||
| 764 | |||
| 765 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; | ||
| 766 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
| 767 | AES_IDATAR(0); | ||
| 768 | dd->dma_lch_in.dma_conf.src_maxburst = dd->caps.max_burst_size; | ||
| 769 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
| 770 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 771 | dd->dma_lch_in.dma_conf.dst_maxburst = dd->caps.max_burst_size; | ||
| 772 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
| 773 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 774 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
| 775 | |||
| 776 | dma_cap_zero(mask_out); | ||
| 777 | dma_cap_set(DMA_SLAVE, mask_out); | ||
| 778 | dd->dma_lch_out.chan = dma_request_channel(mask_out, | ||
| 779 | atmel_aes_filter, &pdata->dma_slave->txdata); | ||
| 780 | |||
| 781 | if (!dd->dma_lch_out.chan) | ||
| 782 | goto err_dma_out; | ||
| 783 | |||
| 784 | dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM; | ||
| 785 | dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + | ||
| 786 | AES_ODATAR(0); | ||
| 787 | dd->dma_lch_out.dma_conf.src_maxburst = dd->caps.max_burst_size; | ||
| 788 | dd->dma_lch_out.dma_conf.src_addr_width = | ||
| 789 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 790 | dd->dma_lch_out.dma_conf.dst_maxburst = dd->caps.max_burst_size; | ||
| 791 | dd->dma_lch_out.dma_conf.dst_addr_width = | ||
| 792 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 793 | dd->dma_lch_out.dma_conf.device_fc = false; | ||
| 794 | |||
| 795 | return 0; | ||
| 796 | } else { | ||
| 797 | return -ENODEV; | ||
| 798 | } | ||
| 799 | 791 | ||
| 800 | err_dma_out: | 792 | err_dma_out: |
| 801 | dma_release_channel(dd->dma_lch_in.chan); | 793 | dma_release_channel(dd->dma_lch_in.chan); |
| 802 | err_dma_in: | 794 | err_dma_in: |
| 795 | dev_warn(dd->dev, "no DMA channel available\n"); | ||
| 803 | return err; | 796 | return err; |
| 804 | } | 797 | } |
| 805 | 798 | ||
| @@ -1261,6 +1254,47 @@ static void atmel_aes_get_cap(struct atmel_aes_dev *dd) | |||
| 1261 | } | 1254 | } |
| 1262 | } | 1255 | } |
| 1263 | 1256 | ||
| 1257 | #if defined(CONFIG_OF) | ||
| 1258 | static const struct of_device_id atmel_aes_dt_ids[] = { | ||
| 1259 | { .compatible = "atmel,at91sam9g46-aes" }, | ||
| 1260 | { /* sentinel */ } | ||
| 1261 | }; | ||
| 1262 | MODULE_DEVICE_TABLE(of, atmel_aes_dt_ids); | ||
| 1263 | |||
| 1264 | static struct crypto_platform_data *atmel_aes_of_init(struct platform_device *pdev) | ||
| 1265 | { | ||
| 1266 | struct device_node *np = pdev->dev.of_node; | ||
| 1267 | struct crypto_platform_data *pdata; | ||
| 1268 | |||
| 1269 | if (!np) { | ||
| 1270 | dev_err(&pdev->dev, "device node not found\n"); | ||
| 1271 | return ERR_PTR(-EINVAL); | ||
| 1272 | } | ||
| 1273 | |||
| 1274 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
| 1275 | if (!pdata) { | ||
| 1276 | dev_err(&pdev->dev, "could not allocate memory for pdata\n"); | ||
| 1277 | return ERR_PTR(-ENOMEM); | ||
| 1278 | } | ||
| 1279 | |||
| 1280 | pdata->dma_slave = devm_kzalloc(&pdev->dev, | ||
| 1281 | sizeof(*(pdata->dma_slave)), | ||
| 1282 | GFP_KERNEL); | ||
| 1283 | if (!pdata->dma_slave) { | ||
| 1284 | dev_err(&pdev->dev, "could not allocate memory for dma_slave\n"); | ||
| 1285 | devm_kfree(&pdev->dev, pdata); | ||
| 1286 | return ERR_PTR(-ENOMEM); | ||
| 1287 | } | ||
| 1288 | |||
| 1289 | return pdata; | ||
| 1290 | } | ||
| 1291 | #else | ||
| 1292 | static inline struct crypto_platform_data *atmel_aes_of_init(struct platform_device *pdev) | ||
| 1293 | { | ||
| 1294 | return ERR_PTR(-EINVAL); | ||
| 1295 | } | ||
| 1296 | #endif | ||
| 1297 | |||
| 1264 | static int atmel_aes_probe(struct platform_device *pdev) | 1298 | static int atmel_aes_probe(struct platform_device *pdev) |
| 1265 | { | 1299 | { |
| 1266 | struct atmel_aes_dev *aes_dd; | 1300 | struct atmel_aes_dev *aes_dd; |
| @@ -1272,6 +1306,14 @@ static int atmel_aes_probe(struct platform_device *pdev) | |||
| 1272 | 1306 | ||
| 1273 | pdata = pdev->dev.platform_data; | 1307 | pdata = pdev->dev.platform_data; |
| 1274 | if (!pdata) { | 1308 | if (!pdata) { |
| 1309 | pdata = atmel_aes_of_init(pdev); | ||
| 1310 | if (IS_ERR(pdata)) { | ||
| 1311 | err = PTR_ERR(pdata); | ||
| 1312 | goto aes_dd_err; | ||
| 1313 | } | ||
| 1314 | } | ||
| 1315 | |||
| 1316 | if (!pdata->dma_slave) { | ||
| 1275 | err = -ENXIO; | 1317 | err = -ENXIO; |
| 1276 | goto aes_dd_err; | 1318 | goto aes_dd_err; |
| 1277 | } | 1319 | } |
| @@ -1358,7 +1400,9 @@ static int atmel_aes_probe(struct platform_device *pdev) | |||
| 1358 | if (err) | 1400 | if (err) |
| 1359 | goto err_algs; | 1401 | goto err_algs; |
| 1360 | 1402 | ||
| 1361 | dev_info(dev, "Atmel AES\n"); | 1403 | dev_info(dev, "Atmel AES - Using %s, %s for DMA transfers\n", |
| 1404 | dma_chan_name(aes_dd->dma_lch_in.chan), | ||
| 1405 | dma_chan_name(aes_dd->dma_lch_out.chan)); | ||
| 1362 | 1406 | ||
| 1363 | return 0; | 1407 | return 0; |
| 1364 | 1408 | ||
| @@ -1424,6 +1468,7 @@ static struct platform_driver atmel_aes_driver = { | |||
| 1424 | .driver = { | 1468 | .driver = { |
| 1425 | .name = "atmel_aes", | 1469 | .name = "atmel_aes", |
| 1426 | .owner = THIS_MODULE, | 1470 | .owner = THIS_MODULE, |
| 1471 | .of_match_table = of_match_ptr(atmel_aes_dt_ids), | ||
| 1427 | }, | 1472 | }, |
| 1428 | }; | 1473 | }; |
| 1429 | 1474 | ||
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c index eaed8bf183bc..0618be06b9fb 100644 --- a/drivers/crypto/atmel-sha.c +++ b/drivers/crypto/atmel-sha.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
| 31 | #include <linux/scatterlist.h> | 31 | #include <linux/scatterlist.h> |
| 32 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
| 33 | #include <linux/of_device.h> | ||
| 33 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
| 34 | #include <linux/crypto.h> | 35 | #include <linux/crypto.h> |
| 35 | #include <linux/cryptohash.h> | 36 | #include <linux/cryptohash.h> |
| @@ -1263,32 +1264,29 @@ static int atmel_sha_dma_init(struct atmel_sha_dev *dd, | |||
| 1263 | int err = -ENOMEM; | 1264 | int err = -ENOMEM; |
| 1264 | dma_cap_mask_t mask_in; | 1265 | dma_cap_mask_t mask_in; |
| 1265 | 1266 | ||
| 1266 | if (pdata && pdata->dma_slave->rxdata.dma_dev) { | 1267 | /* Try to grab DMA channel */ |
| 1267 | /* Try to grab DMA channel */ | 1268 | dma_cap_zero(mask_in); |
| 1268 | dma_cap_zero(mask_in); | 1269 | dma_cap_set(DMA_SLAVE, mask_in); |
| 1269 | dma_cap_set(DMA_SLAVE, mask_in); | ||
| 1270 | 1270 | ||
| 1271 | dd->dma_lch_in.chan = dma_request_channel(mask_in, | 1271 | dd->dma_lch_in.chan = dma_request_slave_channel_compat(mask_in, |
| 1272 | atmel_sha_filter, &pdata->dma_slave->rxdata); | 1272 | atmel_sha_filter, &pdata->dma_slave->rxdata, dd->dev, "tx"); |
| 1273 | 1273 | if (!dd->dma_lch_in.chan) { | |
| 1274 | if (!dd->dma_lch_in.chan) | 1274 | dev_warn(dd->dev, "no DMA channel available\n"); |
| 1275 | return err; | 1275 | return err; |
| 1276 | |||
| 1277 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; | ||
| 1278 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
| 1279 | SHA_REG_DIN(0); | ||
| 1280 | dd->dma_lch_in.dma_conf.src_maxburst = 1; | ||
| 1281 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
| 1282 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 1283 | dd->dma_lch_in.dma_conf.dst_maxburst = 1; | ||
| 1284 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
| 1285 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 1286 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
| 1287 | |||
| 1288 | return 0; | ||
| 1289 | } | 1276 | } |
| 1290 | 1277 | ||
| 1291 | return -ENODEV; | 1278 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; |
| 1279 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
| 1280 | SHA_REG_DIN(0); | ||
| 1281 | dd->dma_lch_in.dma_conf.src_maxburst = 1; | ||
| 1282 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
| 1283 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 1284 | dd->dma_lch_in.dma_conf.dst_maxburst = 1; | ||
| 1285 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
| 1286 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 1287 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
| 1288 | |||
| 1289 | return 0; | ||
| 1292 | } | 1290 | } |
| 1293 | 1291 | ||
| 1294 | static void atmel_sha_dma_cleanup(struct atmel_sha_dev *dd) | 1292 | static void atmel_sha_dma_cleanup(struct atmel_sha_dev *dd) |
| @@ -1326,6 +1324,48 @@ static void atmel_sha_get_cap(struct atmel_sha_dev *dd) | |||
| 1326 | } | 1324 | } |
| 1327 | } | 1325 | } |
| 1328 | 1326 | ||
| 1327 | #if defined(CONFIG_OF) | ||
| 1328 | static const struct of_device_id atmel_sha_dt_ids[] = { | ||
| 1329 | { .compatible = "atmel,at91sam9g46-sha" }, | ||
| 1330 | { /* sentinel */ } | ||
| 1331 | }; | ||
| 1332 | |||
| 1333 | MODULE_DEVICE_TABLE(of, atmel_sha_dt_ids); | ||
| 1334 | |||
| 1335 | static struct crypto_platform_data *atmel_sha_of_init(struct platform_device *pdev) | ||
| 1336 | { | ||
| 1337 | struct device_node *np = pdev->dev.of_node; | ||
| 1338 | struct crypto_platform_data *pdata; | ||
| 1339 | |||
| 1340 | if (!np) { | ||
| 1341 | dev_err(&pdev->dev, "device node not found\n"); | ||
| 1342 | return ERR_PTR(-EINVAL); | ||
| 1343 | } | ||
| 1344 | |||
| 1345 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
| 1346 | if (!pdata) { | ||
| 1347 | dev_err(&pdev->dev, "could not allocate memory for pdata\n"); | ||
| 1348 | return ERR_PTR(-ENOMEM); | ||
| 1349 | } | ||
| 1350 | |||
| 1351 | pdata->dma_slave = devm_kzalloc(&pdev->dev, | ||
| 1352 | sizeof(*(pdata->dma_slave)), | ||
| 1353 | GFP_KERNEL); | ||
| 1354 | if (!pdata->dma_slave) { | ||
| 1355 | dev_err(&pdev->dev, "could not allocate memory for dma_slave\n"); | ||
| 1356 | devm_kfree(&pdev->dev, pdata); | ||
| 1357 | return ERR_PTR(-ENOMEM); | ||
| 1358 | } | ||
| 1359 | |||
| 1360 | return pdata; | ||
| 1361 | } | ||
| 1362 | #else /* CONFIG_OF */ | ||
| 1363 | static inline struct crypto_platform_data *atmel_sha_of_init(struct platform_device *dev) | ||
| 1364 | { | ||
| 1365 | return ERR_PTR(-EINVAL); | ||
| 1366 | } | ||
| 1367 | #endif | ||
| 1368 | |||
| 1329 | static int atmel_sha_probe(struct platform_device *pdev) | 1369 | static int atmel_sha_probe(struct platform_device *pdev) |
| 1330 | { | 1370 | { |
| 1331 | struct atmel_sha_dev *sha_dd; | 1371 | struct atmel_sha_dev *sha_dd; |
| @@ -1402,13 +1442,23 @@ static int atmel_sha_probe(struct platform_device *pdev) | |||
| 1402 | if (sha_dd->caps.has_dma) { | 1442 | if (sha_dd->caps.has_dma) { |
| 1403 | pdata = pdev->dev.platform_data; | 1443 | pdata = pdev->dev.platform_data; |
| 1404 | if (!pdata) { | 1444 | if (!pdata) { |
| 1405 | dev_err(&pdev->dev, "platform data not available\n"); | 1445 | pdata = atmel_sha_of_init(pdev); |
| 1446 | if (IS_ERR(pdata)) { | ||
| 1447 | dev_err(&pdev->dev, "platform data not available\n"); | ||
| 1448 | err = PTR_ERR(pdata); | ||
| 1449 | goto err_pdata; | ||
| 1450 | } | ||
| 1451 | } | ||
| 1452 | if (!pdata->dma_slave) { | ||
| 1406 | err = -ENXIO; | 1453 | err = -ENXIO; |
| 1407 | goto err_pdata; | 1454 | goto err_pdata; |
| 1408 | } | 1455 | } |
| 1409 | err = atmel_sha_dma_init(sha_dd, pdata); | 1456 | err = atmel_sha_dma_init(sha_dd, pdata); |
| 1410 | if (err) | 1457 | if (err) |
| 1411 | goto err_sha_dma; | 1458 | goto err_sha_dma; |
| 1459 | |||
| 1460 | dev_info(dev, "using %s for DMA transfers\n", | ||
| 1461 | dma_chan_name(sha_dd->dma_lch_in.chan)); | ||
| 1412 | } | 1462 | } |
| 1413 | 1463 | ||
| 1414 | spin_lock(&atmel_sha.lock); | 1464 | spin_lock(&atmel_sha.lock); |
| @@ -1419,7 +1469,9 @@ static int atmel_sha_probe(struct platform_device *pdev) | |||
| 1419 | if (err) | 1469 | if (err) |
| 1420 | goto err_algs; | 1470 | goto err_algs; |
| 1421 | 1471 | ||
| 1422 | dev_info(dev, "Atmel SHA1/SHA256\n"); | 1472 | dev_info(dev, "Atmel SHA1/SHA256%s%s\n", |
| 1473 | sha_dd->caps.has_sha224 ? "/SHA224" : "", | ||
| 1474 | sha_dd->caps.has_sha_384_512 ? "/SHA384/SHA512" : ""); | ||
| 1423 | 1475 | ||
| 1424 | return 0; | 1476 | return 0; |
| 1425 | 1477 | ||
| @@ -1483,6 +1535,7 @@ static struct platform_driver atmel_sha_driver = { | |||
| 1483 | .driver = { | 1535 | .driver = { |
| 1484 | .name = "atmel_sha", | 1536 | .name = "atmel_sha", |
| 1485 | .owner = THIS_MODULE, | 1537 | .owner = THIS_MODULE, |
| 1538 | .of_match_table = of_match_ptr(atmel_sha_dt_ids), | ||
| 1486 | }, | 1539 | }, |
| 1487 | }; | 1540 | }; |
| 1488 | 1541 | ||
diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c index 4a99564a08e6..6cde5b530c69 100644 --- a/drivers/crypto/atmel-tdes.c +++ b/drivers/crypto/atmel-tdes.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
| 31 | #include <linux/scatterlist.h> | 31 | #include <linux/scatterlist.h> |
| 32 | #include <linux/dma-mapping.h> | 32 | #include <linux/dma-mapping.h> |
| 33 | #include <linux/of_device.h> | ||
| 33 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
| 34 | #include <linux/crypto.h> | 35 | #include <linux/crypto.h> |
| 35 | #include <linux/cryptohash.h> | 36 | #include <linux/cryptohash.h> |
| @@ -716,59 +717,50 @@ static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd, | |||
| 716 | struct crypto_platform_data *pdata) | 717 | struct crypto_platform_data *pdata) |
| 717 | { | 718 | { |
| 718 | int err = -ENOMEM; | 719 | int err = -ENOMEM; |
| 719 | dma_cap_mask_t mask_in, mask_out; | 720 | dma_cap_mask_t mask; |
| 721 | |||
| 722 | dma_cap_zero(mask); | ||
| 723 | dma_cap_set(DMA_SLAVE, mask); | ||
| 724 | |||
| 725 | /* Try to grab 2 DMA channels */ | ||
| 726 | dd->dma_lch_in.chan = dma_request_slave_channel_compat(mask, | ||
| 727 | atmel_tdes_filter, &pdata->dma_slave->rxdata, dd->dev, "tx"); | ||
| 728 | if (!dd->dma_lch_in.chan) | ||
| 729 | goto err_dma_in; | ||
| 730 | |||
| 731 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; | ||
| 732 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
| 733 | TDES_IDATA1R; | ||
| 734 | dd->dma_lch_in.dma_conf.src_maxburst = 1; | ||
| 735 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
| 736 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 737 | dd->dma_lch_in.dma_conf.dst_maxburst = 1; | ||
| 738 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
| 739 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 740 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
| 741 | |||
| 742 | dd->dma_lch_out.chan = dma_request_slave_channel_compat(mask, | ||
| 743 | atmel_tdes_filter, &pdata->dma_slave->txdata, dd->dev, "rx"); | ||
| 744 | if (!dd->dma_lch_out.chan) | ||
| 745 | goto err_dma_out; | ||
| 746 | |||
| 747 | dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM; | ||
| 748 | dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + | ||
| 749 | TDES_ODATA1R; | ||
| 750 | dd->dma_lch_out.dma_conf.src_maxburst = 1; | ||
| 751 | dd->dma_lch_out.dma_conf.src_addr_width = | ||
| 752 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 753 | dd->dma_lch_out.dma_conf.dst_maxburst = 1; | ||
| 754 | dd->dma_lch_out.dma_conf.dst_addr_width = | ||
| 755 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 756 | dd->dma_lch_out.dma_conf.device_fc = false; | ||
| 720 | 757 | ||
| 721 | if (pdata && pdata->dma_slave->txdata.dma_dev && | 758 | return 0; |
| 722 | pdata->dma_slave->rxdata.dma_dev) { | ||
| 723 | |||
| 724 | /* Try to grab 2 DMA channels */ | ||
| 725 | dma_cap_zero(mask_in); | ||
| 726 | dma_cap_set(DMA_SLAVE, mask_in); | ||
| 727 | |||
| 728 | dd->dma_lch_in.chan = dma_request_channel(mask_in, | ||
| 729 | atmel_tdes_filter, &pdata->dma_slave->rxdata); | ||
| 730 | |||
| 731 | if (!dd->dma_lch_in.chan) | ||
| 732 | goto err_dma_in; | ||
| 733 | |||
| 734 | dd->dma_lch_in.dma_conf.direction = DMA_MEM_TO_DEV; | ||
| 735 | dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + | ||
| 736 | TDES_IDATA1R; | ||
| 737 | dd->dma_lch_in.dma_conf.src_maxburst = 1; | ||
| 738 | dd->dma_lch_in.dma_conf.src_addr_width = | ||
| 739 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 740 | dd->dma_lch_in.dma_conf.dst_maxburst = 1; | ||
| 741 | dd->dma_lch_in.dma_conf.dst_addr_width = | ||
| 742 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 743 | dd->dma_lch_in.dma_conf.device_fc = false; | ||
| 744 | |||
| 745 | dma_cap_zero(mask_out); | ||
| 746 | dma_cap_set(DMA_SLAVE, mask_out); | ||
| 747 | dd->dma_lch_out.chan = dma_request_channel(mask_out, | ||
| 748 | atmel_tdes_filter, &pdata->dma_slave->txdata); | ||
| 749 | |||
| 750 | if (!dd->dma_lch_out.chan) | ||
| 751 | goto err_dma_out; | ||
| 752 | |||
| 753 | dd->dma_lch_out.dma_conf.direction = DMA_DEV_TO_MEM; | ||
| 754 | dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + | ||
| 755 | TDES_ODATA1R; | ||
| 756 | dd->dma_lch_out.dma_conf.src_maxburst = 1; | ||
| 757 | dd->dma_lch_out.dma_conf.src_addr_width = | ||
| 758 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 759 | dd->dma_lch_out.dma_conf.dst_maxburst = 1; | ||
| 760 | dd->dma_lch_out.dma_conf.dst_addr_width = | ||
| 761 | DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
| 762 | dd->dma_lch_out.dma_conf.device_fc = false; | ||
| 763 | |||
| 764 | return 0; | ||
| 765 | } else { | ||
| 766 | return -ENODEV; | ||
| 767 | } | ||
| 768 | 759 | ||
| 769 | err_dma_out: | 760 | err_dma_out: |
| 770 | dma_release_channel(dd->dma_lch_in.chan); | 761 | dma_release_channel(dd->dma_lch_in.chan); |
| 771 | err_dma_in: | 762 | err_dma_in: |
| 763 | dev_warn(dd->dev, "no DMA channel available\n"); | ||
| 772 | return err; | 764 | return err; |
| 773 | } | 765 | } |
| 774 | 766 | ||
| @@ -1317,6 +1309,47 @@ static void atmel_tdes_get_cap(struct atmel_tdes_dev *dd) | |||
| 1317 | } | 1309 | } |
| 1318 | } | 1310 | } |
| 1319 | 1311 | ||
| 1312 | #if defined(CONFIG_OF) | ||
| 1313 | static const struct of_device_id atmel_tdes_dt_ids[] = { | ||
| 1314 | { .compatible = "atmel,at91sam9g46-tdes" }, | ||
| 1315 | { /* sentinel */ } | ||
| 1316 | }; | ||
| 1317 | MODULE_DEVICE_TABLE(of, atmel_tdes_dt_ids); | ||
| 1318 | |||
| 1319 | static struct crypto_platform_data *atmel_tdes_of_init(struct platform_device *pdev) | ||
| 1320 | { | ||
| 1321 | struct device_node *np = pdev->dev.of_node; | ||
| 1322 | struct crypto_platform_data *pdata; | ||
| 1323 | |||
| 1324 | if (!np) { | ||
| 1325 | dev_err(&pdev->dev, "device node not found\n"); | ||
| 1326 | return ERR_PTR(-EINVAL); | ||
| 1327 | } | ||
| 1328 | |||
| 1329 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
| 1330 | if (!pdata) { | ||
| 1331 | dev_err(&pdev->dev, "could not allocate memory for pdata\n"); | ||
| 1332 | return ERR_PTR(-ENOMEM); | ||
| 1333 | } | ||
| 1334 | |||
| 1335 | pdata->dma_slave = devm_kzalloc(&pdev->dev, | ||
| 1336 | sizeof(*(pdata->dma_slave)), | ||
| 1337 | GFP_KERNEL); | ||
| 1338 | if (!pdata->dma_slave) { | ||
| 1339 | dev_err(&pdev->dev, "could not allocate memory for dma_slave\n"); | ||
| 1340 | devm_kfree(&pdev->dev, pdata); | ||
| 1341 | return ERR_PTR(-ENOMEM); | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | return pdata; | ||
| 1345 | } | ||
| 1346 | #else /* CONFIG_OF */ | ||
| 1347 | static inline struct crypto_platform_data *atmel_tdes_of_init(struct platform_device *pdev) | ||
| 1348 | { | ||
| 1349 | return ERR_PTR(-EINVAL); | ||
| 1350 | } | ||
| 1351 | #endif | ||
| 1352 | |||
| 1320 | static int atmel_tdes_probe(struct platform_device *pdev) | 1353 | static int atmel_tdes_probe(struct platform_device *pdev) |
| 1321 | { | 1354 | { |
| 1322 | struct atmel_tdes_dev *tdes_dd; | 1355 | struct atmel_tdes_dev *tdes_dd; |
| @@ -1399,13 +1432,24 @@ static int atmel_tdes_probe(struct platform_device *pdev) | |||
| 1399 | if (tdes_dd->caps.has_dma) { | 1432 | if (tdes_dd->caps.has_dma) { |
| 1400 | pdata = pdev->dev.platform_data; | 1433 | pdata = pdev->dev.platform_data; |
| 1401 | if (!pdata) { | 1434 | if (!pdata) { |
| 1402 | dev_err(&pdev->dev, "platform data not available\n"); | 1435 | pdata = atmel_tdes_of_init(pdev); |
| 1436 | if (IS_ERR(pdata)) { | ||
| 1437 | dev_err(&pdev->dev, "platform data not available\n"); | ||
| 1438 | err = PTR_ERR(pdata); | ||
| 1439 | goto err_pdata; | ||
| 1440 | } | ||
| 1441 | } | ||
| 1442 | if (!pdata->dma_slave) { | ||
| 1403 | err = -ENXIO; | 1443 | err = -ENXIO; |
| 1404 | goto err_pdata; | 1444 | goto err_pdata; |
| 1405 | } | 1445 | } |
| 1406 | err = atmel_tdes_dma_init(tdes_dd, pdata); | 1446 | err = atmel_tdes_dma_init(tdes_dd, pdata); |
| 1407 | if (err) | 1447 | if (err) |
| 1408 | goto err_tdes_dma; | 1448 | goto err_tdes_dma; |
| 1449 | |||
| 1450 | dev_info(dev, "using %s, %s for DMA transfers\n", | ||
| 1451 | dma_chan_name(tdes_dd->dma_lch_in.chan), | ||
| 1452 | dma_chan_name(tdes_dd->dma_lch_out.chan)); | ||
| 1409 | } | 1453 | } |
| 1410 | 1454 | ||
| 1411 | spin_lock(&atmel_tdes.lock); | 1455 | spin_lock(&atmel_tdes.lock); |
| @@ -1487,6 +1531,7 @@ static struct platform_driver atmel_tdes_driver = { | |||
| 1487 | .driver = { | 1531 | .driver = { |
| 1488 | .name = "atmel_tdes", | 1532 | .name = "atmel_tdes", |
| 1489 | .owner = THIS_MODULE, | 1533 | .owner = THIS_MODULE, |
| 1534 | .of_match_table = of_match_ptr(atmel_tdes_dt_ids), | ||
| 1490 | }, | 1535 | }, |
| 1491 | }; | 1536 | }; |
| 1492 | 1537 | ||
