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.dra...@gmail.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to