.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2015-2016 Marvell International Ltd. |
---|
3 | 4 | |
---|
4 | | - * This program is free software: you can redistribute it and/or |
---|
5 | | - * modify it under the terms of the GNU General Public License as |
---|
6 | | - * published by the Free Software Foundation, either version 2 of the |
---|
7 | | - * License, or any later version. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope that it will be useful, but |
---|
10 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
12 | | - * General Public License for more details. |
---|
13 | 5 | */ |
---|
14 | 6 | |
---|
15 | 7 | #include <linux/clk.h> |
---|
.. | .. |
---|
41 | 33 | #define MV_XOR_V2_DMA_IMSG_CDAT_OFF 0x014 |
---|
42 | 34 | #define MV_XOR_V2_DMA_IMSG_THRD_OFF 0x018 |
---|
43 | 35 | #define MV_XOR_V2_DMA_IMSG_THRD_MASK 0x7FFF |
---|
44 | | -#define MV_XOR_V2_DMA_IMSG_THRD_SHIFT 0x0 |
---|
45 | 36 | #define MV_XOR_V2_DMA_IMSG_TIMER_EN BIT(18) |
---|
46 | 37 | #define MV_XOR_V2_DMA_DESQ_AWATTR_OFF 0x01C |
---|
47 | 38 | /* Same flags as MV_XOR_V2_DMA_DESQ_ARATTR_OFF */ |
---|
.. | .. |
---|
58 | 49 | #define MV_XOR_V2_DMA_DESQ_ADD_OFF 0x808 |
---|
59 | 50 | #define MV_XOR_V2_DMA_IMSG_TMOT 0x810 |
---|
60 | 51 | #define MV_XOR_V2_DMA_IMSG_TIMER_THRD_MASK 0x1FFF |
---|
61 | | -#define MV_XOR_V2_DMA_IMSG_TIMER_THRD_SHIFT 0 |
---|
62 | 52 | |
---|
63 | 53 | /* XOR Global registers */ |
---|
64 | 54 | #define MV_XOR_V2_GLOB_BW_CTRL 0x4 |
---|
.. | .. |
---|
145 | 135 | /** |
---|
146 | 136 | * struct mv_xor_v2_device - implements a xor device |
---|
147 | 137 | * @lock: lock for the engine |
---|
| 138 | + * @clk: reference to the 'core' clock |
---|
| 139 | + * @reg_clk: reference to the 'reg' clock |
---|
148 | 140 | * @dma_base: memory mapped DMA register base |
---|
149 | 141 | * @glob_base: memory mapped global register base |
---|
150 | | - * @irq_tasklet: |
---|
| 142 | + * @irq_tasklet: tasklet used for IRQ handling call-backs |
---|
151 | 143 | * @free_sw_desc: linked list of free SW descriptors |
---|
152 | 144 | * @dmadev: dma device |
---|
153 | 145 | * @dmachan: dma channel |
---|
.. | .. |
---|
156 | 148 | * @sw_desq: SW descriptors queue |
---|
157 | 149 | * @desc_size: HW descriptor size |
---|
158 | 150 | * @npendings: number of pending descriptors (for which tx_submit has |
---|
| 151 | + * @hw_queue_idx: HW queue index |
---|
| 152 | + * @msi_desc: local interrupt descriptor information |
---|
159 | 153 | * been called, but not yet issue_pending) |
---|
160 | 154 | */ |
---|
161 | 155 | struct mv_xor_v2_device { |
---|
.. | .. |
---|
269 | 263 | |
---|
270 | 264 | /* Configure threshold of number of descriptors, and enable timer */ |
---|
271 | 265 | reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_THRD_OFF); |
---|
272 | | - reg &= (~MV_XOR_V2_DMA_IMSG_THRD_MASK << MV_XOR_V2_DMA_IMSG_THRD_SHIFT); |
---|
273 | | - reg |= (MV_XOR_V2_DONE_IMSG_THRD << MV_XOR_V2_DMA_IMSG_THRD_SHIFT); |
---|
| 266 | + reg &= ~MV_XOR_V2_DMA_IMSG_THRD_MASK; |
---|
| 267 | + reg |= MV_XOR_V2_DONE_IMSG_THRD; |
---|
274 | 268 | reg |= MV_XOR_V2_DMA_IMSG_TIMER_EN; |
---|
275 | 269 | writel(reg, xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_THRD_OFF); |
---|
276 | 270 | |
---|
277 | 271 | /* Configure Timer Threshold */ |
---|
278 | 272 | reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_TMOT); |
---|
279 | | - reg &= (~MV_XOR_V2_DMA_IMSG_TIMER_THRD_MASK << |
---|
280 | | - MV_XOR_V2_DMA_IMSG_TIMER_THRD_SHIFT); |
---|
281 | | - reg |= (MV_XOR_V2_TIMER_THRD << MV_XOR_V2_DMA_IMSG_TIMER_THRD_SHIFT); |
---|
| 273 | + reg &= ~MV_XOR_V2_DMA_IMSG_TIMER_THRD_MASK; |
---|
| 274 | + reg |= MV_XOR_V2_TIMER_THRD; |
---|
282 | 275 | writel(reg, xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_TMOT); |
---|
283 | 276 | } |
---|
284 | 277 | |
---|
.. | .. |
---|
560 | 553 | /* |
---|
561 | 554 | * handle the descriptors after HW process |
---|
562 | 555 | */ |
---|
563 | | -static void mv_xor_v2_tasklet(unsigned long data) |
---|
| 556 | +static void mv_xor_v2_tasklet(struct tasklet_struct *t) |
---|
564 | 557 | { |
---|
565 | | - struct mv_xor_v2_device *xor_dev = (struct mv_xor_v2_device *) data; |
---|
| 558 | + struct mv_xor_v2_device *xor_dev = from_tasklet(xor_dev, t, |
---|
| 559 | + irq_tasklet); |
---|
566 | 560 | int pending_ptr, num_of_pending, i; |
---|
567 | 561 | struct mv_xor_v2_sw_desc *next_pending_sw_desc = NULL; |
---|
568 | 562 | |
---|
.. | .. |
---|
761 | 755 | } |
---|
762 | 756 | |
---|
763 | 757 | xor_dev->clk = devm_clk_get(&pdev->dev, NULL); |
---|
764 | | - if (IS_ERR(xor_dev->clk) && PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) { |
---|
765 | | - ret = EPROBE_DEFER; |
---|
| 758 | + if (PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) { |
---|
| 759 | + ret = -EPROBE_DEFER; |
---|
766 | 760 | goto disable_reg_clk; |
---|
767 | 761 | } |
---|
768 | 762 | if (!IS_ERR(xor_dev->clk)) { |
---|
.. | .. |
---|
789 | 783 | if (ret) |
---|
790 | 784 | goto free_msi_irqs; |
---|
791 | 785 | |
---|
792 | | - tasklet_init(&xor_dev->irq_tasklet, mv_xor_v2_tasklet, |
---|
793 | | - (unsigned long) xor_dev); |
---|
| 786 | + tasklet_setup(&xor_dev->irq_tasklet, mv_xor_v2_tasklet); |
---|
794 | 787 | |
---|
795 | 788 | xor_dev->desc_size = mv_xor_v2_set_desc_size(xor_dev); |
---|
796 | 789 | |
---|
.. | .. |
---|
906 | 899 | tasklet_kill(&xor_dev->irq_tasklet); |
---|
907 | 900 | |
---|
908 | 901 | clk_disable_unprepare(xor_dev->clk); |
---|
| 902 | + clk_disable_unprepare(xor_dev->reg_clk); |
---|
909 | 903 | |
---|
910 | 904 | return 0; |
---|
911 | 905 | } |
---|