diff options
author | Alexandre Bailon <abailon@baylibre.com> | 2017-02-06 23:53:56 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-02-09 07:35:05 -0500 |
commit | 255348289f714b96e0e95f9b702f435a638e6fd4 (patch) | |
tree | 8582ea828878ab62ba768725eccf809897e2f07d | |
parent | a96ca0d20636b594f28772454eedb2b7d8da5a1b (diff) |
usb: musb: dsps: Manage CPPI 4.1 DMA interrupt in DSPS
Despite the CPPI 4.1 is a generic DMA, it is tied to USB.
On the DSPS, CPPI 4.1 interrupt's registers are in USBSS (the MUSB glue).
Currently, to enable / disable and clear interrupts, the CPPI 4.1 driver
maps and accesses to USBSS's register, which making CPPI 4.1 driver not
really generic.
Move the interrupt management to DSPS driver.
Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
Acked-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Bin Liu <b-liu@ti.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/dma/cppi41.c | 28 | ||||
-rw-r--r-- | drivers/usb/musb/musb_dsps.c | 81 |
2 files changed, 86 insertions, 23 deletions
diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index 200828c60db9..d74cee077842 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c | |||
@@ -79,14 +79,6 @@ | |||
79 | #define QMGR_QUEUE_C(n) (0x2008 + (n) * 0x10) | 79 | #define QMGR_QUEUE_C(n) (0x2008 + (n) * 0x10) |
80 | #define QMGR_QUEUE_D(n) (0x200c + (n) * 0x10) | 80 | #define QMGR_QUEUE_D(n) (0x200c + (n) * 0x10) |
81 | 81 | ||
82 | /* Glue layer specific */ | ||
83 | /* USBSS / USB AM335x */ | ||
84 | #define USBSS_IRQ_STATUS 0x28 | ||
85 | #define USBSS_IRQ_ENABLER 0x2c | ||
86 | #define USBSS_IRQ_CLEARR 0x30 | ||
87 | |||
88 | #define USBSS_IRQ_PD_COMP (1 << 2) | ||
89 | |||
90 | /* Packet Descriptor */ | 82 | /* Packet Descriptor */ |
91 | #define PD2_ZERO_LENGTH (1 << 19) | 83 | #define PD2_ZERO_LENGTH (1 << 19) |
92 | 84 | ||
@@ -294,14 +286,8 @@ static irqreturn_t cppi41_irq(int irq, void *data) | |||
294 | { | 286 | { |
295 | struct cppi41_dd *cdd = data; | 287 | struct cppi41_dd *cdd = data; |
296 | struct cppi41_channel *c; | 288 | struct cppi41_channel *c; |
297 | u32 status; | ||
298 | int i; | 289 | int i; |
299 | 290 | ||
300 | status = cppi_readl(cdd->usbss_mem + USBSS_IRQ_STATUS); | ||
301 | if (!(status & USBSS_IRQ_PD_COMP)) | ||
302 | return IRQ_NONE; | ||
303 | cppi_writel(status, cdd->usbss_mem + USBSS_IRQ_STATUS); | ||
304 | |||
305 | for (i = QMGR_PENDING_SLOT_Q(FIST_COMPLETION_QUEUE); i < QMGR_NUM_PEND; | 291 | for (i = QMGR_PENDING_SLOT_Q(FIST_COMPLETION_QUEUE); i < QMGR_NUM_PEND; |
306 | i++) { | 292 | i++) { |
307 | u32 val; | 293 | u32 val; |
@@ -618,6 +604,7 @@ static void cppi41_compute_td_desc(struct cppi41_desc *d) | |||
618 | 604 | ||
619 | static int cppi41_tear_down_chan(struct cppi41_channel *c) | 605 | static int cppi41_tear_down_chan(struct cppi41_channel *c) |
620 | { | 606 | { |
607 | struct dmaengine_result abort_result; | ||
621 | struct cppi41_dd *cdd = c->cdd; | 608 | struct cppi41_dd *cdd = c->cdd; |
622 | struct cppi41_desc *td; | 609 | struct cppi41_desc *td; |
623 | u32 reg; | 610 | u32 reg; |
@@ -701,6 +688,12 @@ static int cppi41_tear_down_chan(struct cppi41_channel *c) | |||
701 | c->td_seen = 0; | 688 | c->td_seen = 0; |
702 | c->td_desc_seen = 0; | 689 | c->td_desc_seen = 0; |
703 | cppi_writel(0, c->gcr_reg); | 690 | cppi_writel(0, c->gcr_reg); |
691 | |||
692 | /* Invoke the callback to do the necessary clean-up */ | ||
693 | abort_result.result = DMA_TRANS_ABORTED; | ||
694 | dma_cookie_complete(&c->txd); | ||
695 | dmaengine_desc_get_callback_invoke(&c->txd, &abort_result); | ||
696 | |||
704 | return 0; | 697 | return 0; |
705 | } | 698 | } |
706 | 699 | ||
@@ -1066,8 +1059,6 @@ static int cppi41_dma_probe(struct platform_device *pdev) | |||
1066 | goto err_irq; | 1059 | goto err_irq; |
1067 | } | 1060 | } |
1068 | 1061 | ||
1069 | cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER); | ||
1070 | |||
1071 | ret = devm_request_irq(&pdev->dev, irq, glue_info->isr, IRQF_SHARED, | 1062 | ret = devm_request_irq(&pdev->dev, irq, glue_info->isr, IRQF_SHARED, |
1072 | dev_name(dev), cdd); | 1063 | dev_name(dev), cdd); |
1073 | if (ret) | 1064 | if (ret) |
@@ -1091,7 +1082,6 @@ err_of: | |||
1091 | dma_async_device_unregister(&cdd->ddev); | 1082 | dma_async_device_unregister(&cdd->ddev); |
1092 | err_dma_reg: | 1083 | err_dma_reg: |
1093 | err_irq: | 1084 | err_irq: |
1094 | cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); | ||
1095 | cleanup_chans(cdd); | 1085 | cleanup_chans(cdd); |
1096 | err_chans: | 1086 | err_chans: |
1097 | deinit_cppi41(dev, cdd); | 1087 | deinit_cppi41(dev, cdd); |
@@ -1119,7 +1109,6 @@ static int cppi41_dma_remove(struct platform_device *pdev) | |||
1119 | of_dma_controller_free(pdev->dev.of_node); | 1109 | of_dma_controller_free(pdev->dev.of_node); |
1120 | dma_async_device_unregister(&cdd->ddev); | 1110 | dma_async_device_unregister(&cdd->ddev); |
1121 | 1111 | ||
1122 | cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); | ||
1123 | devm_free_irq(&pdev->dev, cdd->irq, cdd); | 1112 | devm_free_irq(&pdev->dev, cdd->irq, cdd); |
1124 | cleanup_chans(cdd); | 1113 | cleanup_chans(cdd); |
1125 | deinit_cppi41(&pdev->dev, cdd); | 1114 | deinit_cppi41(&pdev->dev, cdd); |
@@ -1138,7 +1127,6 @@ static int __maybe_unused cppi41_suspend(struct device *dev) | |||
1138 | struct cppi41_dd *cdd = dev_get_drvdata(dev); | 1127 | struct cppi41_dd *cdd = dev_get_drvdata(dev); |
1139 | 1128 | ||
1140 | cdd->dma_tdfdq = cppi_readl(cdd->ctrl_mem + DMA_TDFDQ); | 1129 | cdd->dma_tdfdq = cppi_readl(cdd->ctrl_mem + DMA_TDFDQ); |
1141 | cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR); | ||
1142 | disable_sched(cdd); | 1130 | disable_sched(cdd); |
1143 | 1131 | ||
1144 | return 0; | 1132 | return 0; |
@@ -1164,8 +1152,6 @@ static int __maybe_unused cppi41_resume(struct device *dev) | |||
1164 | cppi_writel(QMGR_SCRATCH_SIZE, cdd->qmgr_mem + QMGR_LRAM_SIZE); | 1152 | cppi_writel(QMGR_SCRATCH_SIZE, cdd->qmgr_mem + QMGR_LRAM_SIZE); |
1165 | cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM1_BASE); | 1153 | cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM1_BASE); |
1166 | 1154 | ||
1167 | cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER); | ||
1168 | |||
1169 | return 0; | 1155 | return 0; |
1170 | } | 1156 | } |
1171 | 1157 | ||
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index c171a0f13bc3..7c047c4a2565 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
@@ -122,6 +122,7 @@ struct dsps_glue { | |||
122 | struct timer_list timer; /* otg_workaround timer */ | 122 | struct timer_list timer; /* otg_workaround timer */ |
123 | unsigned long last_timer; /* last timer data for each instance */ | 123 | unsigned long last_timer; /* last timer data for each instance */ |
124 | bool sw_babble_enabled; | 124 | bool sw_babble_enabled; |
125 | void __iomem *usbss_base; | ||
125 | 126 | ||
126 | struct dsps_context context; | 127 | struct dsps_context context; |
127 | struct debugfs_regset32 regset; | 128 | struct debugfs_regset32 regset; |
@@ -169,6 +170,13 @@ static void dsps_mod_timer_optional(struct dsps_glue *glue) | |||
169 | dsps_mod_timer(glue, -1); | 170 | dsps_mod_timer(glue, -1); |
170 | } | 171 | } |
171 | 172 | ||
173 | /* USBSS / USB AM335x */ | ||
174 | #define USBSS_IRQ_STATUS 0x28 | ||
175 | #define USBSS_IRQ_ENABLER 0x2c | ||
176 | #define USBSS_IRQ_CLEARR 0x30 | ||
177 | |||
178 | #define USBSS_IRQ_PD_COMP (1 << 2) | ||
179 | |||
172 | /** | 180 | /** |
173 | * dsps_musb_enable - enable interrupts | 181 | * dsps_musb_enable - enable interrupts |
174 | */ | 182 | */ |
@@ -641,14 +649,76 @@ static void dsps_read_fifo32(struct musb_hw_ep *hw_ep, u16 len, u8 *dst) | |||
641 | } | 649 | } |
642 | } | 650 | } |
643 | 651 | ||
652 | #ifdef CONFIG_USB_TI_CPPI41_DMA | ||
653 | static void dsps_dma_controller_callback(struct dma_controller *c) | ||
654 | { | ||
655 | struct musb *musb = c->musb; | ||
656 | struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent); | ||
657 | void __iomem *usbss_base = glue->usbss_base; | ||
658 | u32 status; | ||
659 | |||
660 | status = musb_readl(usbss_base, USBSS_IRQ_STATUS); | ||
661 | if (status & USBSS_IRQ_PD_COMP) | ||
662 | musb_writel(usbss_base, USBSS_IRQ_STATUS, USBSS_IRQ_PD_COMP); | ||
663 | } | ||
664 | |||
665 | static struct dma_controller * | ||
666 | dsps_dma_controller_create(struct musb *musb, void __iomem *base) | ||
667 | { | ||
668 | struct dma_controller *controller; | ||
669 | struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent); | ||
670 | void __iomem *usbss_base = glue->usbss_base; | ||
671 | |||
672 | controller = cppi41_dma_controller_create(musb, base); | ||
673 | if (IS_ERR_OR_NULL(controller)) | ||
674 | return controller; | ||
675 | |||
676 | musb_writel(usbss_base, USBSS_IRQ_ENABLER, USBSS_IRQ_PD_COMP); | ||
677 | controller->dma_callback = dsps_dma_controller_callback; | ||
678 | |||
679 | return controller; | ||
680 | } | ||
681 | |||
682 | static void dsps_dma_controller_destroy(struct dma_controller *c) | ||
683 | { | ||
684 | struct musb *musb = c->musb; | ||
685 | struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent); | ||
686 | void __iomem *usbss_base = glue->usbss_base; | ||
687 | |||
688 | musb_writel(usbss_base, USBSS_IRQ_CLEARR, USBSS_IRQ_PD_COMP); | ||
689 | cppi41_dma_controller_destroy(c); | ||
690 | } | ||
691 | |||
692 | #ifdef CONFIG_PM_SLEEP | ||
693 | static void dsps_dma_controller_suspend(struct dsps_glue *glue) | ||
694 | { | ||
695 | void __iomem *usbss_base = glue->usbss_base; | ||
696 | |||
697 | musb_writel(usbss_base, USBSS_IRQ_CLEARR, USBSS_IRQ_PD_COMP); | ||
698 | } | ||
699 | |||
700 | static void dsps_dma_controller_resume(struct dsps_glue *glue) | ||
701 | { | ||
702 | void __iomem *usbss_base = glue->usbss_base; | ||
703 | |||
704 | musb_writel(usbss_base, USBSS_IRQ_ENABLER, USBSS_IRQ_PD_COMP); | ||
705 | } | ||
706 | #endif | ||
707 | #else /* CONFIG_USB_TI_CPPI41_DMA */ | ||
708 | #ifdef CONFIG_PM_SLEEP | ||
709 | static void dsps_dma_controller_suspend(struct dsps_glue *glue) {} | ||
710 | static void dsps_dma_controller_resume(struct dsps_glue *glue) {} | ||
711 | #endif | ||
712 | #endif /* CONFIG_USB_TI_CPPI41_DMA */ | ||
713 | |||
644 | static struct musb_platform_ops dsps_ops = { | 714 | static struct musb_platform_ops dsps_ops = { |
645 | .quirks = MUSB_DMA_CPPI41 | MUSB_INDEXED_EP, | 715 | .quirks = MUSB_DMA_CPPI41 | MUSB_INDEXED_EP, |
646 | .init = dsps_musb_init, | 716 | .init = dsps_musb_init, |
647 | .exit = dsps_musb_exit, | 717 | .exit = dsps_musb_exit, |
648 | 718 | ||
649 | #ifdef CONFIG_USB_TI_CPPI41_DMA | 719 | #ifdef CONFIG_USB_TI_CPPI41_DMA |
650 | .dma_init = cppi41_dma_controller_create, | 720 | .dma_init = dsps_dma_controller_create, |
651 | .dma_exit = cppi41_dma_controller_destroy, | 721 | .dma_exit = dsps_dma_controller_destroy, |
652 | #endif | 722 | #endif |
653 | .enable = dsps_musb_enable, | 723 | .enable = dsps_musb_enable, |
654 | .disable = dsps_musb_disable, | 724 | .disable = dsps_musb_disable, |
@@ -856,6 +926,9 @@ static int dsps_probe(struct platform_device *pdev) | |||
856 | 926 | ||
857 | glue->dev = &pdev->dev; | 927 | glue->dev = &pdev->dev; |
858 | glue->wrp = wrp; | 928 | glue->wrp = wrp; |
929 | glue->usbss_base = of_iomap(pdev->dev.parent->of_node, 0); | ||
930 | if (!glue->usbss_base) | ||
931 | return -ENXIO; | ||
859 | 932 | ||
860 | if (usb_get_dr_mode(&pdev->dev) == USB_DR_MODE_PERIPHERAL) { | 933 | if (usb_get_dr_mode(&pdev->dev) == USB_DR_MODE_PERIPHERAL) { |
861 | ret = dsps_setup_optional_vbus_irq(pdev, glue); | 934 | ret = dsps_setup_optional_vbus_irq(pdev, glue); |
@@ -950,6 +1023,8 @@ static int dsps_suspend(struct device *dev) | |||
950 | glue->context.tx_mode = musb_readl(mbase, wrp->tx_mode); | 1023 | glue->context.tx_mode = musb_readl(mbase, wrp->tx_mode); |
951 | glue->context.rx_mode = musb_readl(mbase, wrp->rx_mode); | 1024 | glue->context.rx_mode = musb_readl(mbase, wrp->rx_mode); |
952 | 1025 | ||
1026 | dsps_dma_controller_suspend(glue); | ||
1027 | |||
953 | return 0; | 1028 | return 0; |
954 | } | 1029 | } |
955 | 1030 | ||
@@ -963,6 +1038,8 @@ static int dsps_resume(struct device *dev) | |||
963 | if (!musb) | 1038 | if (!musb) |
964 | return 0; | 1039 | return 0; |
965 | 1040 | ||
1041 | dsps_dma_controller_resume(glue); | ||
1042 | |||
966 | mbase = musb->ctrl_base; | 1043 | mbase = musb->ctrl_base; |
967 | musb_writel(mbase, wrp->control, glue->context.control); | 1044 | musb_writel(mbase, wrp->control, glue->context.control); |
968 | musb_writel(mbase, wrp->epintr_set, glue->context.epintr); | 1045 | musb_writel(mbase, wrp->epintr_set, glue->context.epintr); |