.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2013-2014 Allwinner Tech Co., Ltd |
---|
3 | 4 | * Author: Sugar <shuge@allwinnertech.com> |
---|
4 | 5 | * |
---|
5 | 6 | * Copyright (C) 2014 Maxime Ripard |
---|
6 | 7 | * Maxime Ripard <maxime.ripard@free-electrons.com> |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify |
---|
9 | | - * it under the terms of the GNU General Public License as published by |
---|
10 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
11 | | - * (at your option) any later version. |
---|
12 | 8 | */ |
---|
13 | 9 | |
---|
14 | 10 | #include <linux/clk.h> |
---|
.. | .. |
---|
68 | 64 | #define DMA_CHAN_LLI_ADDR 0x08 |
---|
69 | 65 | |
---|
70 | 66 | #define DMA_CHAN_CUR_CFG 0x0c |
---|
71 | | -#define DMA_CHAN_MAX_DRQ 0x1f |
---|
72 | | -#define DMA_CHAN_CFG_SRC_DRQ(x) ((x) & DMA_CHAN_MAX_DRQ) |
---|
73 | | -#define DMA_CHAN_CFG_SRC_IO_MODE BIT(5) |
---|
74 | | -#define DMA_CHAN_CFG_SRC_LINEAR_MODE (0 << 5) |
---|
| 67 | +#define DMA_CHAN_MAX_DRQ_A31 0x1f |
---|
| 68 | +#define DMA_CHAN_MAX_DRQ_H6 0x3f |
---|
| 69 | +#define DMA_CHAN_CFG_SRC_DRQ_A31(x) ((x) & DMA_CHAN_MAX_DRQ_A31) |
---|
| 70 | +#define DMA_CHAN_CFG_SRC_DRQ_H6(x) ((x) & DMA_CHAN_MAX_DRQ_H6) |
---|
| 71 | +#define DMA_CHAN_CFG_SRC_MODE_A31(x) (((x) & 0x1) << 5) |
---|
| 72 | +#define DMA_CHAN_CFG_SRC_MODE_H6(x) (((x) & 0x1) << 8) |
---|
75 | 73 | #define DMA_CHAN_CFG_SRC_BURST_A31(x) (((x) & 0x3) << 7) |
---|
76 | 74 | #define DMA_CHAN_CFG_SRC_BURST_H3(x) (((x) & 0x3) << 6) |
---|
77 | 75 | #define DMA_CHAN_CFG_SRC_WIDTH(x) (((x) & 0x3) << 9) |
---|
78 | 76 | |
---|
79 | | -#define DMA_CHAN_CFG_DST_DRQ(x) (DMA_CHAN_CFG_SRC_DRQ(x) << 16) |
---|
80 | | -#define DMA_CHAN_CFG_DST_IO_MODE (DMA_CHAN_CFG_SRC_IO_MODE << 16) |
---|
81 | | -#define DMA_CHAN_CFG_DST_LINEAR_MODE (DMA_CHAN_CFG_SRC_LINEAR_MODE << 16) |
---|
| 77 | +#define DMA_CHAN_CFG_DST_DRQ_A31(x) (DMA_CHAN_CFG_SRC_DRQ_A31(x) << 16) |
---|
| 78 | +#define DMA_CHAN_CFG_DST_DRQ_H6(x) (DMA_CHAN_CFG_SRC_DRQ_H6(x) << 16) |
---|
| 79 | +#define DMA_CHAN_CFG_DST_MODE_A31(x) (DMA_CHAN_CFG_SRC_MODE_A31(x) << 16) |
---|
| 80 | +#define DMA_CHAN_CFG_DST_MODE_H6(x) (DMA_CHAN_CFG_SRC_MODE_H6(x) << 16) |
---|
82 | 81 | #define DMA_CHAN_CFG_DST_BURST_A31(x) (DMA_CHAN_CFG_SRC_BURST_A31(x) << 16) |
---|
83 | 82 | #define DMA_CHAN_CFG_DST_BURST_H3(x) (DMA_CHAN_CFG_SRC_BURST_H3(x) << 16) |
---|
84 | 83 | #define DMA_CHAN_CFG_DST_WIDTH(x) (DMA_CHAN_CFG_SRC_WIDTH(x) << 16) |
---|
.. | .. |
---|
98 | 97 | #define LLI_LAST_ITEM 0xfffff800 |
---|
99 | 98 | #define NORMAL_WAIT 8 |
---|
100 | 99 | #define DRQ_SDRAM 1 |
---|
| 100 | +#define LINEAR_MODE 0 |
---|
| 101 | +#define IO_MODE 1 |
---|
101 | 102 | |
---|
102 | 103 | /* forward declaration */ |
---|
103 | 104 | struct sun6i_dma_dev; |
---|
.. | .. |
---|
125 | 126 | */ |
---|
126 | 127 | void (*clock_autogate_enable)(struct sun6i_dma_dev *); |
---|
127 | 128 | void (*set_burst_length)(u32 *p_cfg, s8 src_burst, s8 dst_burst); |
---|
| 129 | + void (*set_drq)(u32 *p_cfg, s8 src_drq, s8 dst_drq); |
---|
| 130 | + void (*set_mode)(u32 *p_cfg, s8 src_mode, s8 dst_mode); |
---|
128 | 131 | u32 src_burst_lengths; |
---|
129 | 132 | u32 dst_burst_lengths; |
---|
130 | 133 | u32 src_addr_widths; |
---|
131 | 134 | u32 dst_addr_widths; |
---|
| 135 | + bool has_mbus_clk; |
---|
132 | 136 | }; |
---|
133 | 137 | |
---|
134 | 138 | /* |
---|
.. | .. |
---|
182 | 186 | struct dma_device slave; |
---|
183 | 187 | void __iomem *base; |
---|
184 | 188 | struct clk *clk; |
---|
| 189 | + struct clk *clk_mbus; |
---|
185 | 190 | int irq; |
---|
186 | 191 | spinlock_t lock; |
---|
187 | 192 | struct reset_control *rstc; |
---|
.. | .. |
---|
307 | 312 | { |
---|
308 | 313 | *p_cfg |= DMA_CHAN_CFG_SRC_BURST_H3(src_burst) | |
---|
309 | 314 | DMA_CHAN_CFG_DST_BURST_H3(dst_burst); |
---|
| 315 | +} |
---|
| 316 | + |
---|
| 317 | +static void sun6i_set_drq_a31(u32 *p_cfg, s8 src_drq, s8 dst_drq) |
---|
| 318 | +{ |
---|
| 319 | + *p_cfg |= DMA_CHAN_CFG_SRC_DRQ_A31(src_drq) | |
---|
| 320 | + DMA_CHAN_CFG_DST_DRQ_A31(dst_drq); |
---|
| 321 | +} |
---|
| 322 | + |
---|
| 323 | +static void sun6i_set_drq_h6(u32 *p_cfg, s8 src_drq, s8 dst_drq) |
---|
| 324 | +{ |
---|
| 325 | + *p_cfg |= DMA_CHAN_CFG_SRC_DRQ_H6(src_drq) | |
---|
| 326 | + DMA_CHAN_CFG_DST_DRQ_H6(dst_drq); |
---|
| 327 | +} |
---|
| 328 | + |
---|
| 329 | +static void sun6i_set_mode_a31(u32 *p_cfg, s8 src_mode, s8 dst_mode) |
---|
| 330 | +{ |
---|
| 331 | + *p_cfg |= DMA_CHAN_CFG_SRC_MODE_A31(src_mode) | |
---|
| 332 | + DMA_CHAN_CFG_DST_MODE_A31(dst_mode); |
---|
| 333 | +} |
---|
| 334 | + |
---|
| 335 | +static void sun6i_set_mode_h6(u32 *p_cfg, s8 src_mode, s8 dst_mode) |
---|
| 336 | +{ |
---|
| 337 | + *p_cfg |= DMA_CHAN_CFG_SRC_MODE_H6(src_mode) | |
---|
| 338 | + DMA_CHAN_CFG_DST_MODE_H6(dst_mode); |
---|
310 | 339 | } |
---|
311 | 340 | |
---|
312 | 341 | static size_t sun6i_get_chan_size(struct sun6i_pchan *pchan) |
---|
.. | .. |
---|
438 | 467 | return 0; |
---|
439 | 468 | } |
---|
440 | 469 | |
---|
441 | | -static void sun6i_dma_tasklet(unsigned long data) |
---|
| 470 | +static void sun6i_dma_tasklet(struct tasklet_struct *t) |
---|
442 | 471 | { |
---|
443 | | - struct sun6i_dma_dev *sdev = (struct sun6i_dma_dev *)data; |
---|
| 472 | + struct sun6i_dma_dev *sdev = from_tasklet(sdev, t, task); |
---|
444 | 473 | struct sun6i_vchan *vchan; |
---|
445 | 474 | struct sun6i_pchan *pchan; |
---|
446 | 475 | unsigned int pchan_alloc = 0; |
---|
.. | .. |
---|
632 | 661 | |
---|
633 | 662 | burst = convert_burst(8); |
---|
634 | 663 | width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES); |
---|
635 | | - v_lli->cfg = DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | |
---|
636 | | - DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | |
---|
637 | | - DMA_CHAN_CFG_DST_LINEAR_MODE | |
---|
638 | | - DMA_CHAN_CFG_SRC_LINEAR_MODE | |
---|
639 | | - DMA_CHAN_CFG_SRC_WIDTH(width) | |
---|
| 664 | + v_lli->cfg = DMA_CHAN_CFG_SRC_WIDTH(width) | |
---|
640 | 665 | DMA_CHAN_CFG_DST_WIDTH(width); |
---|
641 | 666 | |
---|
642 | 667 | sdev->cfg->set_burst_length(&v_lli->cfg, burst, burst); |
---|
| 668 | + sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, DRQ_SDRAM); |
---|
| 669 | + sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, LINEAR_MODE); |
---|
643 | 670 | |
---|
644 | 671 | sun6i_dma_lli_add(NULL, v_lli, p_lli, txd); |
---|
645 | 672 | |
---|
.. | .. |
---|
691 | 718 | if (dir == DMA_MEM_TO_DEV) { |
---|
692 | 719 | v_lli->src = sg_dma_address(sg); |
---|
693 | 720 | v_lli->dst = sconfig->dst_addr; |
---|
694 | | - v_lli->cfg = lli_cfg | |
---|
695 | | - DMA_CHAN_CFG_DST_IO_MODE | |
---|
696 | | - DMA_CHAN_CFG_SRC_LINEAR_MODE | |
---|
697 | | - DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | |
---|
698 | | - DMA_CHAN_CFG_DST_DRQ(vchan->port); |
---|
| 721 | + v_lli->cfg = lli_cfg; |
---|
| 722 | + sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); |
---|
| 723 | + sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE); |
---|
699 | 724 | |
---|
700 | 725 | dev_dbg(chan2dev(chan), |
---|
701 | 726 | "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", |
---|
.. | .. |
---|
706 | 731 | } else { |
---|
707 | 732 | v_lli->src = sconfig->src_addr; |
---|
708 | 733 | v_lli->dst = sg_dma_address(sg); |
---|
709 | | - v_lli->cfg = lli_cfg | |
---|
710 | | - DMA_CHAN_CFG_DST_LINEAR_MODE | |
---|
711 | | - DMA_CHAN_CFG_SRC_IO_MODE | |
---|
712 | | - DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | |
---|
713 | | - DMA_CHAN_CFG_SRC_DRQ(vchan->port); |
---|
| 734 | + v_lli->cfg = lli_cfg; |
---|
| 735 | + sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); |
---|
| 736 | + sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE); |
---|
714 | 737 | |
---|
715 | 738 | dev_dbg(chan2dev(chan), |
---|
716 | 739 | "%s; chan: %d, dest: %pad, src: %pad, len: %u. flags: 0x%08lx\n", |
---|
.. | .. |
---|
776 | 799 | if (dir == DMA_MEM_TO_DEV) { |
---|
777 | 800 | v_lli->src = buf_addr + period_len * i; |
---|
778 | 801 | v_lli->dst = sconfig->dst_addr; |
---|
779 | | - v_lli->cfg = lli_cfg | |
---|
780 | | - DMA_CHAN_CFG_DST_IO_MODE | |
---|
781 | | - DMA_CHAN_CFG_SRC_LINEAR_MODE | |
---|
782 | | - DMA_CHAN_CFG_SRC_DRQ(DRQ_SDRAM) | |
---|
783 | | - DMA_CHAN_CFG_DST_DRQ(vchan->port); |
---|
| 802 | + v_lli->cfg = lli_cfg; |
---|
| 803 | + sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); |
---|
| 804 | + sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE); |
---|
784 | 805 | } else { |
---|
785 | 806 | v_lli->src = sconfig->src_addr; |
---|
786 | 807 | v_lli->dst = buf_addr + period_len * i; |
---|
787 | | - v_lli->cfg = lli_cfg | |
---|
788 | | - DMA_CHAN_CFG_DST_LINEAR_MODE | |
---|
789 | | - DMA_CHAN_CFG_SRC_IO_MODE | |
---|
790 | | - DMA_CHAN_CFG_DST_DRQ(DRQ_SDRAM) | |
---|
791 | | - DMA_CHAN_CFG_SRC_DRQ(vchan->port); |
---|
| 808 | + v_lli->cfg = lli_cfg; |
---|
| 809 | + sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); |
---|
| 810 | + sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE); |
---|
792 | 811 | } |
---|
793 | 812 | |
---|
794 | 813 | prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd); |
---|
.. | .. |
---|
1053 | 1072 | .nr_max_requests = 30, |
---|
1054 | 1073 | .nr_max_vchans = 53, |
---|
1055 | 1074 | .set_burst_length = sun6i_set_burst_length_a31, |
---|
| 1075 | + .set_drq = sun6i_set_drq_a31, |
---|
| 1076 | + .set_mode = sun6i_set_mode_a31, |
---|
1056 | 1077 | .src_burst_lengths = BIT(1) | BIT(8), |
---|
1057 | 1078 | .dst_burst_lengths = BIT(1) | BIT(8), |
---|
1058 | 1079 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
---|
.. | .. |
---|
1074 | 1095 | .nr_max_vchans = 37, |
---|
1075 | 1096 | .clock_autogate_enable = sun6i_enable_clock_autogate_a23, |
---|
1076 | 1097 | .set_burst_length = sun6i_set_burst_length_a31, |
---|
| 1098 | + .set_drq = sun6i_set_drq_a31, |
---|
| 1099 | + .set_mode = sun6i_set_mode_a31, |
---|
1077 | 1100 | .src_burst_lengths = BIT(1) | BIT(8), |
---|
1078 | 1101 | .dst_burst_lengths = BIT(1) | BIT(8), |
---|
1079 | 1102 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
---|
.. | .. |
---|
1090 | 1113 | .nr_max_vchans = 39, |
---|
1091 | 1114 | .clock_autogate_enable = sun6i_enable_clock_autogate_a23, |
---|
1092 | 1115 | .set_burst_length = sun6i_set_burst_length_a31, |
---|
| 1116 | + .set_drq = sun6i_set_drq_a31, |
---|
| 1117 | + .set_mode = sun6i_set_mode_a31, |
---|
1093 | 1118 | .src_burst_lengths = BIT(1) | BIT(8), |
---|
1094 | 1119 | .dst_burst_lengths = BIT(1) | BIT(8), |
---|
1095 | 1120 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
---|
.. | .. |
---|
1113 | 1138 | .nr_max_vchans = 34, |
---|
1114 | 1139 | .clock_autogate_enable = sun6i_enable_clock_autogate_h3, |
---|
1115 | 1140 | .set_burst_length = sun6i_set_burst_length_h3, |
---|
| 1141 | + .set_drq = sun6i_set_drq_a31, |
---|
| 1142 | + .set_mode = sun6i_set_mode_a31, |
---|
1116 | 1143 | .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
---|
1117 | 1144 | .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
---|
1118 | 1145 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
---|
.. | .. |
---|
1132 | 1159 | static struct sun6i_dma_config sun50i_a64_dma_cfg = { |
---|
1133 | 1160 | .clock_autogate_enable = sun6i_enable_clock_autogate_h3, |
---|
1134 | 1161 | .set_burst_length = sun6i_set_burst_length_h3, |
---|
| 1162 | + .set_drq = sun6i_set_drq_a31, |
---|
| 1163 | + .set_mode = sun6i_set_mode_a31, |
---|
1135 | 1164 | .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
---|
1136 | 1165 | .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
---|
1137 | 1166 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
---|
.. | .. |
---|
1145 | 1174 | }; |
---|
1146 | 1175 | |
---|
1147 | 1176 | /* |
---|
| 1177 | + * The H6 binding uses the number of dma channels from the |
---|
| 1178 | + * device tree node. |
---|
| 1179 | + */ |
---|
| 1180 | +static struct sun6i_dma_config sun50i_h6_dma_cfg = { |
---|
| 1181 | + .clock_autogate_enable = sun6i_enable_clock_autogate_h3, |
---|
| 1182 | + .set_burst_length = sun6i_set_burst_length_h3, |
---|
| 1183 | + .set_drq = sun6i_set_drq_h6, |
---|
| 1184 | + .set_mode = sun6i_set_mode_h6, |
---|
| 1185 | + .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
---|
| 1186 | + .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16), |
---|
| 1187 | + .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
---|
| 1188 | + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | |
---|
| 1189 | + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | |
---|
| 1190 | + BIT(DMA_SLAVE_BUSWIDTH_8_BYTES), |
---|
| 1191 | + .dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
---|
| 1192 | + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | |
---|
| 1193 | + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | |
---|
| 1194 | + BIT(DMA_SLAVE_BUSWIDTH_8_BYTES), |
---|
| 1195 | + .has_mbus_clk = true, |
---|
| 1196 | +}; |
---|
| 1197 | + |
---|
| 1198 | +/* |
---|
1148 | 1199 | * The V3s have only 8 physical channels, a maximum DRQ port id of 23, |
---|
1149 | 1200 | * and a total of 24 usable source and destination endpoints. |
---|
1150 | 1201 | */ |
---|
.. | .. |
---|
1155 | 1206 | .nr_max_vchans = 24, |
---|
1156 | 1207 | .clock_autogate_enable = sun6i_enable_clock_autogate_a23, |
---|
1157 | 1208 | .set_burst_length = sun6i_set_burst_length_a31, |
---|
| 1209 | + .set_drq = sun6i_set_drq_a31, |
---|
| 1210 | + .set_mode = sun6i_set_mode_a31, |
---|
1158 | 1211 | .src_burst_lengths = BIT(1) | BIT(8), |
---|
1159 | 1212 | .dst_burst_lengths = BIT(1) | BIT(8), |
---|
1160 | 1213 | .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | |
---|
.. | .. |
---|
1172 | 1225 | { .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg }, |
---|
1173 | 1226 | { .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg }, |
---|
1174 | 1227 | { .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg }, |
---|
| 1228 | + { .compatible = "allwinner,sun50i-h6-dma", .data = &sun50i_h6_dma_cfg }, |
---|
1175 | 1229 | { /* sentinel */ } |
---|
1176 | 1230 | }; |
---|
1177 | 1231 | MODULE_DEVICE_TABLE(of, sun6i_dma_match); |
---|
.. | .. |
---|
1197 | 1251 | return PTR_ERR(sdc->base); |
---|
1198 | 1252 | |
---|
1199 | 1253 | sdc->irq = platform_get_irq(pdev, 0); |
---|
1200 | | - if (sdc->irq < 0) { |
---|
1201 | | - dev_err(&pdev->dev, "Cannot claim IRQ\n"); |
---|
| 1254 | + if (sdc->irq < 0) |
---|
1202 | 1255 | return sdc->irq; |
---|
1203 | | - } |
---|
1204 | 1256 | |
---|
1205 | 1257 | sdc->clk = devm_clk_get(&pdev->dev, NULL); |
---|
1206 | 1258 | if (IS_ERR(sdc->clk)) { |
---|
1207 | 1259 | dev_err(&pdev->dev, "No clock specified\n"); |
---|
1208 | 1260 | return PTR_ERR(sdc->clk); |
---|
| 1261 | + } |
---|
| 1262 | + |
---|
| 1263 | + if (sdc->cfg->has_mbus_clk) { |
---|
| 1264 | + sdc->clk_mbus = devm_clk_get(&pdev->dev, "mbus"); |
---|
| 1265 | + if (IS_ERR(sdc->clk_mbus)) { |
---|
| 1266 | + dev_err(&pdev->dev, "No mbus clock specified\n"); |
---|
| 1267 | + return PTR_ERR(sdc->clk_mbus); |
---|
| 1268 | + } |
---|
1209 | 1269 | } |
---|
1210 | 1270 | |
---|
1211 | 1271 | sdc->rstc = devm_reset_control_get(&pdev->dev, NULL); |
---|
.. | .. |
---|
1262 | 1322 | ret = of_property_read_u32(np, "dma-requests", &sdc->max_request); |
---|
1263 | 1323 | if (ret && !sdc->max_request) { |
---|
1264 | 1324 | dev_info(&pdev->dev, "Missing dma-requests, using %u.\n", |
---|
1265 | | - DMA_CHAN_MAX_DRQ); |
---|
1266 | | - sdc->max_request = DMA_CHAN_MAX_DRQ; |
---|
| 1325 | + DMA_CHAN_MAX_DRQ_A31); |
---|
| 1326 | + sdc->max_request = DMA_CHAN_MAX_DRQ_A31; |
---|
1267 | 1327 | } |
---|
1268 | 1328 | |
---|
1269 | 1329 | /* |
---|
.. | .. |
---|
1283 | 1343 | if (!sdc->vchans) |
---|
1284 | 1344 | return -ENOMEM; |
---|
1285 | 1345 | |
---|
1286 | | - tasklet_init(&sdc->task, sun6i_dma_tasklet, (unsigned long)sdc); |
---|
| 1346 | + tasklet_setup(&sdc->task, sun6i_dma_tasklet); |
---|
1287 | 1347 | |
---|
1288 | 1348 | for (i = 0; i < sdc->num_pchans; i++) { |
---|
1289 | 1349 | struct sun6i_pchan *pchan = &sdc->pchans[i]; |
---|
.. | .. |
---|
1312 | 1372 | goto err_reset_assert; |
---|
1313 | 1373 | } |
---|
1314 | 1374 | |
---|
| 1375 | + if (sdc->cfg->has_mbus_clk) { |
---|
| 1376 | + ret = clk_prepare_enable(sdc->clk_mbus); |
---|
| 1377 | + if (ret) { |
---|
| 1378 | + dev_err(&pdev->dev, "Couldn't enable mbus clock\n"); |
---|
| 1379 | + goto err_clk_disable; |
---|
| 1380 | + } |
---|
| 1381 | + } |
---|
| 1382 | + |
---|
1315 | 1383 | ret = devm_request_irq(&pdev->dev, sdc->irq, sun6i_dma_interrupt, 0, |
---|
1316 | 1384 | dev_name(&pdev->dev), sdc); |
---|
1317 | 1385 | if (ret) { |
---|
1318 | 1386 | dev_err(&pdev->dev, "Cannot request IRQ\n"); |
---|
1319 | | - goto err_clk_disable; |
---|
| 1387 | + goto err_mbus_clk_disable; |
---|
1320 | 1388 | } |
---|
1321 | 1389 | |
---|
1322 | 1390 | ret = dma_async_device_register(&sdc->slave); |
---|
.. | .. |
---|
1341 | 1409 | dma_async_device_unregister(&sdc->slave); |
---|
1342 | 1410 | err_irq_disable: |
---|
1343 | 1411 | sun6i_kill_tasklet(sdc); |
---|
| 1412 | +err_mbus_clk_disable: |
---|
| 1413 | + clk_disable_unprepare(sdc->clk_mbus); |
---|
1344 | 1414 | err_clk_disable: |
---|
1345 | 1415 | clk_disable_unprepare(sdc->clk); |
---|
1346 | 1416 | err_reset_assert: |
---|
.. | .. |
---|
1359 | 1429 | |
---|
1360 | 1430 | sun6i_kill_tasklet(sdc); |
---|
1361 | 1431 | |
---|
| 1432 | + clk_disable_unprepare(sdc->clk_mbus); |
---|
1362 | 1433 | clk_disable_unprepare(sdc->clk); |
---|
1363 | 1434 | reset_control_assert(sdc->rstc); |
---|
1364 | 1435 | |
---|