Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91e9c4fe authored by Sergei Shtylyov's avatar Sergei Shtylyov Committed by Greg Kroah-Hartman
Browse files

musb: split out CPPI interrupt handler



As DaVinci DM646x has a dedicated CPPI DMA interrupt, replace
cppi_completion() (which has always been kind of layering
violation) by a complete CPPI interrupt handler.

[ dbrownell@users.sourceforge.net: only cppi_dma.c needs platform
device header, not cppi_dma.h ]

Signed-off-by: default avatarDmitry Krivoschekov <dkrivoschekov@ru.mvista.com>
Signed-off-by: default avatarSergei Shtylyov <sshtylyov@ru.mvista.com>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent c9cd06b3
Loading
Loading
Loading
Loading
+31 −3
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
 * The TUSB6020, using VLYNQ, has CPPI that looks much like DaVinci.
 */

#include <linux/platform_device.h>
#include <linux/usb.h>

#include "musb_core.h"
@@ -1145,17 +1146,27 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch)
	return completed;
}

void cppi_completion(struct musb *musb, u32 rx, u32 tx)
irqreturn_t cppi_interrupt(int irq, void *dev_id)
{
	void __iomem		*tibase;
	int			i, index;
	struct musb		*musb = dev_id;
	struct cppi		*cppi;
	void __iomem		*tibase;
	struct musb_hw_ep	*hw_ep = NULL;
	u32			rx, tx;
	int			i, index;

	cppi = container_of(musb->dma_controller, struct cppi, controller);

	tibase = musb->ctrl_base;

	tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG);
	rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG);

	if (!tx && !rx)
		return IRQ_NONE;

	DBG(4, "CPPI IRQ Tx%x Rx%x\n", tx, rx);

	/* process TX channels */
	for (index = 0; tx; tx = tx >> 1, index++) {
		struct cppi_channel		*tx_ch;
@@ -1273,6 +1284,8 @@ void cppi_completion(struct musb *musb, u32 rx, u32 tx)

	/* write to CPPI EOI register to re-enable interrupts */
	musb_writel(tibase, DAVINCI_CPPI_EOI_REG, 0);

	return IRQ_HANDLED;
}

/* Instantiate a software object representing a DMA controller. */
@@ -1280,6 +1293,9 @@ struct dma_controller *__init
dma_controller_create(struct musb *musb, void __iomem *mregs)
{
	struct cppi		*controller;
	struct device		*dev = musb->controller;
	struct platform_device	*pdev = to_platform_device(dev);
	int			irq = platform_get_irq(pdev, 1);

	controller = kzalloc(sizeof *controller, GFP_KERNEL);
	if (!controller)
@@ -1310,6 +1326,15 @@ dma_controller_create(struct musb *musb, void __iomem *mregs)
		return NULL;
	}

	if (irq > 0) {
		if (request_irq(irq, cppi_interrupt, 0, "cppi-dma", musb)) {
			dev_err(dev, "request_irq %d failed!\n", irq);
			dma_controller_destroy(&controller->controller);
			return NULL;
		}
		controller->irq = irq;
	}

	return &controller->controller;
}

@@ -1322,6 +1347,9 @@ void dma_controller_destroy(struct dma_controller *c)

	cppi = container_of(c, struct cppi, controller);

	if (cppi->irq)
		free_irq(cppi->irq, cppi->musb);

	/* assert:  caller stopped the controller first */
	dma_pool_destroy(cppi->pool);

+4 −2
Original line number Diff line number Diff line
@@ -119,6 +119,8 @@ struct cppi {
	void __iomem			*mregs;		/* Mentor regs */
	void __iomem			*tibase;	/* TI/CPPI regs */

	int				irq;

	struct cppi_channel		tx[4];
	struct cppi_channel		rx[4];

@@ -127,7 +129,7 @@ struct cppi {
	struct list_head		tx_complete;
};

/* irq handling hook */
extern void cppi_completion(struct musb *, u32 rx, u32 tx);
/* CPPI IRQ handler */
extern irqreturn_t cppi_interrupt(int, void *);

#endif				/* end of ifndef _CPPI_DMA_H_ */
+4 −10
Original line number Diff line number Diff line
@@ -265,6 +265,7 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
	irqreturn_t	retval = IRQ_NONE;
	struct musb	*musb = __hci;
	void __iomem	*tibase = musb->ctrl_base;
	struct cppi	*cppi;
	u32		tmp;

	spin_lock_irqsave(&musb->lock, flags);
@@ -281,16 +282,9 @@ static irqreturn_t davinci_interrupt(int irq, void *__hci)
	/* CPPI interrupts share the same IRQ line, but have their own
	 * mask, state, "vector", and EOI registers.
	 */
	if (is_cppi_enabled()) {
		u32 cppi_tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG);
		u32 cppi_rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG);

		if (cppi_tx || cppi_rx) {
			DBG(4, "CPPI IRQ t%x r%x\n", cppi_tx, cppi_rx);
			cppi_completion(musb, cppi_rx, cppi_tx);
			retval = IRQ_HANDLED;
		}
	}
	cppi = container_of(musb->dma_controller, struct cppi, controller);
	if (is_cppi_enabled() && musb->dma_controller && !cppi->irq)
		retval = cppi_interrupt(irq, __hci);

	/* ack and handle non-CPPI interrupts */
	tmp = musb_readl(tibase, DAVINCI_USB_INT_SRC_MASKED_REG);