aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGregory Herrero <gregory.herrero@intel.com>2015-04-29 16:09:16 -0400
committerFelipe Balbi <balbi@ti.com>2015-04-29 16:20:00 -0400
commitdb62b9a804b465f5050438eb06151c99c625ec9a (patch)
treedd167e381e31826ef95c1d9718908494c2f8fdcf
parent33ad261aa62be02f0cedeb4d5735cc726de84a3f (diff)
usb: dwc2: host: don't use dma_alloc_coherent with irqs disabled
Align buffer must be allocated using kmalloc since irqs are disabled. Coherency is handled through dma_map_single which can be used with irqs disabled. Reviewed-by: Julius Werner <jwerner@chromium.org> Acked-by: John Youn <johnyoun@synopsys.com> Signed-off-by: Gregory Herrero <gregory.herrero@intel.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
-rw-r--r--drivers/usb/dwc2/hcd.c13
-rw-r--r--drivers/usb/dwc2/hcd_intr.c53
-rw-r--r--drivers/usb/dwc2/hcd_queue.c10
3 files changed, 54 insertions, 22 deletions
diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c
index d72557cfc052..745230d0d8b3 100644
--- a/drivers/usb/dwc2/hcd.c
+++ b/drivers/usb/dwc2/hcd.c
@@ -719,9 +719,7 @@ static int dwc2_hc_setup_align_buf(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
719 /* 3072 = 3 max-size Isoc packets */ 719 /* 3072 = 3 max-size Isoc packets */
720 buf_size = 3072; 720 buf_size = 3072;
721 721
722 qh->dw_align_buf = dma_alloc_coherent(hsotg->dev, buf_size, 722 qh->dw_align_buf = kmalloc(buf_size, GFP_ATOMIC | GFP_DMA);
723 &qh->dw_align_buf_dma,
724 GFP_ATOMIC);
725 if (!qh->dw_align_buf) 723 if (!qh->dw_align_buf)
726 return -ENOMEM; 724 return -ENOMEM;
727 qh->dw_align_buf_size = buf_size; 725 qh->dw_align_buf_size = buf_size;
@@ -746,6 +744,15 @@ static int dwc2_hc_setup_align_buf(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
746 } 744 }
747 } 745 }
748 746
747 qh->dw_align_buf_dma = dma_map_single(hsotg->dev,
748 qh->dw_align_buf, qh->dw_align_buf_size,
749 chan->ep_is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
750 if (dma_mapping_error(hsotg->dev, qh->dw_align_buf_dma)) {
751 dev_err(hsotg->dev, "can't map align_buf\n");
752 chan->align_buf = (dma_addr_t)NULL;
753 return -EINVAL;
754 }
755
749 chan->align_buf = qh->dw_align_buf_dma; 756 chan->align_buf = qh->dw_align_buf_dma;
750 return 0; 757 return 0;
751} 758}
diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index 6927bba86245..6ea8eb6899f4 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -466,10 +466,15 @@ static int dwc2_update_urb_state(struct dwc2_hsotg *hsotg,
466 } 466 }
467 467
468 /* Non DWORD-aligned buffer case handling */ 468 /* Non DWORD-aligned buffer case handling */
469 if (chan->align_buf && xfer_length && chan->ep_is_in) { 469 if (chan->align_buf && xfer_length) {
470 dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__); 470 dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__);
471 memcpy(urb->buf + urb->actual_length, chan->qh->dw_align_buf, 471 dma_unmap_single(hsotg->dev, chan->qh->dw_align_buf_dma,
472 xfer_length); 472 chan->qh->dw_align_buf_size,
473 chan->ep_is_in ?
474 DMA_FROM_DEVICE : DMA_TO_DEVICE);
475 if (chan->ep_is_in)
476 memcpy(urb->buf + urb->actual_length,
477 chan->qh->dw_align_buf, xfer_length);
473 } 478 }
474 479
475 dev_vdbg(hsotg->dev, "urb->actual_length=%d xfer_length=%d\n", 480 dev_vdbg(hsotg->dev, "urb->actual_length=%d xfer_length=%d\n",
@@ -555,13 +560,18 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state(
555 chan, chnum, qtd, halt_status, NULL); 560 chan, chnum, qtd, halt_status, NULL);
556 561
557 /* Non DWORD-aligned buffer case handling */ 562 /* Non DWORD-aligned buffer case handling */
558 if (chan->align_buf && frame_desc->actual_length && 563 if (chan->align_buf && frame_desc->actual_length) {
559 chan->ep_is_in) {
560 dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", 564 dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n",
561 __func__); 565 __func__);
562 memcpy(urb->buf + frame_desc->offset + 566 dma_unmap_single(hsotg->dev, chan->qh->dw_align_buf_dma,
563 qtd->isoc_split_offset, chan->qh->dw_align_buf, 567 chan->qh->dw_align_buf_size,
564 frame_desc->actual_length); 568 chan->ep_is_in ?
569 DMA_FROM_DEVICE : DMA_TO_DEVICE);
570 if (chan->ep_is_in)
571 memcpy(urb->buf + frame_desc->offset +
572 qtd->isoc_split_offset,
573 chan->qh->dw_align_buf,
574 frame_desc->actual_length);
565 } 575 }
566 break; 576 break;
567 case DWC2_HC_XFER_FRAME_OVERRUN: 577 case DWC2_HC_XFER_FRAME_OVERRUN:
@@ -584,13 +594,18 @@ static enum dwc2_halt_status dwc2_update_isoc_urb_state(
584 chan, chnum, qtd, halt_status, NULL); 594 chan, chnum, qtd, halt_status, NULL);
585 595
586 /* Non DWORD-aligned buffer case handling */ 596 /* Non DWORD-aligned buffer case handling */
587 if (chan->align_buf && frame_desc->actual_length && 597 if (chan->align_buf && frame_desc->actual_length) {
588 chan->ep_is_in) {
589 dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", 598 dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n",
590 __func__); 599 __func__);
591 memcpy(urb->buf + frame_desc->offset + 600 dma_unmap_single(hsotg->dev, chan->qh->dw_align_buf_dma,
592 qtd->isoc_split_offset, chan->qh->dw_align_buf, 601 chan->qh->dw_align_buf_size,
593 frame_desc->actual_length); 602 chan->ep_is_in ?
603 DMA_FROM_DEVICE : DMA_TO_DEVICE);
604 if (chan->ep_is_in)
605 memcpy(urb->buf + frame_desc->offset +
606 qtd->isoc_split_offset,
607 chan->qh->dw_align_buf,
608 frame_desc->actual_length);
594 } 609 }
595 610
596 /* Skip whole frame */ 611 /* Skip whole frame */
@@ -926,6 +941,8 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg *hsotg,
926 941
927 if (chan->align_buf) { 942 if (chan->align_buf) {
928 dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__); 943 dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__);
944 dma_unmap_single(hsotg->dev, chan->qh->dw_align_buf_dma,
945 chan->qh->dw_align_buf_size, DMA_FROM_DEVICE);
929 memcpy(qtd->urb->buf + frame_desc->offset + 946 memcpy(qtd->urb->buf + frame_desc->offset +
930 qtd->isoc_split_offset, chan->qh->dw_align_buf, len); 947 qtd->isoc_split_offset, chan->qh->dw_align_buf, len);
931 } 948 }
@@ -1155,8 +1172,14 @@ static void dwc2_update_urb_state_abn(struct dwc2_hsotg *hsotg,
1155 /* Non DWORD-aligned buffer case handling */ 1172 /* Non DWORD-aligned buffer case handling */
1156 if (chan->align_buf && xfer_length && chan->ep_is_in) { 1173 if (chan->align_buf && xfer_length && chan->ep_is_in) {
1157 dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__); 1174 dev_vdbg(hsotg->dev, "%s(): non-aligned buffer\n", __func__);
1158 memcpy(urb->buf + urb->actual_length, chan->qh->dw_align_buf, 1175 dma_unmap_single(hsotg->dev, chan->qh->dw_align_buf_dma,
1159 xfer_length); 1176 chan->qh->dw_align_buf_size,
1177 chan->ep_is_in ?
1178 DMA_FROM_DEVICE : DMA_TO_DEVICE);
1179 if (chan->ep_is_in)
1180 memcpy(urb->buf + urb->actual_length,
1181 chan->qh->dw_align_buf,
1182 xfer_length);
1160 } 1183 }
1161 1184
1162 urb->actual_length += xfer_length; 1185 urb->actual_length += xfer_length;
diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index 63207dc3cb22..9b5c36256627 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -229,11 +229,13 @@ static struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
229 */ 229 */
230void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh) 230void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh)
231{ 231{
232 if (hsotg->core_params->dma_desc_enable > 0) 232 if (hsotg->core_params->dma_desc_enable > 0) {
233 dwc2_hcd_qh_free_ddma(hsotg, qh); 233 dwc2_hcd_qh_free_ddma(hsotg, qh);
234 else if (qh->dw_align_buf) 234 } else {
235 dma_free_coherent(hsotg->dev, qh->dw_align_buf_size, 235 /* kfree(NULL) is safe */
236 qh->dw_align_buf, qh->dw_align_buf_dma); 236 kfree(qh->dw_align_buf);
237 qh->dw_align_buf_dma = (dma_addr_t)0;
238 }
237 kfree(qh); 239 kfree(qh);
238} 240}
239 241