Lines Matching +full:sun4i +full:- +full:a10 +full:- +full:spi
1 // SPDX-License-Identifier: GPL-2.0-or-later
19 #include "virt-dma.h"
74 #define SUN4I_DDMA_PARA_DST_DATA_BLK_SIZE(n) (((n) - 1) << 24)
75 #define SUN4I_DDMA_PARA_DST_WAIT_CYCLES(n) (((n) - 1) << 16)
76 #define SUN4I_DDMA_PARA_SRC_DATA_BLK_SIZE(n) (((n) - 1) << 8)
77 #define SUN4I_DDMA_PARA_SRC_WAIT_CYCLES(n) (((n) - 1) << 0)
112 #define SUN4I_NDMA_NR_MAX_VCHANS (29 * 2 - 1)
118 * working with the SPI driver and seem to make it behave correctly */
189 return &chan->dev->device; in chan2dev()
195 return -EINVAL; in convert_burst()
197 /* 1 -> 0, 4 -> 1, 8 -> 2 */ in convert_burst()
204 return -EINVAL; in convert_buswidth()
206 /* 8 (1 byte) -> 0, 16 (2 bytes) -> 1, 32 (4 bytes) -> 2 */ in convert_buswidth()
214 vchan_free_chan_resources(&vchan->vc); in sun4i_dma_free_chan_resources()
220 struct sun4i_dma_pchan *pchan = NULL, *pchans = priv->pchans; in find_and_use_pchan()
225 * pchans 0-SUN4I_NDMA_NR_MAX_CHANNELS are normal, and in find_and_use_pchan()
228 if (vchan->is_dedicated) { in find_and_use_pchan()
236 spin_lock_irqsave(&priv->lock, flags); in find_and_use_pchan()
237 for_each_clear_bit_from(i, priv->pchans_used, max) { in find_and_use_pchan()
239 pchan->vchan = vchan; in find_and_use_pchan()
240 set_bit(i, priv->pchans_used); in find_and_use_pchan()
243 spin_unlock_irqrestore(&priv->lock, flags); in find_and_use_pchan()
252 int nr = pchan - priv->pchans; in release_pchan()
254 spin_lock_irqsave(&priv->lock, flags); in release_pchan()
256 pchan->vchan = NULL; in release_pchan()
257 clear_bit(nr, priv->pchans_used); in release_pchan()
259 spin_unlock_irqrestore(&priv->lock, flags); in release_pchan()
269 if (pchan->is_dedicated) { in configure_pchan()
270 writel_relaxed(d->src, pchan->base + SUN4I_DDMA_SRC_ADDR_REG); in configure_pchan()
271 writel_relaxed(d->dst, pchan->base + SUN4I_DDMA_DST_ADDR_REG); in configure_pchan()
272 writel_relaxed(d->len, pchan->base + SUN4I_DDMA_BYTE_COUNT_REG); in configure_pchan()
273 writel_relaxed(d->para, pchan->base + SUN4I_DDMA_PARA_REG); in configure_pchan()
274 writel_relaxed(d->cfg, pchan->base + SUN4I_DDMA_CFG_REG); in configure_pchan()
276 writel_relaxed(d->src, pchan->base + SUN4I_NDMA_SRC_ADDR_REG); in configure_pchan()
277 writel_relaxed(d->dst, pchan->base + SUN4I_NDMA_DST_ADDR_REG); in configure_pchan()
278 writel_relaxed(d->len, pchan->base + SUN4I_NDMA_BYTE_COUNT_REG); in configure_pchan()
279 writel_relaxed(d->cfg, pchan->base + SUN4I_NDMA_CFG_REG); in configure_pchan()
288 int pchan_number = pchan - priv->pchans; in set_pchan_interrupt()
291 spin_lock_irqsave(&priv->lock, flags); in set_pchan_interrupt()
293 reg = readl_relaxed(priv->base + SUN4I_DMA_IRQ_ENABLE_REG); in set_pchan_interrupt()
305 writel_relaxed(reg, priv->base + SUN4I_DMA_IRQ_ENABLE_REG); in set_pchan_interrupt()
307 spin_unlock_irqrestore(&priv->lock, flags); in set_pchan_interrupt()
317 * This function must be called with &vchan->vc.lock held.
328 lockdep_assert_held(&vchan->vc.lock); in __execute_vchan_pending()
333 return -EBUSY; in __execute_vchan_pending()
339 if (vchan->processing) { in __execute_vchan_pending()
340 dev_dbg(chan2dev(&vchan->vc.chan), in __execute_vchan_pending()
342 ret = -EBUSY; in __execute_vchan_pending()
348 vd = vchan_next_desc(&vchan->vc); in __execute_vchan_pending()
350 dev_dbg(chan2dev(&vchan->vc.chan), in __execute_vchan_pending()
357 if (list_empty(&contract->demands)) { in __execute_vchan_pending()
359 list_del(&contract->vd.node); in __execute_vchan_pending()
360 vchan_cookie_complete(&contract->vd); in __execute_vchan_pending()
361 dev_dbg(chan2dev(&vchan->vc.chan), in __execute_vchan_pending()
364 } while (list_empty(&contract->demands)); in __execute_vchan_pending()
367 promise = list_first_entry(&contract->demands, in __execute_vchan_pending()
369 vchan->processing = promise; in __execute_vchan_pending()
373 vchan->contract = contract; in __execute_vchan_pending()
374 vchan->pchan = pchan; in __execute_vchan_pending()
375 set_pchan_interrupt(priv, pchan, contract->is_cyclic, 1); in __execute_vchan_pending()
391 if ((sconfig->dst_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) || in sanitize_config()
392 !sconfig->dst_maxburst) in sanitize_config()
393 return -EINVAL; in sanitize_config()
395 if (sconfig->src_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) in sanitize_config()
396 sconfig->src_addr_width = sconfig->dst_addr_width; in sanitize_config()
398 if (!sconfig->src_maxburst) in sanitize_config()
399 sconfig->src_maxburst = sconfig->dst_maxburst; in sanitize_config()
404 if ((sconfig->src_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) || in sanitize_config()
405 !sconfig->src_maxburst) in sanitize_config()
406 return -EINVAL; in sanitize_config()
408 if (sconfig->dst_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) in sanitize_config()
409 sconfig->dst_addr_width = sconfig->src_addr_width; in sanitize_config()
411 if (!sconfig->dst_maxburst) in sanitize_config()
412 sconfig->dst_maxburst = sconfig->src_maxburst; in sanitize_config()
426 * normal part of the DMA Engine and get data copied. A non-executed
447 promise->src = src; in generate_ndma_promise()
448 promise->dst = dest; in generate_ndma_promise()
449 promise->len = len; in generate_ndma_promise()
450 promise->cfg = SUN4I_DMA_CFG_LOADING | in generate_ndma_promise()
455 sconfig->src_maxburst, sconfig->dst_maxburst, in generate_ndma_promise()
456 sconfig->src_addr_width, sconfig->dst_addr_width); in generate_ndma_promise()
459 ret = convert_burst(sconfig->src_maxburst); in generate_ndma_promise()
462 promise->cfg |= SUN4I_DMA_CFG_SRC_BURST_LENGTH(ret); in generate_ndma_promise()
465 ret = convert_burst(sconfig->dst_maxburst); in generate_ndma_promise()
468 promise->cfg |= SUN4I_DMA_CFG_DST_BURST_LENGTH(ret); in generate_ndma_promise()
471 ret = convert_buswidth(sconfig->src_addr_width); in generate_ndma_promise()
474 promise->cfg |= SUN4I_DMA_CFG_SRC_DATA_WIDTH(ret); in generate_ndma_promise()
477 ret = convert_buswidth(sconfig->dst_addr_width); in generate_ndma_promise()
480 promise->cfg |= SUN4I_DMA_CFG_DST_DATA_WIDTH(ret); in generate_ndma_promise()
493 * Dedicated part of the DMA Engine and get data copied. A non-executed
509 promise->src = src; in generate_ddma_promise()
510 promise->dst = dest; in generate_ddma_promise()
511 promise->len = len; in generate_ddma_promise()
512 promise->cfg = SUN4I_DMA_CFG_LOADING | in generate_ddma_promise()
516 ret = convert_burst(sconfig->src_maxburst); in generate_ddma_promise()
519 promise->cfg |= SUN4I_DMA_CFG_SRC_BURST_LENGTH(ret); in generate_ddma_promise()
522 ret = convert_burst(sconfig->dst_maxburst); in generate_ddma_promise()
525 promise->cfg |= SUN4I_DMA_CFG_DST_BURST_LENGTH(ret); in generate_ddma_promise()
528 ret = convert_buswidth(sconfig->src_addr_width); in generate_ddma_promise()
531 promise->cfg |= SUN4I_DMA_CFG_SRC_DATA_WIDTH(ret); in generate_ddma_promise()
534 ret = convert_buswidth(sconfig->dst_addr_width); in generate_ddma_promise()
537 promise->cfg |= SUN4I_DMA_CFG_DST_DATA_WIDTH(ret); in generate_ddma_promise()
562 INIT_LIST_HEAD(&contract->demands); in generate_dma_contract()
563 INIT_LIST_HEAD(&contract->completed_demands); in generate_dma_contract()
580 promise = list_first_entry_or_null(&contract->demands, in get_next_cyclic_promise()
583 list_splice_init(&contract->completed_demands, in get_next_cyclic_promise()
584 &contract->demands); in get_next_cyclic_promise()
585 promise = list_first_entry(&contract->demands, in get_next_cyclic_promise()
601 list_for_each_entry_safe(promise, tmp, &contract->demands, list) in sun4i_dma_free_contract()
604 list_for_each_entry_safe(promise, tmp, &contract->completed_demands, list) in sun4i_dma_free_contract()
615 struct dma_slave_config *sconfig = &vchan->cfg; in sun4i_dma_prep_dma_memcpy()
628 sconfig->src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; in sun4i_dma_prep_dma_memcpy()
629 sconfig->dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; in sun4i_dma_prep_dma_memcpy()
630 sconfig->src_maxburst = 8; in sun4i_dma_prep_dma_memcpy()
631 sconfig->dst_maxburst = 8; in sun4i_dma_prep_dma_memcpy()
633 if (vchan->is_dedicated) in sun4i_dma_prep_dma_memcpy()
645 if (vchan->is_dedicated) { in sun4i_dma_prep_dma_memcpy()
646 promise->cfg |= SUN4I_DMA_CFG_SRC_DRQ_TYPE(SUN4I_DDMA_DRQ_TYPE_SDRAM) | in sun4i_dma_prep_dma_memcpy()
649 promise->cfg |= SUN4I_DMA_CFG_SRC_DRQ_TYPE(SUN4I_NDMA_DRQ_TYPE_SDRAM) | in sun4i_dma_prep_dma_memcpy()
654 list_add_tail(&promise->list, &contract->demands); in sun4i_dma_prep_dma_memcpy()
657 return vchan_tx_prep(&vchan->vc, &contract->vd, flags); in sun4i_dma_prep_dma_memcpy()
666 struct dma_slave_config *sconfig = &vchan->cfg; in sun4i_dma_prep_dma_cyclic()
683 contract->is_cyclic = 1; in sun4i_dma_prep_dma_cyclic()
685 if (vchan->is_dedicated) { in sun4i_dma_prep_dma_cyclic()
697 dest = sconfig->dst_addr; in sun4i_dma_prep_dma_cyclic()
698 endpoints = SUN4I_DMA_CFG_DST_DRQ_TYPE(vchan->endpoint) | in sun4i_dma_prep_dma_cyclic()
703 src = sconfig->src_addr; in sun4i_dma_prep_dma_cyclic()
707 SUN4I_DMA_CFG_SRC_DRQ_TYPE(vchan->endpoint) | in sun4i_dma_prep_dma_cyclic()
718 * The engine can interrupt on half-transfer, so we can use in sun4i_dma_prep_dma_cyclic()
727 * |---|---|---|---| (periods / promises) in sun4i_dma_prep_dma_cyclic()
732 * |-------|-------| (promises as configured on hw) in sun4i_dma_prep_dma_cyclic()
733 * |---|---|---|---| (periods) in sun4i_dma_prep_dma_cyclic()
743 plength = min((len - offset), (period_len * 2)); in sun4i_dma_prep_dma_cyclic()
750 if (vchan->is_dedicated) in sun4i_dma_prep_dma_cyclic()
761 promise->cfg |= endpoints; in sun4i_dma_prep_dma_cyclic()
764 list_add_tail(&promise->list, &contract->demands); in sun4i_dma_prep_dma_cyclic()
768 return vchan_tx_prep(&vchan->vc, &contract->vd, flags); in sun4i_dma_prep_dma_cyclic()
777 struct dma_slave_config *sconfig = &vchan->cfg; in sun4i_dma_prep_slave_sg()
798 if (vchan->is_dedicated) { in sun4i_dma_prep_slave_sg()
809 endpoints = SUN4I_DMA_CFG_DST_DRQ_TYPE(vchan->endpoint) | in sun4i_dma_prep_slave_sg()
816 SUN4I_DMA_CFG_SRC_DRQ_TYPE(vchan->endpoint) | in sun4i_dma_prep_slave_sg()
823 dstaddr = sconfig->dst_addr; in sun4i_dma_prep_slave_sg()
825 srcaddr = sconfig->src_addr; in sun4i_dma_prep_slave_sg()
830 * These are the magic DMA engine timings that keep SPI going. in sun4i_dma_prep_slave_sg()
841 if (vchan->is_dedicated) in sun4i_dma_prep_slave_sg()
853 promise->cfg |= endpoints; in sun4i_dma_prep_slave_sg()
854 promise->para = para; in sun4i_dma_prep_slave_sg()
857 list_add_tail(&promise->list, &contract->demands); in sun4i_dma_prep_slave_sg()
864 return vchan_tx_prep(&vchan->vc, &contract->vd, flags); in sun4i_dma_prep_slave_sg()
869 struct sun4i_dma_dev *priv = to_sun4i_dma_dev(chan->device); in sun4i_dma_terminate_all()
871 struct sun4i_dma_pchan *pchan = vchan->pchan; in sun4i_dma_terminate_all()
875 spin_lock_irqsave(&vchan->vc.lock, flags); in sun4i_dma_terminate_all()
876 vchan_get_all_descriptors(&vchan->vc, &head); in sun4i_dma_terminate_all()
877 spin_unlock_irqrestore(&vchan->vc.lock, flags); in sun4i_dma_terminate_all()
884 if (pchan->is_dedicated) in sun4i_dma_terminate_all()
885 writel(0, pchan->base + SUN4I_DDMA_CFG_REG); in sun4i_dma_terminate_all()
887 writel(0, pchan->base + SUN4I_NDMA_CFG_REG); in sun4i_dma_terminate_all()
892 spin_lock_irqsave(&vchan->vc.lock, flags); in sun4i_dma_terminate_all()
894 vchan->processing = NULL; in sun4i_dma_terminate_all()
895 vchan->pchan = NULL; in sun4i_dma_terminate_all()
896 spin_unlock_irqrestore(&vchan->vc.lock, flags); in sun4i_dma_terminate_all()
898 vchan_dma_desc_free_list(&vchan->vc, &head); in sun4i_dma_terminate_all()
908 memcpy(&vchan->cfg, config, sizeof(*config)); in sun4i_dma_config()
916 struct sun4i_dma_dev *priv = ofdma->of_dma_data; in sun4i_dma_of_xlate()
919 u8 is_dedicated = dma_spec->args[0]; in sun4i_dma_of_xlate()
920 u8 endpoint = dma_spec->args[1]; in sun4i_dma_of_xlate()
931 chan = dma_get_any_slave_channel(&priv->slave); in sun4i_dma_of_xlate()
937 vchan->is_dedicated = is_dedicated; in sun4i_dma_of_xlate()
938 vchan->endpoint = endpoint; in sun4i_dma_of_xlate()
948 struct sun4i_dma_pchan *pchan = vchan->pchan; in sun4i_dma_tx_status()
960 spin_lock_irqsave(&vchan->vc.lock, flags); in sun4i_dma_tx_status()
961 vd = vchan_find_desc(&vchan->vc, cookie); in sun4i_dma_tx_status()
966 list_for_each_entry(promise, &contract->demands, list) in sun4i_dma_tx_status()
967 bytes += promise->len; in sun4i_dma_tx_status()
974 promise = list_first_entry_or_null(&contract->demands, in sun4i_dma_tx_status()
977 bytes -= promise->len; in sun4i_dma_tx_status()
978 if (pchan->is_dedicated) in sun4i_dma_tx_status()
979 bytes += readl(pchan->base + SUN4I_DDMA_BYTE_COUNT_REG); in sun4i_dma_tx_status()
981 bytes += readl(pchan->base + SUN4I_NDMA_BYTE_COUNT_REG); in sun4i_dma_tx_status()
987 spin_unlock_irqrestore(&vchan->vc.lock, flags); in sun4i_dma_tx_status()
994 struct sun4i_dma_dev *priv = to_sun4i_dma_dev(chan->device); in sun4i_dma_issue_pending()
998 spin_lock_irqsave(&vchan->vc.lock, flags); in sun4i_dma_issue_pending()
1004 if (vchan_issue_pending(&vchan->vc)) in sun4i_dma_issue_pending()
1007 spin_unlock_irqrestore(&vchan->vc.lock, flags); in sun4i_dma_issue_pending()
1013 struct sun4i_dma_pchan *pchans = priv->pchans, *pchan; in sun4i_dma_interrupt()
1020 pendirq = readl_relaxed(priv->base + SUN4I_DMA_IRQ_PENDING_STATUS_REG); in sun4i_dma_interrupt()
1029 vchan = pchan->vchan; in sun4i_dma_interrupt()
1032 contract = vchan->contract; in sun4i_dma_interrupt()
1039 spin_lock(&vchan->vc.lock); in sun4i_dma_interrupt()
1045 list_move_tail(&vchan->processing->list, in sun4i_dma_interrupt()
1046 &contract->completed_demands); in sun4i_dma_interrupt()
1050 * - There's always something we can dispatch in sun4i_dma_interrupt()
1051 * - We need to run the callback in sun4i_dma_interrupt()
1052 * - Latency is very important, as this is used by audio in sun4i_dma_interrupt()
1057 * For non-cyclic transfers we need to look around, in sun4i_dma_interrupt()
1061 if (contract->is_cyclic) { in sun4i_dma_interrupt()
1063 vchan->processing = promise; in sun4i_dma_interrupt()
1065 vchan_cyclic_callback(&contract->vd); in sun4i_dma_interrupt()
1067 vchan->processing = NULL; in sun4i_dma_interrupt()
1068 vchan->pchan = NULL; in sun4i_dma_interrupt()
1075 spin_unlock(&vchan->vc.lock); in sun4i_dma_interrupt()
1078 if (contract->is_cyclic) in sun4i_dma_interrupt()
1079 vchan_cyclic_callback(&contract->vd); in sun4i_dma_interrupt()
1086 spin_lock(&priv->lock); in sun4i_dma_interrupt()
1087 irqs = readl_relaxed(priv->base + SUN4I_DMA_IRQ_ENABLE_REG); in sun4i_dma_interrupt()
1089 priv->base + SUN4I_DMA_IRQ_ENABLE_REG); in sun4i_dma_interrupt()
1090 spin_unlock(&priv->lock); in sun4i_dma_interrupt()
1093 writel_relaxed(pendirq, priv->base + SUN4I_DMA_IRQ_PENDING_STATUS_REG); in sun4i_dma_interrupt()
1101 vchan = &priv->vchans[i]; in sun4i_dma_interrupt()
1102 spin_lock(&vchan->vc.lock); in sun4i_dma_interrupt()
1104 spin_unlock(&vchan->vc.lock); in sun4i_dma_interrupt()
1113 pendirq = readl_relaxed(priv->base + in sun4i_dma_interrupt()
1130 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in sun4i_dma_probe()
1132 return -ENOMEM; in sun4i_dma_probe()
1135 priv->base = devm_ioremap_resource(&pdev->dev, res); in sun4i_dma_probe()
1136 if (IS_ERR(priv->base)) in sun4i_dma_probe()
1137 return PTR_ERR(priv->base); in sun4i_dma_probe()
1139 priv->irq = platform_get_irq(pdev, 0); in sun4i_dma_probe()
1140 if (priv->irq < 0) in sun4i_dma_probe()
1141 return priv->irq; in sun4i_dma_probe()
1143 priv->clk = devm_clk_get(&pdev->dev, NULL); in sun4i_dma_probe()
1144 if (IS_ERR(priv->clk)) { in sun4i_dma_probe()
1145 dev_err(&pdev->dev, "No clock specified\n"); in sun4i_dma_probe()
1146 return PTR_ERR(priv->clk); in sun4i_dma_probe()
1150 spin_lock_init(&priv->lock); in sun4i_dma_probe()
1152 dma_cap_zero(priv->slave.cap_mask); in sun4i_dma_probe()
1153 dma_cap_set(DMA_PRIVATE, priv->slave.cap_mask); in sun4i_dma_probe()
1154 dma_cap_set(DMA_MEMCPY, priv->slave.cap_mask); in sun4i_dma_probe()
1155 dma_cap_set(DMA_CYCLIC, priv->slave.cap_mask); in sun4i_dma_probe()
1156 dma_cap_set(DMA_SLAVE, priv->slave.cap_mask); in sun4i_dma_probe()
1158 INIT_LIST_HEAD(&priv->slave.channels); in sun4i_dma_probe()
1159 priv->slave.device_free_chan_resources = sun4i_dma_free_chan_resources; in sun4i_dma_probe()
1160 priv->slave.device_tx_status = sun4i_dma_tx_status; in sun4i_dma_probe()
1161 priv->slave.device_issue_pending = sun4i_dma_issue_pending; in sun4i_dma_probe()
1162 priv->slave.device_prep_slave_sg = sun4i_dma_prep_slave_sg; in sun4i_dma_probe()
1163 priv->slave.device_prep_dma_memcpy = sun4i_dma_prep_dma_memcpy; in sun4i_dma_probe()
1164 priv->slave.device_prep_dma_cyclic = sun4i_dma_prep_dma_cyclic; in sun4i_dma_probe()
1165 priv->slave.device_config = sun4i_dma_config; in sun4i_dma_probe()
1166 priv->slave.device_terminate_all = sun4i_dma_terminate_all; in sun4i_dma_probe()
1167 priv->slave.copy_align = 2; in sun4i_dma_probe()
1168 priv->slave.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | in sun4i_dma_probe()
1171 priv->slave.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | in sun4i_dma_probe()
1174 priv->slave.directions = BIT(DMA_DEV_TO_MEM) | in sun4i_dma_probe()
1176 priv->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST; in sun4i_dma_probe()
1178 priv->slave.dev = &pdev->dev; in sun4i_dma_probe()
1180 priv->pchans = devm_kcalloc(&pdev->dev, SUN4I_DMA_NR_MAX_CHANNELS, in sun4i_dma_probe()
1182 priv->vchans = devm_kcalloc(&pdev->dev, SUN4I_DMA_NR_MAX_VCHANS, in sun4i_dma_probe()
1184 if (!priv->vchans || !priv->pchans) in sun4i_dma_probe()
1185 return -ENOMEM; in sun4i_dma_probe()
1193 priv->pchans[i].base = priv->base + in sun4i_dma_probe()
1197 priv->pchans[i].base = priv->base + in sun4i_dma_probe()
1199 priv->pchans[i].is_dedicated = 1; in sun4i_dma_probe()
1203 struct sun4i_dma_vchan *vchan = &priv->vchans[i]; in sun4i_dma_probe()
1205 spin_lock_init(&vchan->vc.lock); in sun4i_dma_probe()
1206 vchan->vc.desc_free = sun4i_dma_free_contract; in sun4i_dma_probe()
1207 vchan_init(&vchan->vc, &priv->slave); in sun4i_dma_probe()
1210 ret = clk_prepare_enable(priv->clk); in sun4i_dma_probe()
1212 dev_err(&pdev->dev, "Couldn't enable the clock\n"); in sun4i_dma_probe()
1220 writel(0, priv->base + SUN4I_DMA_IRQ_ENABLE_REG); in sun4i_dma_probe()
1221 writel(0xFFFFFFFF, priv->base + SUN4I_DMA_IRQ_PENDING_STATUS_REG); in sun4i_dma_probe()
1223 ret = devm_request_irq(&pdev->dev, priv->irq, sun4i_dma_interrupt, in sun4i_dma_probe()
1224 0, dev_name(&pdev->dev), priv); in sun4i_dma_probe()
1226 dev_err(&pdev->dev, "Cannot request IRQ\n"); in sun4i_dma_probe()
1230 ret = dma_async_device_register(&priv->slave); in sun4i_dma_probe()
1232 dev_warn(&pdev->dev, "Failed to register DMA engine device\n"); in sun4i_dma_probe()
1236 ret = of_dma_controller_register(pdev->dev.of_node, sun4i_dma_of_xlate, in sun4i_dma_probe()
1239 dev_err(&pdev->dev, "of_dma_controller_register failed\n"); in sun4i_dma_probe()
1243 dev_dbg(&pdev->dev, "Successfully probed SUN4I_DMA\n"); in sun4i_dma_probe()
1248 dma_async_device_unregister(&priv->slave); in sun4i_dma_probe()
1250 clk_disable_unprepare(priv->clk); in sun4i_dma_probe()
1259 disable_irq(priv->irq); in sun4i_dma_remove()
1261 of_dma_controller_free(pdev->dev.of_node); in sun4i_dma_remove()
1262 dma_async_device_unregister(&priv->slave); in sun4i_dma_remove()
1264 clk_disable_unprepare(priv->clk); in sun4i_dma_remove()
1270 { .compatible = "allwinner,sun4i-a10-dma" },
1279 .name = "sun4i-dma",
1286 MODULE_DESCRIPTION("Allwinner A10 Dedicated DMA Controller Driver");