diff options
Diffstat (limited to 'drivers/mfd/rtsx_pcr.c')
-rw-r--r-- | drivers/mfd/rtsx_pcr.c | 76 |
1 files changed, 48 insertions, 28 deletions
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index 1d15735f9ef9..d01b8c249231 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c | |||
@@ -337,40 +337,64 @@ static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr, | |||
337 | int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, | 337 | int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, |
338 | int num_sg, bool read, int timeout) | 338 | int num_sg, bool read, int timeout) |
339 | { | 339 | { |
340 | struct completion trans_done; | 340 | int err = 0, count; |
341 | u8 dir; | ||
342 | int err = 0, i, count; | ||
343 | long timeleft; | ||
344 | unsigned long flags; | ||
345 | struct scatterlist *sg; | ||
346 | enum dma_data_direction dma_dir; | ||
347 | u32 val; | ||
348 | dma_addr_t addr; | ||
349 | unsigned int len; | ||
350 | 341 | ||
351 | dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg); | 342 | dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg); |
343 | count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read); | ||
344 | if (count < 1) | ||
345 | return -EINVAL; | ||
346 | dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); | ||
347 | |||
348 | err = rtsx_pci_dma_transfer(pcr, sglist, count, read, timeout); | ||
349 | |||
350 | rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read); | ||
351 | |||
352 | return err; | ||
353 | } | ||
354 | EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); | ||
355 | |||
356 | int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
357 | int num_sg, bool read) | ||
358 | { | ||
359 | enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
352 | 360 | ||
353 | /* don't transfer data during abort processing */ | ||
354 | if (pcr->remove_pci) | 361 | if (pcr->remove_pci) |
355 | return -EINVAL; | 362 | return -EINVAL; |
356 | 363 | ||
357 | if ((sglist == NULL) || (num_sg <= 0)) | 364 | if ((sglist == NULL) || (num_sg <= 0)) |
358 | return -EINVAL; | 365 | return -EINVAL; |
359 | 366 | ||
360 | if (read) { | 367 | return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir); |
361 | dir = DEVICE_TO_HOST; | 368 | } |
362 | dma_dir = DMA_FROM_DEVICE; | 369 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg); |
363 | } else { | ||
364 | dir = HOST_TO_DEVICE; | ||
365 | dma_dir = DMA_TO_DEVICE; | ||
366 | } | ||
367 | 370 | ||
368 | count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); | 371 | void rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, |
369 | if (count < 1) { | 372 | int num_sg, bool read) |
370 | dev_err(&(pcr->pci->dev), "scatterlist map failed\n"); | 373 | { |
374 | enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
375 | |||
376 | dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir); | ||
377 | } | ||
378 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg); | ||
379 | |||
380 | int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
381 | int count, bool read, int timeout) | ||
382 | { | ||
383 | struct completion trans_done; | ||
384 | struct scatterlist *sg; | ||
385 | dma_addr_t addr; | ||
386 | long timeleft; | ||
387 | unsigned long flags; | ||
388 | unsigned int len; | ||
389 | int i, err = 0; | ||
390 | u32 val; | ||
391 | u8 dir = read ? DEVICE_TO_HOST : HOST_TO_DEVICE; | ||
392 | |||
393 | if (pcr->remove_pci) | ||
394 | return -ENODEV; | ||
395 | |||
396 | if ((sglist == NULL) || (count < 1)) | ||
371 | return -EINVAL; | 397 | return -EINVAL; |
372 | } | ||
373 | dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); | ||
374 | 398 | ||
375 | val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; | 399 | val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; |
376 | pcr->sgi = 0; | 400 | pcr->sgi = 0; |
@@ -400,12 +424,10 @@ int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, | |||
400 | } | 424 | } |
401 | 425 | ||
402 | spin_lock_irqsave(&pcr->lock, flags); | 426 | spin_lock_irqsave(&pcr->lock, flags); |
403 | |||
404 | if (pcr->trans_result == TRANS_RESULT_FAIL) | 427 | if (pcr->trans_result == TRANS_RESULT_FAIL) |
405 | err = -EINVAL; | 428 | err = -EINVAL; |
406 | else if (pcr->trans_result == TRANS_NO_DEVICE) | 429 | else if (pcr->trans_result == TRANS_NO_DEVICE) |
407 | err = -ENODEV; | 430 | err = -ENODEV; |
408 | |||
409 | spin_unlock_irqrestore(&pcr->lock, flags); | 431 | spin_unlock_irqrestore(&pcr->lock, flags); |
410 | 432 | ||
411 | out: | 433 | out: |
@@ -413,8 +435,6 @@ out: | |||
413 | pcr->done = NULL; | 435 | pcr->done = NULL; |
414 | spin_unlock_irqrestore(&pcr->lock, flags); | 436 | spin_unlock_irqrestore(&pcr->lock, flags); |
415 | 437 | ||
416 | dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); | ||
417 | |||
418 | if ((err < 0) && (err != -ENODEV)) | 438 | if ((err < 0) && (err != -ENODEV)) |
419 | rtsx_pci_stop_cmd(pcr); | 439 | rtsx_pci_stop_cmd(pcr); |
420 | 440 | ||
@@ -423,7 +443,7 @@ out: | |||
423 | 443 | ||
424 | return err; | 444 | return err; |
425 | } | 445 | } |
426 | EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); | 446 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_transfer); |
427 | 447 | ||
428 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) | 448 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) |
429 | { | 449 | { |