mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
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>
This commit is contained in:
parent
a96ca0d206
commit
255348289f
2 changed files with 86 additions and 23 deletions
|
@ -79,14 +79,6 @@
|
|||
#define QMGR_QUEUE_C(n) (0x2008 + (n) * 0x10)
|
||||
#define QMGR_QUEUE_D(n) (0x200c + (n) * 0x10)
|
||||
|
||||
/* Glue layer specific */
|
||||
/* USBSS / USB AM335x */
|
||||
#define USBSS_IRQ_STATUS 0x28
|
||||
#define USBSS_IRQ_ENABLER 0x2c
|
||||
#define USBSS_IRQ_CLEARR 0x30
|
||||
|
||||
#define USBSS_IRQ_PD_COMP (1 << 2)
|
||||
|
||||
/* Packet Descriptor */
|
||||
#define PD2_ZERO_LENGTH (1 << 19)
|
||||
|
||||
|
@ -294,14 +286,8 @@ static irqreturn_t cppi41_irq(int irq, void *data)
|
|||
{
|
||||
struct cppi41_dd *cdd = data;
|
||||
struct cppi41_channel *c;
|
||||
u32 status;
|
||||
int i;
|
||||
|
||||
status = cppi_readl(cdd->usbss_mem + USBSS_IRQ_STATUS);
|
||||
if (!(status & USBSS_IRQ_PD_COMP))
|
||||
return IRQ_NONE;
|
||||
cppi_writel(status, cdd->usbss_mem + USBSS_IRQ_STATUS);
|
||||
|
||||
for (i = QMGR_PENDING_SLOT_Q(FIST_COMPLETION_QUEUE); i < QMGR_NUM_PEND;
|
||||
i++) {
|
||||
u32 val;
|
||||
|
@ -618,6 +604,7 @@ static void cppi41_compute_td_desc(struct cppi41_desc *d)
|
|||
|
||||
static int cppi41_tear_down_chan(struct cppi41_channel *c)
|
||||
{
|
||||
struct dmaengine_result abort_result;
|
||||
struct cppi41_dd *cdd = c->cdd;
|
||||
struct cppi41_desc *td;
|
||||
u32 reg;
|
||||
|
@ -701,6 +688,12 @@ static int cppi41_tear_down_chan(struct cppi41_channel *c)
|
|||
c->td_seen = 0;
|
||||
c->td_desc_seen = 0;
|
||||
cppi_writel(0, c->gcr_reg);
|
||||
|
||||
/* Invoke the callback to do the necessary clean-up */
|
||||
abort_result.result = DMA_TRANS_ABORTED;
|
||||
dma_cookie_complete(&c->txd);
|
||||
dmaengine_desc_get_callback_invoke(&c->txd, &abort_result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1066,8 +1059,6 @@ static int cppi41_dma_probe(struct platform_device *pdev)
|
|||
goto err_irq;
|
||||
}
|
||||
|
||||
cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER);
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, irq, glue_info->isr, IRQF_SHARED,
|
||||
dev_name(dev), cdd);
|
||||
if (ret)
|
||||
|
@ -1091,7 +1082,6 @@ static int cppi41_dma_probe(struct platform_device *pdev)
|
|||
dma_async_device_unregister(&cdd->ddev);
|
||||
err_dma_reg:
|
||||
err_irq:
|
||||
cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR);
|
||||
cleanup_chans(cdd);
|
||||
err_chans:
|
||||
deinit_cppi41(dev, cdd);
|
||||
|
@ -1119,7 +1109,6 @@ static int cppi41_dma_remove(struct platform_device *pdev)
|
|||
of_dma_controller_free(pdev->dev.of_node);
|
||||
dma_async_device_unregister(&cdd->ddev);
|
||||
|
||||
cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR);
|
||||
devm_free_irq(&pdev->dev, cdd->irq, cdd);
|
||||
cleanup_chans(cdd);
|
||||
deinit_cppi41(&pdev->dev, cdd);
|
||||
|
@ -1138,7 +1127,6 @@ static int __maybe_unused cppi41_suspend(struct device *dev)
|
|||
struct cppi41_dd *cdd = dev_get_drvdata(dev);
|
||||
|
||||
cdd->dma_tdfdq = cppi_readl(cdd->ctrl_mem + DMA_TDFDQ);
|
||||
cppi_writel(0, cdd->usbss_mem + USBSS_IRQ_CLEARR);
|
||||
disable_sched(cdd);
|
||||
|
||||
return 0;
|
||||
|
@ -1164,8 +1152,6 @@ static int __maybe_unused cppi41_resume(struct device *dev)
|
|||
cppi_writel(QMGR_SCRATCH_SIZE, cdd->qmgr_mem + QMGR_LRAM_SIZE);
|
||||
cppi_writel(0, cdd->qmgr_mem + QMGR_LRAM1_BASE);
|
||||
|
||||
cppi_writel(USBSS_IRQ_PD_COMP, cdd->usbss_mem + USBSS_IRQ_ENABLER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@ struct dsps_glue {
|
|||
struct timer_list timer; /* otg_workaround timer */
|
||||
unsigned long last_timer; /* last timer data for each instance */
|
||||
bool sw_babble_enabled;
|
||||
void __iomem *usbss_base;
|
||||
|
||||
struct dsps_context context;
|
||||
struct debugfs_regset32 regset;
|
||||
|
@ -169,6 +170,13 @@ static void dsps_mod_timer_optional(struct dsps_glue *glue)
|
|||
dsps_mod_timer(glue, -1);
|
||||
}
|
||||
|
||||
/* USBSS / USB AM335x */
|
||||
#define USBSS_IRQ_STATUS 0x28
|
||||
#define USBSS_IRQ_ENABLER 0x2c
|
||||
#define USBSS_IRQ_CLEARR 0x30
|
||||
|
||||
#define USBSS_IRQ_PD_COMP (1 << 2)
|
||||
|
||||
/**
|
||||
* dsps_musb_enable - enable interrupts
|
||||
*/
|
||||
|
@ -641,14 +649,76 @@ static void dsps_read_fifo32(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_TI_CPPI41_DMA
|
||||
static void dsps_dma_controller_callback(struct dma_controller *c)
|
||||
{
|
||||
struct musb *musb = c->musb;
|
||||
struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent);
|
||||
void __iomem *usbss_base = glue->usbss_base;
|
||||
u32 status;
|
||||
|
||||
status = musb_readl(usbss_base, USBSS_IRQ_STATUS);
|
||||
if (status & USBSS_IRQ_PD_COMP)
|
||||
musb_writel(usbss_base, USBSS_IRQ_STATUS, USBSS_IRQ_PD_COMP);
|
||||
}
|
||||
|
||||
static struct dma_controller *
|
||||
dsps_dma_controller_create(struct musb *musb, void __iomem *base)
|
||||
{
|
||||
struct dma_controller *controller;
|
||||
struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent);
|
||||
void __iomem *usbss_base = glue->usbss_base;
|
||||
|
||||
controller = cppi41_dma_controller_create(musb, base);
|
||||
if (IS_ERR_OR_NULL(controller))
|
||||
return controller;
|
||||
|
||||
musb_writel(usbss_base, USBSS_IRQ_ENABLER, USBSS_IRQ_PD_COMP);
|
||||
controller->dma_callback = dsps_dma_controller_callback;
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
||||
static void dsps_dma_controller_destroy(struct dma_controller *c)
|
||||
{
|
||||
struct musb *musb = c->musb;
|
||||
struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent);
|
||||
void __iomem *usbss_base = glue->usbss_base;
|
||||
|
||||
musb_writel(usbss_base, USBSS_IRQ_CLEARR, USBSS_IRQ_PD_COMP);
|
||||
cppi41_dma_controller_destroy(c);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static void dsps_dma_controller_suspend(struct dsps_glue *glue)
|
||||
{
|
||||
void __iomem *usbss_base = glue->usbss_base;
|
||||
|
||||
musb_writel(usbss_base, USBSS_IRQ_CLEARR, USBSS_IRQ_PD_COMP);
|
||||
}
|
||||
|
||||
static void dsps_dma_controller_resume(struct dsps_glue *glue)
|
||||
{
|
||||
void __iomem *usbss_base = glue->usbss_base;
|
||||
|
||||
musb_writel(usbss_base, USBSS_IRQ_ENABLER, USBSS_IRQ_PD_COMP);
|
||||
}
|
||||
#endif
|
||||
#else /* CONFIG_USB_TI_CPPI41_DMA */
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static void dsps_dma_controller_suspend(struct dsps_glue *glue) {}
|
||||
static void dsps_dma_controller_resume(struct dsps_glue *glue) {}
|
||||
#endif
|
||||
#endif /* CONFIG_USB_TI_CPPI41_DMA */
|
||||
|
||||
static struct musb_platform_ops dsps_ops = {
|
||||
.quirks = MUSB_DMA_CPPI41 | MUSB_INDEXED_EP,
|
||||
.init = dsps_musb_init,
|
||||
.exit = dsps_musb_exit,
|
||||
|
||||
#ifdef CONFIG_USB_TI_CPPI41_DMA
|
||||
.dma_init = cppi41_dma_controller_create,
|
||||
.dma_exit = cppi41_dma_controller_destroy,
|
||||
.dma_init = dsps_dma_controller_create,
|
||||
.dma_exit = dsps_dma_controller_destroy,
|
||||
#endif
|
||||
.enable = dsps_musb_enable,
|
||||
.disable = dsps_musb_disable,
|
||||
|
@ -856,6 +926,9 @@ static int dsps_probe(struct platform_device *pdev)
|
|||
|
||||
glue->dev = &pdev->dev;
|
||||
glue->wrp = wrp;
|
||||
glue->usbss_base = of_iomap(pdev->dev.parent->of_node, 0);
|
||||
if (!glue->usbss_base)
|
||||
return -ENXIO;
|
||||
|
||||
if (usb_get_dr_mode(&pdev->dev) == USB_DR_MODE_PERIPHERAL) {
|
||||
ret = dsps_setup_optional_vbus_irq(pdev, glue);
|
||||
|
@ -950,6 +1023,8 @@ static int dsps_suspend(struct device *dev)
|
|||
glue->context.tx_mode = musb_readl(mbase, wrp->tx_mode);
|
||||
glue->context.rx_mode = musb_readl(mbase, wrp->rx_mode);
|
||||
|
||||
dsps_dma_controller_suspend(glue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -963,6 +1038,8 @@ static int dsps_resume(struct device *dev)
|
|||
if (!musb)
|
||||
return 0;
|
||||
|
||||
dsps_dma_controller_resume(glue);
|
||||
|
||||
mbase = musb->ctrl_base;
|
||||
musb_writel(mbase, wrp->control, glue->context.control);
|
||||
musb_writel(mbase, wrp->epintr_set, glue->context.epintr);
|
||||
|
|
Loading…
Reference in a new issue