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