linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* i.MX SDMA patches
@ 2011-08-25  9:03 Sascha Hauer
  2011-08-25  9:03 ` [PATCH 1/3] dmaengine i.MX SDMA: lock channel 0 Sascha Hauer
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Sascha Hauer @ 2011-08-25  9:03 UTC (permalink / raw)
  To: linux-arm-kernel

The following series has some i.MX SDMA fixes. The first two
should go into -rc, the third either in -rc or next. It fixes
that the driver blocks in probe() when the driver is compiled
into the kernel but the firmware is not. From this point of
view it should go in -rc, but on the other hand it's no straight
forward fix.

Sascha

Sascha Hauer (3):
      dmaengine i.MX SDMA: lock channel 0
      dmaengine i.MX SDMA: set firmware scripts addresses to negative value initially
      dmaengine i.MX SDMA: use request_firmware_nowait

 drivers/dma/imx-sdma.c |   47 ++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 38 insertions(+), 9 deletions(-)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/3] dmaengine i.MX SDMA: lock channel 0
  2011-08-25  9:03 i.MX SDMA patches Sascha Hauer
@ 2011-08-25  9:03 ` Sascha Hauer
  2011-08-25  9:03 ` [PATCH 2/3] dmaengine i.MX SDMA: set firmware scripts addresses to negative value initially Sascha Hauer
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2011-08-25  9:03 UTC (permalink / raw)
  To: linux-arm-kernel

channel0 of the sdma engine is the configuration channel. It
is a shared resource and thus must be protected by a mutex.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/dma/imx-sdma.c |   18 ++++++++++++++++--
 1 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 7bd7e98..f50c87c 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -318,6 +318,7 @@ struct sdma_engine {
 	dma_addr_t			context_phys;
 	struct dma_device		dma_device;
 	struct clk			*clk;
+	struct mutex			channel_0_lock;
 	struct sdma_script_start_addrs	*script_addrs;
 };
 
@@ -415,11 +416,15 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
 	dma_addr_t buf_phys;
 	int ret;
 
+	mutex_lock(&sdma->channel_0_lock);
+
 	buf_virt = dma_alloc_coherent(NULL,
 			size,
 			&buf_phys, GFP_KERNEL);
-	if (!buf_virt)
-		return -ENOMEM;
+	if (!buf_virt) {
+		ret = -ENOMEM;
+		goto err_out;
+	}
 
 	bd0->mode.command = C0_SETPM;
 	bd0->mode.status = BD_DONE | BD_INTR | BD_WRAP | BD_EXTD;
@@ -433,6 +438,9 @@ static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size,
 
 	dma_free_coherent(NULL, size, buf_virt, buf_phys);
 
+err_out:
+	mutex_unlock(&sdma->channel_0_lock);
+
 	return ret;
 }
 
@@ -656,6 +664,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
 	dev_dbg(sdma->dev, "event_mask0 = 0x%08x\n", sdmac->event_mask0);
 	dev_dbg(sdma->dev, "event_mask1 = 0x%08x\n", sdmac->event_mask1);
 
+	mutex_lock(&sdma->channel_0_lock);
+
 	memset(context, 0, sizeof(*context));
 	context->channel_state.pc = load_address;
 
@@ -676,6 +686,8 @@ static int sdma_load_context(struct sdma_channel *sdmac)
 
 	ret = sdma_run_channel(&sdma->channel[0]);
 
+	mutex_unlock(&sdma->channel_0_lock);
+
 	return ret;
 }
 
@@ -1274,6 +1286,8 @@ static int __init sdma_probe(struct platform_device *pdev)
 	if (!sdma)
 		return -ENOMEM;
 
+	mutex_init(&sdma->channel_0_lock);
+
 	sdma->dev = &pdev->dev;
 
 	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/3] dmaengine i.MX SDMA: set firmware scripts addresses to negative value initially
  2011-08-25  9:03 i.MX SDMA patches Sascha Hauer
  2011-08-25  9:03 ` [PATCH 1/3] dmaengine i.MX SDMA: lock channel 0 Sascha Hauer
@ 2011-08-25  9:03 ` Sascha Hauer
  2011-08-25  9:03 ` [PATCH 3/3] dmaengine i.MX SDMA: use request_firmware_nowait Sascha Hauer
  2011-08-29 14:41 ` i.MX SDMA patches Vinod Koul
  3 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2011-08-25  9:03 UTC (permalink / raw)
  To: linux-arm-kernel

If we do not have a firmare script for a given transfer,
the setup of this channel must fail. For this the script
addresses have to be < 0 initially, not 0.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/dma/imx-sdma.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index f50c87c..8abf8c1 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1281,6 +1281,7 @@ static int __init sdma_probe(struct platform_device *pdev)
 	struct sdma_platform_data *pdata = pdev->dev.platform_data;
 	int i;
 	struct sdma_engine *sdma;
+	s32 *saddr_arr;
 
 	sdma = kzalloc(sizeof(*sdma), GFP_KERNEL);
 	if (!sdma)
@@ -1324,6 +1325,11 @@ static int __init sdma_probe(struct platform_device *pdev)
 		goto err_alloc;
 	}
 
+	/* initially no scripts available */
+	saddr_arr = (s32 *)sdma->script_addrs;
+	for (i = 0; i < SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1; i++)
+		saddr_arr[i] = -EINVAL;
+
 	if (of_id)
 		pdev->id_entry = of_id->data;
 	sdma->devtype = pdev->id_entry->driver_data;
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/3] dmaengine i.MX SDMA: use request_firmware_nowait
  2011-08-25  9:03 i.MX SDMA patches Sascha Hauer
  2011-08-25  9:03 ` [PATCH 1/3] dmaengine i.MX SDMA: lock channel 0 Sascha Hauer
  2011-08-25  9:03 ` [PATCH 2/3] dmaengine i.MX SDMA: set firmware scripts addresses to negative value initially Sascha Hauer
@ 2011-08-25  9:03 ` Sascha Hauer
  2011-08-25 18:01   ` Koul, Vinod
  2011-08-29 14:41 ` i.MX SDMA patches Vinod Koul
  3 siblings, 1 reply; 7+ messages in thread
From: Sascha Hauer @ 2011-08-25  9:03 UTC (permalink / raw)
  To: linux-arm-kernel

The firmware blob may not be available when the driver
probes. Instead of blocking the whole kernel use
request_firmware_nowait() and continue without firmware.
The ROM scripts can already be used then if available.
For the devicetree case the ROM scripts are not available,
still the probe function should not block. The driver
will be unusable in this case, but we have no way of
detecting this properly. The configuration of the dma
channels will fail, so nothing bad should happen.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/dma/imx-sdma.c |   23 ++++++++++++++++-------
 1 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 8abf8c1..b5cc27d 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1143,18 +1143,17 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
 			saddr_arr[i] = addr_arr[i];
 }
 
-static int __init sdma_get_firmware(struct sdma_engine *sdma,
-		const char *fw_name)
+static void sdma_load_firmware(const struct firmware *fw, void *context)
 {
-	const struct firmware *fw;
+	struct sdma_engine *sdma = context;
 	const struct sdma_firmware_header *header;
-	int ret;
 	const struct sdma_script_start_addrs *addr;
 	unsigned short *ram_code;
 
-	ret = request_firmware(&fw, fw_name, sdma->dev);
-	if (ret)
-		return ret;
+	if (!fw) {
+		dev_err(sdma->dev, "firmware not found\n");
+		return;
+	}
 
 	if (fw->size < sizeof(*header))
 		goto err_firmware;
@@ -1184,6 +1183,16 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma,
 
 err_firmware:
 	release_firmware(fw);
+}
+
+static int __init sdma_get_firmware(struct sdma_engine *sdma,
+		const char *fw_name)
+{
+	int ret;
+
+	ret = request_firmware_nowait(THIS_MODULE,
+			FW_ACTION_HOTPLUG, fw_name, sdma->dev,
+			GFP_KERNEL, sdma, sdma_load_firmware);
 
 	return ret;
 }
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/3] dmaengine i.MX SDMA: use request_firmware_nowait
  2011-08-25  9:03 ` [PATCH 3/3] dmaengine i.MX SDMA: use request_firmware_nowait Sascha Hauer
@ 2011-08-25 18:01   ` Koul, Vinod
  2011-08-26  6:47     ` Sascha Hauer
  0 siblings, 1 reply; 7+ messages in thread
From: Koul, Vinod @ 2011-08-25 18:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2011-08-25 at 11:03 +0200, Sascha Hauer wrote:
> The firmware blob may not be available when the driver
> probes. Instead of blocking the whole kernel use
> request_firmware_nowait() and continue without firmware.
> The ROM scripts can already be used then if available.
> For the devicetree case the ROM scripts are not available,
> still the probe function should not block. The driver
> will be unusable in this case, but we have no way of
> detecting this properly. The configuration of the dma
> channels will fail, so nothing bad should happen.
Shouldn't you track if firmware is loaded properly and in the case it is
not return error in your prepare functions?

--
~Vinod
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  drivers/dma/imx-sdma.c |   23 ++++++++++++++++-------
>  1 files changed, 16 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index 8abf8c1..b5cc27d 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -1143,18 +1143,17 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
>  			saddr_arr[i] = addr_arr[i];
>  }
>  
> -static int __init sdma_get_firmware(struct sdma_engine *sdma,
> -		const char *fw_name)
> +static void sdma_load_firmware(const struct firmware *fw, void *context)
>  {
> -	const struct firmware *fw;
> +	struct sdma_engine *sdma = context;
>  	const struct sdma_firmware_header *header;
> -	int ret;
>  	const struct sdma_script_start_addrs *addr;
>  	unsigned short *ram_code;
>  
> -	ret = request_firmware(&fw, fw_name, sdma->dev);
> -	if (ret)
> -		return ret;
> +	if (!fw) {
> +		dev_err(sdma->dev, "firmware not found\n");
> +		return;
> +	}
>  
>  	if (fw->size < sizeof(*header))
>  		goto err_firmware;
> @@ -1184,6 +1183,16 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma,
>  
>  err_firmware:
>  	release_firmware(fw);
> +}
> +
> +static int __init sdma_get_firmware(struct sdma_engine *sdma,
> +		const char *fw_name)
> +{
> +	int ret;
> +
> +	ret = request_firmware_nowait(THIS_MODULE,
> +			FW_ACTION_HOTPLUG, fw_name, sdma->dev,
> +			GFP_KERNEL, sdma, sdma_load_firmware);
>  
>  	return ret;
>  }

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/3] dmaengine i.MX SDMA: use request_firmware_nowait
  2011-08-25 18:01   ` Koul, Vinod
@ 2011-08-26  6:47     ` Sascha Hauer
  0 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2011-08-26  6:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Aug 25, 2011 at 11:31:57PM +0530, Koul, Vinod wrote:
> On Thu, 2011-08-25 at 11:03 +0200, Sascha Hauer wrote:
> > The firmware blob may not be available when the driver
> > probes. Instead of blocking the whole kernel use
> > request_firmware_nowait() and continue without firmware.
> > The ROM scripts can already be used then if available.
> > For the devicetree case the ROM scripts are not available,
> > still the probe function should not block. The driver
> > will be unusable in this case, but we have no way of
> > detecting this properly. The configuration of the dma
> > channels will fail, so nothing bad should happen.
> Shouldn't you track if firmware is loaded properly and in the case it is
> not return error in your prepare functions?

Parts of the firmware is in ROM, enough to handle many transfer
types. The RAM firmware only offers additional transfer types.
Which transfer types are available is tracked in sdma->script_addrs.
The firmware loader just adds values here. The DMA_SLAVE_CONFIG
call will fail if a needed piece of firmware is missing.

Sascha

> --
> ~Vinod
> > 
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> >  drivers/dma/imx-sdma.c |   23 ++++++++++++++++-------
> >  1 files changed, 16 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> > index 8abf8c1..b5cc27d 100644
> > --- a/drivers/dma/imx-sdma.c
> > +++ b/drivers/dma/imx-sdma.c
> > @@ -1143,18 +1143,17 @@ static void sdma_add_scripts(struct sdma_engine *sdma,
> >  			saddr_arr[i] = addr_arr[i];
> >  }
> >  
> > -static int __init sdma_get_firmware(struct sdma_engine *sdma,
> > -		const char *fw_name)
> > +static void sdma_load_firmware(const struct firmware *fw, void *context)
> >  {
> > -	const struct firmware *fw;
> > +	struct sdma_engine *sdma = context;
> >  	const struct sdma_firmware_header *header;
> > -	int ret;
> >  	const struct sdma_script_start_addrs *addr;
> >  	unsigned short *ram_code;
> >  
> > -	ret = request_firmware(&fw, fw_name, sdma->dev);
> > -	if (ret)
> > -		return ret;
> > +	if (!fw) {
> > +		dev_err(sdma->dev, "firmware not found\n");
> > +		return;
> > +	}
> >  
> >  	if (fw->size < sizeof(*header))
> >  		goto err_firmware;
> > @@ -1184,6 +1183,16 @@ static int __init sdma_get_firmware(struct sdma_engine *sdma,
> >  
> >  err_firmware:
> >  	release_firmware(fw);
> > +}
> > +
> > +static int __init sdma_get_firmware(struct sdma_engine *sdma,
> > +		const char *fw_name)
> > +{
> > +	int ret;
> > +
> > +	ret = request_firmware_nowait(THIS_MODULE,
> > +			FW_ACTION_HOTPLUG, fw_name, sdma->dev,
> > +			GFP_KERNEL, sdma, sdma_load_firmware);
> >  
> >  	return ret;
> >  }
> 
> 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 7+ messages in thread

* i.MX SDMA patches
  2011-08-25  9:03 i.MX SDMA patches Sascha Hauer
                   ` (2 preceding siblings ...)
  2011-08-25  9:03 ` [PATCH 3/3] dmaengine i.MX SDMA: use request_firmware_nowait Sascha Hauer
@ 2011-08-29 14:41 ` Vinod Koul
  3 siblings, 0 replies; 7+ messages in thread
From: Vinod Koul @ 2011-08-29 14:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 2011-08-25 at 11:03 +0200, Sascha Hauer wrote:
> The following series has some i.MX SDMA fixes. The first two
> should go into -rc, the third either in -rc or next. It fixes
> that the driver blocks in probe() when the driver is compiled
> into the kernel but the firmware is not. From this point of
> view it should go in -rc, but on the other hand it's no straight
> forward fix.
> 
> Sascha
> 
> Sascha Hauer (3):
>       dmaengine i.MX SDMA: lock channel 0
>       dmaengine i.MX SDMA: set firmware scripts addresses to negative value initially
>       dmaengine i.MX SDMA: use request_firmware_nowait
> 
>  drivers/dma/imx-sdma.c |   47 ++++++++++++++++++++++++++++++++++++++---------
>  1 files changed, 38 insertions(+), 9 deletions(-)
Applied, Thanks

-- 
~Vinod

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-08-29 14:41 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-08-25  9:03 i.MX SDMA patches Sascha Hauer
2011-08-25  9:03 ` [PATCH 1/3] dmaengine i.MX SDMA: lock channel 0 Sascha Hauer
2011-08-25  9:03 ` [PATCH 2/3] dmaengine i.MX SDMA: set firmware scripts addresses to negative value initially Sascha Hauer
2011-08-25  9:03 ` [PATCH 3/3] dmaengine i.MX SDMA: use request_firmware_nowait Sascha Hauer
2011-08-25 18:01   ` Koul, Vinod
2011-08-26  6:47     ` Sascha Hauer
2011-08-29 14:41 ` i.MX SDMA patches Vinod Koul

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).