fsl-edma-common.c (3eb66e91a25497065c5322b1268cbc3953642227) | fsl-edma-common.c (0fa89f972da607540497f11afbb47af6fea5bce0) |
---|---|
1// SPDX-License-Identifier: GPL-2.0+ 2// 3// Copyright (c) 2013-2014 Freescale Semiconductor, Inc 4// Copyright (c) 2017 Sysam, Angelo Dureghello <angelo@sysam.it> 5 6#include <linux/dmapool.h> 7#include <linux/module.h> 8#include <linux/slab.h> | 1// SPDX-License-Identifier: GPL-2.0+ 2// 3// Copyright (c) 2013-2014 Freescale Semiconductor, Inc 4// Copyright (c) 2017 Sysam, Angelo Dureghello <angelo@sysam.it> 5 6#include <linux/dmapool.h> 7#include <linux/module.h> 8#include <linux/slab.h> |
9#include <linux/dma-mapping.h> |
|
9 10#include "fsl-edma-common.h" 11 12#define EDMA_CR 0x00 13#define EDMA_ES 0x04 14#define EDMA_ERQ 0x0C 15#define EDMA_EEI 0x14 16#define EDMA_SERQ 0x1B --- 151 unchanged lines hidden (view full) --- 168 fsl_chan->status = DMA_IN_PROGRESS; 169 fsl_chan->idle = false; 170 } 171 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); 172 return 0; 173} 174EXPORT_SYMBOL_GPL(fsl_edma_resume); 175 | 10 11#include "fsl-edma-common.h" 12 13#define EDMA_CR 0x00 14#define EDMA_ES 0x04 15#define EDMA_ERQ 0x0C 16#define EDMA_EEI 0x14 17#define EDMA_SERQ 0x1B --- 151 unchanged lines hidden (view full) --- 169 fsl_chan->status = DMA_IN_PROGRESS; 170 fsl_chan->idle = false; 171 } 172 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); 173 return 0; 174} 175EXPORT_SYMBOL_GPL(fsl_edma_resume); 176 |
177static void fsl_edma_unprep_slave_dma(struct fsl_edma_chan *fsl_chan) 178{ 179 if (fsl_chan->dma_dir != DMA_NONE) 180 dma_unmap_resource(fsl_chan->vchan.chan.device->dev, 181 fsl_chan->dma_dev_addr, 182 fsl_chan->dma_dev_size, 183 fsl_chan->dma_dir, 0); 184 fsl_chan->dma_dir = DMA_NONE; 185} 186 187static bool fsl_edma_prep_slave_dma(struct fsl_edma_chan *fsl_chan, 188 enum dma_transfer_direction dir) 189{ 190 struct device *dev = fsl_chan->vchan.chan.device->dev; 191 enum dma_data_direction dma_dir; 192 phys_addr_t addr = 0; 193 u32 size = 0; 194 195 switch (dir) { 196 case DMA_MEM_TO_DEV: 197 dma_dir = DMA_FROM_DEVICE; 198 addr = fsl_chan->cfg.dst_addr; 199 size = fsl_chan->cfg.dst_maxburst; 200 break; 201 case DMA_DEV_TO_MEM: 202 dma_dir = DMA_TO_DEVICE; 203 addr = fsl_chan->cfg.src_addr; 204 size = fsl_chan->cfg.src_maxburst; 205 break; 206 default: 207 dma_dir = DMA_NONE; 208 break; 209 } 210 211 /* Already mapped for this config? */ 212 if (fsl_chan->dma_dir == dma_dir) 213 return true; 214 215 fsl_edma_unprep_slave_dma(fsl_chan); 216 217 fsl_chan->dma_dev_addr = dma_map_resource(dev, addr, size, dma_dir, 0); 218 if (dma_mapping_error(dev, fsl_chan->dma_dev_addr)) 219 return false; 220 fsl_chan->dma_dev_size = size; 221 fsl_chan->dma_dir = dma_dir; 222 223 return true; 224} 225 |
|
176int fsl_edma_slave_config(struct dma_chan *chan, 177 struct dma_slave_config *cfg) 178{ 179 struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); 180 181 memcpy(&fsl_chan->cfg, cfg, sizeof(*cfg)); | 226int fsl_edma_slave_config(struct dma_chan *chan, 227 struct dma_slave_config *cfg) 228{ 229 struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); 230 231 memcpy(&fsl_chan->cfg, cfg, sizeof(*cfg)); |
232 fsl_edma_unprep_slave_dma(fsl_chan); |
|
182 183 return 0; 184} 185EXPORT_SYMBOL_GPL(fsl_edma_slave_config); 186 187static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan, 188 struct virt_dma_desc *vdesc, bool in_progress) 189{ --- 144 unchanged lines hidden (view full) --- 334} 335 336static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan, 337 int sg_len) 338{ 339 struct fsl_edma_desc *fsl_desc; 340 int i; 341 | 233 234 return 0; 235} 236EXPORT_SYMBOL_GPL(fsl_edma_slave_config); 237 238static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan, 239 struct virt_dma_desc *vdesc, bool in_progress) 240{ --- 144 unchanged lines hidden (view full) --- 385} 386 387static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan, 388 int sg_len) 389{ 390 struct fsl_edma_desc *fsl_desc; 391 int i; 392 |
342 fsl_desc = kzalloc(sizeof(*fsl_desc) + 343 sizeof(struct fsl_edma_sw_tcd) * 344 sg_len, GFP_NOWAIT); | 393 fsl_desc = kzalloc(struct_size(fsl_desc, tcd, sg_len), GFP_NOWAIT); |
345 if (!fsl_desc) 346 return NULL; 347 348 fsl_desc->echan = fsl_chan; 349 fsl_desc->n_tcds = sg_len; 350 for (i = 0; i < sg_len; i++) { 351 fsl_desc->tcd[i].vtcd = dma_pool_alloc(fsl_chan->tcd_pool, 352 GFP_NOWAIT, &fsl_desc->tcd[i].ptcd); --- 20 unchanged lines hidden (view full) --- 373 dma_addr_t dma_buf_next; 374 int sg_len, i; 375 u32 src_addr, dst_addr, last_sg, nbytes; 376 u16 soff, doff, iter; 377 378 if (!is_slave_direction(direction)) 379 return NULL; 380 | 394 if (!fsl_desc) 395 return NULL; 396 397 fsl_desc->echan = fsl_chan; 398 fsl_desc->n_tcds = sg_len; 399 for (i = 0; i < sg_len; i++) { 400 fsl_desc->tcd[i].vtcd = dma_pool_alloc(fsl_chan->tcd_pool, 401 GFP_NOWAIT, &fsl_desc->tcd[i].ptcd); --- 20 unchanged lines hidden (view full) --- 422 dma_addr_t dma_buf_next; 423 int sg_len, i; 424 u32 src_addr, dst_addr, last_sg, nbytes; 425 u16 soff, doff, iter; 426 427 if (!is_slave_direction(direction)) 428 return NULL; 429 |
430 if (!fsl_edma_prep_slave_dma(fsl_chan, direction)) 431 return NULL; 432 |
|
381 sg_len = buf_len / period_len; 382 fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len); 383 if (!fsl_desc) 384 return NULL; 385 fsl_desc->iscyclic = true; 386 fsl_desc->dirn = direction; 387 388 dma_buf_next = dma_addr; --- 15 unchanged lines hidden (view full) --- 404 if (dma_buf_next >= dma_addr + buf_len) 405 dma_buf_next = dma_addr; 406 407 /* get next sg's physical address */ 408 last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd; 409 410 if (direction == DMA_MEM_TO_DEV) { 411 src_addr = dma_buf_next; | 433 sg_len = buf_len / period_len; 434 fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len); 435 if (!fsl_desc) 436 return NULL; 437 fsl_desc->iscyclic = true; 438 fsl_desc->dirn = direction; 439 440 dma_buf_next = dma_addr; --- 15 unchanged lines hidden (view full) --- 456 if (dma_buf_next >= dma_addr + buf_len) 457 dma_buf_next = dma_addr; 458 459 /* get next sg's physical address */ 460 last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd; 461 462 if (direction == DMA_MEM_TO_DEV) { 463 src_addr = dma_buf_next; |
412 dst_addr = fsl_chan->cfg.dst_addr; | 464 dst_addr = fsl_chan->dma_dev_addr; |
413 soff = fsl_chan->cfg.dst_addr_width; 414 doff = 0; 415 } else { | 465 soff = fsl_chan->cfg.dst_addr_width; 466 doff = 0; 467 } else { |
416 src_addr = fsl_chan->cfg.src_addr; | 468 src_addr = fsl_chan->dma_dev_addr; |
417 dst_addr = dma_buf_next; 418 soff = 0; 419 doff = fsl_chan->cfg.src_addr_width; 420 } 421 422 fsl_edma_fill_tcd(fsl_desc->tcd[i].vtcd, src_addr, dst_addr, 423 fsl_chan->attr, soff, nbytes, 0, iter, 424 iter, doff, last_sg, true, false, true); --- 14 unchanged lines hidden (view full) --- 439 struct scatterlist *sg; 440 u32 src_addr, dst_addr, last_sg, nbytes; 441 u16 soff, doff, iter; 442 int i; 443 444 if (!is_slave_direction(direction)) 445 return NULL; 446 | 469 dst_addr = dma_buf_next; 470 soff = 0; 471 doff = fsl_chan->cfg.src_addr_width; 472 } 473 474 fsl_edma_fill_tcd(fsl_desc->tcd[i].vtcd, src_addr, dst_addr, 475 fsl_chan->attr, soff, nbytes, 0, iter, 476 iter, doff, last_sg, true, false, true); --- 14 unchanged lines hidden (view full) --- 491 struct scatterlist *sg; 492 u32 src_addr, dst_addr, last_sg, nbytes; 493 u16 soff, doff, iter; 494 int i; 495 496 if (!is_slave_direction(direction)) 497 return NULL; 498 |
499 if (!fsl_edma_prep_slave_dma(fsl_chan, direction)) 500 return NULL; 501 |
|
447 fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len); 448 if (!fsl_desc) 449 return NULL; 450 fsl_desc->iscyclic = false; 451 fsl_desc->dirn = direction; 452 453 if (direction == DMA_MEM_TO_DEV) { 454 fsl_chan->attr = --- 8 unchanged lines hidden (view full) --- 463 } 464 465 for_each_sg(sgl, sg, sg_len, i) { 466 /* get next sg's physical address */ 467 last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd; 468 469 if (direction == DMA_MEM_TO_DEV) { 470 src_addr = sg_dma_address(sg); | 502 fsl_desc = fsl_edma_alloc_desc(fsl_chan, sg_len); 503 if (!fsl_desc) 504 return NULL; 505 fsl_desc->iscyclic = false; 506 fsl_desc->dirn = direction; 507 508 if (direction == DMA_MEM_TO_DEV) { 509 fsl_chan->attr = --- 8 unchanged lines hidden (view full) --- 518 } 519 520 for_each_sg(sgl, sg, sg_len, i) { 521 /* get next sg's physical address */ 522 last_sg = fsl_desc->tcd[(i + 1) % sg_len].ptcd; 523 524 if (direction == DMA_MEM_TO_DEV) { 525 src_addr = sg_dma_address(sg); |
471 dst_addr = fsl_chan->cfg.dst_addr; | 526 dst_addr = fsl_chan->dma_dev_addr; |
472 soff = fsl_chan->cfg.dst_addr_width; 473 doff = 0; 474 } else { | 527 soff = fsl_chan->cfg.dst_addr_width; 528 doff = 0; 529 } else { |
475 src_addr = fsl_chan->cfg.src_addr; | 530 src_addr = fsl_chan->dma_dev_addr; |
476 dst_addr = sg_dma_address(sg); 477 soff = 0; 478 doff = fsl_chan->cfg.src_addr_width; 479 } 480 481 iter = sg_dma_len(sg) / nbytes; 482 if (i < sg_len - 1) { 483 last_sg = fsl_desc->tcd[(i + 1)].ptcd; --- 66 unchanged lines hidden (view full) --- 550 unsigned long flags; 551 LIST_HEAD(head); 552 553 spin_lock_irqsave(&fsl_chan->vchan.lock, flags); 554 fsl_edma_disable_request(fsl_chan); 555 fsl_edma_chan_mux(fsl_chan, 0, false); 556 fsl_chan->edesc = NULL; 557 vchan_get_all_descriptors(&fsl_chan->vchan, &head); | 531 dst_addr = sg_dma_address(sg); 532 soff = 0; 533 doff = fsl_chan->cfg.src_addr_width; 534 } 535 536 iter = sg_dma_len(sg) / nbytes; 537 if (i < sg_len - 1) { 538 last_sg = fsl_desc->tcd[(i + 1)].ptcd; --- 66 unchanged lines hidden (view full) --- 605 unsigned long flags; 606 LIST_HEAD(head); 607 608 spin_lock_irqsave(&fsl_chan->vchan.lock, flags); 609 fsl_edma_disable_request(fsl_chan); 610 fsl_edma_chan_mux(fsl_chan, 0, false); 611 fsl_chan->edesc = NULL; 612 vchan_get_all_descriptors(&fsl_chan->vchan, &head); |
613 fsl_edma_unprep_slave_dma(fsl_chan); |
|
558 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); 559 560 vchan_dma_desc_free_list(&fsl_chan->vchan, &head); 561 dma_pool_destroy(fsl_chan->tcd_pool); 562 fsl_chan->tcd_pool = NULL; 563} 564EXPORT_SYMBOL_GPL(fsl_edma_free_chan_resources); 565 --- 61 unchanged lines hidden --- | 614 spin_unlock_irqrestore(&fsl_chan->vchan.lock, flags); 615 616 vchan_dma_desc_free_list(&fsl_chan->vchan, &head); 617 dma_pool_destroy(fsl_chan->tcd_pool); 618 fsl_chan->tcd_pool = NULL; 619} 620EXPORT_SYMBOL_GPL(fsl_edma_free_chan_resources); 621 --- 61 unchanged lines hidden --- |