diff mbox

[v2,3/4] usb: musb: musb_cppi41: Configure the number of channels for DA8xx

Message ID 20170920073513.11650-4-abailon@baylibre.com (mailing list archive)
State New, archived
Headers show

Commit Message

Alexandre Bailon Sept. 20, 2017, 7:35 a.m. UTC
Currently, the number of channels is set to 15 but in the case of DA8xx,
the number of channels is 4.
Update the driver to configure the number of channels at runtime.

Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
---
 drivers/usb/musb/musb_cppi41.c | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

Comments

Sergei Shtylyov Sept. 20, 2017, 9:21 a.m. UTC | #1
Hello!

On 9/20/2017 10:35 AM, Alexandre Bailon wrote:

> Currently, the number of channels is set to 15 but in the case of DA8xx,
> the number of channels is 4.
> Update the driver to configure the number of channels at runtime.
> 
> Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
> ---
>   drivers/usb/musb/musb_cppi41.c | 31 ++++++++++++++++++++++++++-----
>   1 file changed, 26 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
> index b2b1306c01cf..2d1468cccae0 100644
> --- a/drivers/usb/musb/musb_cppi41.c
> +++ b/drivers/usb/musb/musb_cppi41.c
[...]
> @@ -770,18 +776,33 @@ cppi41_dma_controller_create(struct musb *musb, void __iomem *base)
>   		controller->tdown_reg = DA8XX_USB_TEARDOWN;
>   		controller->autoreq_reg = DA8XX_USB_AUTOREQ;
>   		controller->set_dma_mode = da8xx_set_dma_mode;
> +		controller->num_channels = DA8XX_DMA_NUM_CHANNELS;
>   	} else {
>   		controller->tdown_reg = USB_TDOWN;
>   		controller->autoreq_reg = USB_CTRL_AUTOREQ;
>   		controller->set_dma_mode = cppi41_set_dma_mode;
> +		controller->num_channels = MUSB_DMA_NUM_CHANNELS;
>   	}
>   
> +	channel_size = controller->num_channels *
> +			sizeof(struct cppi41_dma_channel);
> +	controller->rx_channel = kzalloc(channel_size, GFP_KERNEL);
> +	if (controller->rx_channel)

    How can this work? The NULL check is reversed.

> +		goto rx_channel_alloc_fail;
> +	controller->tx_channel = kzalloc(channel_size, GFP_KERNEL);
> +	if (controller->tx_channel)

    Same here.

> +		goto tx_channel_alloc_fail;
> +
>   	ret = cppi41_dma_controller_start(controller);
>   	if (ret)
>   		goto plat_get_fail;
>   	return &controller->controller;
>   
>   plat_get_fail:
> +	kfree(controller->tx_channel);
> +tx_channel_alloc_fail:
> +	kfree(controller->rx_channel);
> +rx_channel_alloc_fail:
>   	kfree(controller);
>   kzalloc_fail:
>   	if (ret == -EPROBE_DEFER)
> 

MBR, Sergei
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alexandre Bailon Sept. 20, 2017, 5:35 p.m. UTC | #2
On 09/20/2017 11:21 AM, Sergei Shtylyov wrote:
> Hello!
> 
> On 9/20/2017 10:35 AM, Alexandre Bailon wrote:
> 
>> Currently, the number of channels is set to 15 but in the case of DA8xx,
>> the number of channels is 4.
>> Update the driver to configure the number of channels at runtime.
>>
>> Signed-off-by: Alexandre Bailon <abailon@baylibre.com>
>> ---
>>   drivers/usb/musb/musb_cppi41.c | 31 ++++++++++++++++++++++++++-----
>>   1 file changed, 26 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/usb/musb/musb_cppi41.c
>> b/drivers/usb/musb/musb_cppi41.c
>> index b2b1306c01cf..2d1468cccae0 100644
>> --- a/drivers/usb/musb/musb_cppi41.c
>> +++ b/drivers/usb/musb/musb_cppi41.c
> [...]
>> @@ -770,18 +776,33 @@ cppi41_dma_controller_create(struct musb *musb,
>> void __iomem *base)
>>           controller->tdown_reg = DA8XX_USB_TEARDOWN;
>>           controller->autoreq_reg = DA8XX_USB_AUTOREQ;
>>           controller->set_dma_mode = da8xx_set_dma_mode;
>> +        controller->num_channels = DA8XX_DMA_NUM_CHANNELS;
>>       } else {
>>           controller->tdown_reg = USB_TDOWN;
>>           controller->autoreq_reg = USB_CTRL_AUTOREQ;
>>           controller->set_dma_mode = cppi41_set_dma_mode;
>> +        controller->num_channels = MUSB_DMA_NUM_CHANNELS;
>>       }
>>   +    channel_size = controller->num_channels *
>> +            sizeof(struct cppi41_dma_channel);
>> +    controller->rx_channel = kzalloc(channel_size, GFP_KERNEL);
>> +    if (controller->rx_channel)
> 
>    How can this work? The NULL check is reversed.
Indeed! That's a good question! I have tested the series before to send
it but I could not explain why it have worked.
Anyway, I will fix it.

Best Regards,
Alexandre
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c
index b2b1306c01cf..2d1468cccae0 100644
--- a/drivers/usb/musb/musb_cppi41.c
+++ b/drivers/usb/musb/musb_cppi41.c
@@ -30,10 +30,12 @@ 
 #define DA8XX_USB_AUTOREQ	0x14
 #define DA8XX_USB_TEARDOWN	0x1c
 
+#define DA8XX_DMA_NUM_CHANNELS 4
+
 struct cppi41_dma_controller {
 	struct dma_controller controller;
-	struct cppi41_dma_channel rx_channel[MUSB_DMA_NUM_CHANNELS];
-	struct cppi41_dma_channel tx_channel[MUSB_DMA_NUM_CHANNELS];
+	struct cppi41_dma_channel *rx_channel;
+	struct cppi41_dma_channel *tx_channel;
 	struct hrtimer early_tx;
 	struct list_head early_tx_list;
 	u32 rx_mode;
@@ -45,6 +47,7 @@  struct cppi41_dma_controller {
 
 	void (*set_dma_mode)(struct cppi41_dma_channel *cppi41_channel,
 			     unsigned int mode);
+	u8 num_channels;
 };
 
 static void save_rx_toggle(struct cppi41_dma_channel *cppi41_channel)
@@ -483,7 +486,7 @@  static struct dma_channel *cppi41_dma_channel_allocate(struct dma_controller *c,
 	struct cppi41_dma_channel *cppi41_channel = NULL;
 	u8 ch_num = hw_ep->epnum - 1;
 
-	if (ch_num >= MUSB_DMA_NUM_CHANNELS)
+	if (ch_num >= controller->num_channels)
 		return NULL;
 
 	if (is_tx)
@@ -643,7 +646,7 @@  static void cppi41_release_all_dma_chans(struct cppi41_dma_controller *ctrl)
 	struct dma_chan *dc;
 	int i;
 
-	for (i = 0; i < MUSB_DMA_NUM_CHANNELS; i++) {
+	for (i = 0; i < ctrl->num_channels; i++) {
 		dc = ctrl->tx_channel[i].dc;
 		if (dc)
 			dma_release_channel(dc);
@@ -695,7 +698,7 @@  static int cppi41_dma_controller_start(struct cppi41_dma_controller *controller)
 			goto err;
 
 		ret = -EINVAL;
-		if (port > MUSB_DMA_NUM_CHANNELS || !port)
+		if (port > controller->num_channels || !port)
 			goto err;
 		if (is_tx)
 			cppi41_channel = &controller->tx_channel[port - 1];
@@ -736,6 +739,8 @@  void cppi41_dma_controller_destroy(struct dma_controller *c)
 
 	hrtimer_cancel(&controller->early_tx);
 	cppi41_dma_controller_stop(controller);
+	kfree(controller->rx_channel);
+	kfree(controller->tx_channel);
 	kfree(controller);
 }
 EXPORT_SYMBOL_GPL(cppi41_dma_controller_destroy);
@@ -744,6 +749,7 @@  struct dma_controller *
 cppi41_dma_controller_create(struct musb *musb, void __iomem *base)
 {
 	struct cppi41_dma_controller *controller;
+	int channel_size;
 	int ret = 0;
 
 	if (!musb->controller->parent->of_node) {
@@ -770,18 +776,33 @@  cppi41_dma_controller_create(struct musb *musb, void __iomem *base)
 		controller->tdown_reg = DA8XX_USB_TEARDOWN;
 		controller->autoreq_reg = DA8XX_USB_AUTOREQ;
 		controller->set_dma_mode = da8xx_set_dma_mode;
+		controller->num_channels = DA8XX_DMA_NUM_CHANNELS;
 	} else {
 		controller->tdown_reg = USB_TDOWN;
 		controller->autoreq_reg = USB_CTRL_AUTOREQ;
 		controller->set_dma_mode = cppi41_set_dma_mode;
+		controller->num_channels = MUSB_DMA_NUM_CHANNELS;
 	}
 
+	channel_size = controller->num_channels *
+			sizeof(struct cppi41_dma_channel);
+	controller->rx_channel = kzalloc(channel_size, GFP_KERNEL);
+	if (controller->rx_channel)
+		goto rx_channel_alloc_fail;
+	controller->tx_channel = kzalloc(channel_size, GFP_KERNEL);
+	if (controller->tx_channel)
+		goto tx_channel_alloc_fail;
+
 	ret = cppi41_dma_controller_start(controller);
 	if (ret)
 		goto plat_get_fail;
 	return &controller->controller;
 
 plat_get_fail:
+	kfree(controller->tx_channel);
+tx_channel_alloc_fail:
+	kfree(controller->rx_channel);
+rx_channel_alloc_fail:
 	kfree(controller);
 kzalloc_fail:
 	if (ret == -EPROBE_DEFER)