[PATCH V2] usb:musb: musbhsdma: change the number of dma channels according to hardware configuration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



According to "musbhdrd usb 2.0 high-speed dual-role controller
Product Specification"
the number of dma channels can be read from register RAMINFO.
it is not always that number of dma channels is MUSB_HSDMA_CHANNELS, some
SOC may have little dma channels.

Signed-off-by: Yingchun Li<sword.l.dragon@xxxxxxxxx>
---
 drivers/usb/musb/musbhsdma.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 3d1fd52..f3c3d62 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -57,7 +57,7 @@ static int dma_controller_stop(struct dma_controller *c)
 		dev_err(musb->controller,
 			"Stopping DMA controller while channel active\n");

-		for (bit = 0; bit < MUSB_HSDMA_CHANNELS; bit++) {
+		for (bit = 0; bit < controller->channel_count; bit++) {
 			if (controller->used_channels & (1 << bit)) {
 				channel = &controller->channel[bit].channel;
 				dma_channel_release(channel);
@@ -80,7 +80,7 @@ static struct dma_channel
*dma_channel_allocate(struct dma_controller *c,
 	struct dma_channel *channel = NULL;
 	u8 bit;

-	for (bit = 0; bit < MUSB_HSDMA_CHANNELS; bit++) {
+	for (bit = 0; bit < controller->channel_count; bit++) {
 		if (!(controller->used_channels & (1 << bit))) {
 			controller->used_channels |= (1 << bit);
 			musb_channel = &(controller->channel[bit]);
@@ -277,7 +277,8 @@ static irqreturn_t dma_controller_irq(int irq,
void *private_data)
 	if (!int_hsdma) {
 		dev_dbg(musb->controller, "spurious DMA irq\n");

-		for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) {
+		for (bchannel = 0; bchannel < controller->channel_count;
+	             bchannel++) {
 			musb_channel = (struct musb_dma_channel *)
 					&(controller->channel[bchannel]);
 			channel = &musb_channel->channel;
@@ -295,7 +296,7 @@ static irqreturn_t dma_controller_irq(int irq,
void *private_data)
 			goto done;
 	}

-	for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) {
+	for (bchannel = 0; bchannel < controller->channel_count; bchannel++) {
 		if (int_hsdma & (1 << bchannel)) {
 			musb_channel = (struct musb_dma_channel *)
 					&(controller->channel[bchannel]);
@@ -386,6 +387,7 @@ struct dma_controller
*dma_controller_create(struct musb *musb, void __iomem *ba
 	struct device *dev = musb->controller;
 	struct platform_device *pdev = to_platform_device(dev);
 	int irq = platform_get_irq_byname(pdev, "dma");
+	u8 count;

 	if (irq <= 0) {
 		dev_err(dev, "No DMA interrupt line!\n");
@@ -396,7 +398,9 @@ struct dma_controller
*dma_controller_create(struct musb *musb, void __iomem *ba
 	if (!controller)
 		return NULL;

-	controller->channel_count = MUSB_HSDMA_CHANNELS;
+	count = musb_readb(musb->mregs, MUSB_RAMINFO) >> 4;
+	controller->channel_count = (count > MUSB_HSDMA_CHANNELS) ?
+					MUSB_HSDMA_CHANNELS : count;
 	controller->private_data = musb;
 	controller->base = base;
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux