.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * This file is part of STM32 Crypto driver for Linux. |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2017, STMicroelectronics - All Rights Reserved |
---|
5 | 6 | * Author(s): Lionel DEBIEVE <lionel.debieve@st.com> for STMicroelectronics. |
---|
6 | | - * |
---|
7 | | - * License terms: GPL V2.0. |
---|
8 | | - * |
---|
9 | | - * This program is free software; you can redistribute it and/or modify it |
---|
10 | | - * under the terms of the GNU General Public License version 2 as published by |
---|
11 | | - * the Free Software Foundation. |
---|
12 | | - * |
---|
13 | | - * This program is distributed in the hope that it will be useful, but |
---|
14 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
15 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
---|
16 | | - * details. |
---|
17 | | - * |
---|
18 | | - * You should have received a copy of the GNU General Public License along with |
---|
19 | | - * this program. If not, see <http://www.gnu.org/licenses/>. |
---|
20 | | - * |
---|
21 | 7 | */ |
---|
22 | 8 | |
---|
23 | 9 | #include <linux/clk.h> |
---|
24 | 10 | #include <linux/crypto.h> |
---|
25 | 11 | #include <linux/delay.h> |
---|
| 12 | +#include <linux/dma-mapping.h> |
---|
26 | 13 | #include <linux/dmaengine.h> |
---|
27 | 14 | #include <linux/interrupt.h> |
---|
28 | 15 | #include <linux/io.h> |
---|
.. | .. |
---|
180 | 167 | phys_addr_t phys_base; |
---|
181 | 168 | u32 dma_mode; |
---|
182 | 169 | u32 dma_maxburst; |
---|
183 | | - |
---|
184 | | - spinlock_t lock; /* lock to protect queue */ |
---|
185 | 170 | |
---|
186 | 171 | struct ahash_request *req; |
---|
187 | 172 | struct crypto_engine *engine; |
---|
.. | .. |
---|
354 | 339 | |
---|
355 | 340 | len32 = DIV_ROUND_UP(length, sizeof(u32)); |
---|
356 | 341 | |
---|
357 | | - dev_dbg(hdev->dev, "%s: length: %d, final: %x len32 %i\n", |
---|
| 342 | + dev_dbg(hdev->dev, "%s: length: %zd, final: %x len32 %i\n", |
---|
358 | 343 | __func__, length, final, len32); |
---|
359 | 344 | |
---|
360 | 345 | hdev->flags |= HASH_FLAGS_CPU; |
---|
.. | .. |
---|
463 | 448 | |
---|
464 | 449 | dma_async_issue_pending(hdev->dma_lch); |
---|
465 | 450 | |
---|
466 | | - if (!wait_for_completion_interruptible_timeout(&hdev->dma_completion, |
---|
467 | | - msecs_to_jiffies(100))) |
---|
| 451 | + if (!wait_for_completion_timeout(&hdev->dma_completion, |
---|
| 452 | + msecs_to_jiffies(100))) |
---|
468 | 453 | err = -ETIMEDOUT; |
---|
469 | 454 | |
---|
470 | 455 | if (dma_async_is_tx_complete(hdev->dma_lch, cookie, |
---|
.. | .. |
---|
523 | 508 | static int stm32_hash_dma_init(struct stm32_hash_dev *hdev) |
---|
524 | 509 | { |
---|
525 | 510 | struct dma_slave_config dma_conf; |
---|
| 511 | + struct dma_chan *chan; |
---|
526 | 512 | int err; |
---|
527 | 513 | |
---|
528 | 514 | memset(&dma_conf, 0, sizeof(dma_conf)); |
---|
.. | .. |
---|
534 | 520 | dma_conf.dst_maxburst = hdev->dma_maxburst; |
---|
535 | 521 | dma_conf.device_fc = false; |
---|
536 | 522 | |
---|
537 | | - hdev->dma_lch = dma_request_slave_channel(hdev->dev, "in"); |
---|
538 | | - if (!hdev->dma_lch) { |
---|
539 | | - dev_err(hdev->dev, "Couldn't acquire a slave DMA channel.\n"); |
---|
540 | | - return -EBUSY; |
---|
541 | | - } |
---|
| 523 | + chan = dma_request_chan(hdev->dev, "in"); |
---|
| 524 | + if (IS_ERR(chan)) |
---|
| 525 | + return PTR_ERR(chan); |
---|
| 526 | + |
---|
| 527 | + hdev->dma_lch = chan; |
---|
542 | 528 | |
---|
543 | 529 | err = dmaengine_slave_config(hdev->dma_lch, &dma_conf); |
---|
544 | 530 | if (err) { |
---|
.. | .. |
---|
578 | 564 | } |
---|
579 | 565 | |
---|
580 | 566 | for_each_sg(rctx->sg, tsg, rctx->nents, i) { |
---|
| 567 | + sg[0] = *tsg; |
---|
581 | 568 | len = sg->length; |
---|
582 | 569 | |
---|
583 | | - sg[0] = *tsg; |
---|
584 | 570 | if (sg_is_last(sg)) { |
---|
585 | 571 | if (hdev->dma_mode == 1) { |
---|
586 | 572 | len = (ALIGN(sg->length, 16) - 16); |
---|
.. | .. |
---|
763 | 749 | static void stm32_hash_copy_hash(struct ahash_request *req) |
---|
764 | 750 | { |
---|
765 | 751 | struct stm32_hash_request_ctx *rctx = ahash_request_ctx(req); |
---|
766 | | - u32 *hash = (u32 *)rctx->digest; |
---|
| 752 | + __be32 *hash = (void *)rctx->digest; |
---|
767 | 753 | unsigned int i, hashsize; |
---|
768 | 754 | |
---|
769 | 755 | switch (rctx->flags & HASH_FLAGS_ALGO_MASK) { |
---|
.. | .. |
---|
784 | 770 | } |
---|
785 | 771 | |
---|
786 | 772 | for (i = 0; i < hashsize / sizeof(u32); i++) |
---|
787 | | - hash[i] = be32_to_cpu(stm32_hash_read(rctx->hdev, |
---|
| 773 | + hash[i] = cpu_to_be32(stm32_hash_read(rctx->hdev, |
---|
788 | 774 | HASH_HREG(i))); |
---|
789 | 775 | } |
---|
790 | 776 | |
---|
.. | .. |
---|
977 | 963 | |
---|
978 | 964 | pm_runtime_get_sync(hdev->dev); |
---|
979 | 965 | |
---|
980 | | - while (!(stm32_hash_read(hdev, HASH_SR) & HASH_SR_DATA_INPUT_READY)) |
---|
| 966 | + while ((stm32_hash_read(hdev, HASH_SR) & HASH_SR_BUSY)) |
---|
981 | 967 | cpu_relax(); |
---|
982 | 968 | |
---|
983 | 969 | rctx->hw_context = kmalloc_array(3 + HASH_CSR_REGISTER_NUMBER, |
---|
.. | .. |
---|
1466 | 1452 | return ret; |
---|
1467 | 1453 | |
---|
1468 | 1454 | irq = platform_get_irq(pdev, 0); |
---|
1469 | | - if (irq < 0) { |
---|
1470 | | - dev_err(dev, "Cannot get IRQ resource\n"); |
---|
| 1455 | + if (irq < 0) |
---|
1471 | 1456 | return irq; |
---|
1472 | | - } |
---|
1473 | 1457 | |
---|
1474 | 1458 | ret = devm_request_threaded_irq(dev, irq, stm32_hash_irq_handler, |
---|
1475 | 1459 | stm32_hash_irq_thread, IRQF_ONESHOT, |
---|
.. | .. |
---|
1480 | 1464 | } |
---|
1481 | 1465 | |
---|
1482 | 1466 | hdev->clk = devm_clk_get(&pdev->dev, NULL); |
---|
1483 | | - if (IS_ERR(hdev->clk)) { |
---|
1484 | | - dev_err(dev, "failed to get clock for hash (%lu)\n", |
---|
1485 | | - PTR_ERR(hdev->clk)); |
---|
1486 | | - return PTR_ERR(hdev->clk); |
---|
1487 | | - } |
---|
| 1467 | + if (IS_ERR(hdev->clk)) |
---|
| 1468 | + return dev_err_probe(dev, PTR_ERR(hdev->clk), |
---|
| 1469 | + "failed to get clock for hash\n"); |
---|
1488 | 1470 | |
---|
1489 | 1471 | ret = clk_prepare_enable(hdev->clk); |
---|
1490 | 1472 | if (ret) { |
---|
.. | .. |
---|
1500 | 1482 | pm_runtime_enable(dev); |
---|
1501 | 1483 | |
---|
1502 | 1484 | hdev->rst = devm_reset_control_get(&pdev->dev, NULL); |
---|
1503 | | - if (!IS_ERR(hdev->rst)) { |
---|
| 1485 | + if (IS_ERR(hdev->rst)) { |
---|
| 1486 | + if (PTR_ERR(hdev->rst) == -EPROBE_DEFER) { |
---|
| 1487 | + ret = -EPROBE_DEFER; |
---|
| 1488 | + goto err_reset; |
---|
| 1489 | + } |
---|
| 1490 | + } else { |
---|
1504 | 1491 | reset_control_assert(hdev->rst); |
---|
1505 | 1492 | udelay(2); |
---|
1506 | 1493 | reset_control_deassert(hdev->rst); |
---|
.. | .. |
---|
1511 | 1498 | platform_set_drvdata(pdev, hdev); |
---|
1512 | 1499 | |
---|
1513 | 1500 | ret = stm32_hash_dma_init(hdev); |
---|
1514 | | - if (ret) |
---|
| 1501 | + switch (ret) { |
---|
| 1502 | + case 0: |
---|
| 1503 | + break; |
---|
| 1504 | + case -ENOENT: |
---|
1515 | 1505 | dev_dbg(dev, "DMA mode not available\n"); |
---|
| 1506 | + break; |
---|
| 1507 | + default: |
---|
| 1508 | + goto err_dma; |
---|
| 1509 | + } |
---|
1516 | 1510 | |
---|
1517 | 1511 | spin_lock(&stm32_hash.lock); |
---|
1518 | 1512 | list_add_tail(&hdev->list, &stm32_hash.dev_list); |
---|
.. | .. |
---|
1550 | 1544 | spin_lock(&stm32_hash.lock); |
---|
1551 | 1545 | list_del(&hdev->list); |
---|
1552 | 1546 | spin_unlock(&stm32_hash.lock); |
---|
1553 | | - |
---|
| 1547 | +err_dma: |
---|
1554 | 1548 | if (hdev->dma_lch) |
---|
1555 | 1549 | dma_release_channel(hdev->dma_lch); |
---|
1556 | | - |
---|
| 1550 | +err_reset: |
---|
1557 | 1551 | pm_runtime_disable(dev); |
---|
1558 | 1552 | pm_runtime_put_noidle(dev); |
---|
1559 | 1553 | |
---|
.. | .. |
---|
1564 | 1558 | |
---|
1565 | 1559 | static int stm32_hash_remove(struct platform_device *pdev) |
---|
1566 | 1560 | { |
---|
1567 | | - static struct stm32_hash_dev *hdev; |
---|
| 1561 | + struct stm32_hash_dev *hdev; |
---|
1568 | 1562 | int ret; |
---|
1569 | 1563 | |
---|
1570 | 1564 | hdev = platform_get_drvdata(pdev); |
---|
.. | .. |
---|
1572 | 1566 | return -ENODEV; |
---|
1573 | 1567 | |
---|
1574 | 1568 | ret = pm_runtime_get_sync(hdev->dev); |
---|
1575 | | - if (ret < 0) |
---|
1576 | | - return ret; |
---|
1577 | 1569 | |
---|
1578 | 1570 | stm32_hash_unregister_algs(hdev); |
---|
1579 | 1571 | |
---|
.. | .. |
---|
1589 | 1581 | pm_runtime_disable(hdev->dev); |
---|
1590 | 1582 | pm_runtime_put_noidle(hdev->dev); |
---|
1591 | 1583 | |
---|
1592 | | - clk_disable_unprepare(hdev->clk); |
---|
| 1584 | + if (ret >= 0) |
---|
| 1585 | + clk_disable_unprepare(hdev->clk); |
---|
1593 | 1586 | |
---|
1594 | 1587 | return 0; |
---|
1595 | 1588 | } |
---|