[alsa-devel] [PATCH] ASoC: omap-pcm: Lower the dma coherent mask to 32bits
Peter Ujfalusi
peter.ujfalusi at ti.com
Tue Dec 10 10:37:09 CET 2013
Hi Russell,
On 12/09/2013 07:03 PM, Russell King - ARM Linux wrote:
> Yes, that's a good idea. Revised version of the patch. Peter, can you
> retest please, thanks.
With this patch PandaES and BeagleXM works fine on top of today's mainline.
Thank you Russell and Takashi!
Tested-by: Peter Ujfalusi <peter.ujfalusi at ti.com>
> diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
> index f6b6bfa88ecf..86c564e52ea7 100644
> --- a/arch/arm/mm/dma-mapping.c
> +++ b/arch/arm/mm/dma-mapping.c
> @@ -158,6 +158,44 @@ struct dma_map_ops arm_coherent_dma_ops = {
> };
> EXPORT_SYMBOL(arm_coherent_dma_ops);
>
> +static int __dma_supported(struct device *dev, u64 mask, bool warn)
> +{
> + unsigned long max_dma_pfn;
> +
> + /*
> + * If the mask allows for more memory than we can address,
> + * and we actually have that much memory, then we must
> + * indicate that DMA to this device is not supported.
> + */
> + if (sizeof(mask) != sizeof(dma_addr_t) &&
> + mask > (dma_addr_t)~0 &&
> + dma_to_pfn(dev, ~0) < max_pfn) {
> + if (warn) {
> + dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n",
> + mask);
> + dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n");
> + }
> + return 0;
> + }
> +
> + max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
> +
> + /*
> + * Translate the device's DMA mask to a PFN limit. This
> + * PFN number includes the page which we can DMA to.
> + */
> + if (dma_to_pfn(dev, mask) < max_dma_pfn) {
> + if (warn)
> + dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n",
> + mask,
> + dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1,
> + max_dma_pfn + 1);
> + return 0;
> + }
> +
> + return 1;
> +}
> +
> static u64 get_coherent_dma_mask(struct device *dev)
> {
> u64 mask = (u64)DMA_BIT_MASK(32);
> @@ -176,34 +214,8 @@ static u64 get_coherent_dma_mask(struct device *dev)
> return 0;
> }
>
> - max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
> -
> - /*
> - * If the mask allows for more memory than we can address,
> - * and we actually have that much memory, then fail the
> - * allocation.
> - */
> - if (sizeof(mask) != sizeof(dma_addr_t) &&
> - mask > (dma_addr_t)~0 &&
> - dma_to_pfn(dev, ~0) > max_dma_pfn) {
> - dev_warn(dev, "Coherent DMA mask %#llx is larger than dma_addr_t allows\n",
> - mask);
> - dev_warn(dev, "Driver did not use or check the return value from dma_set_coherent_mask()?\n");
> - return 0;
> - }
> -
> - /*
> - * Now check that the mask, when translated to a PFN,
> - * fits within the allowable addresses which we can
> - * allocate.
> - */
> - if (dma_to_pfn(dev, mask) < max_dma_pfn) {
> - dev_warn(dev, "Coherent DMA mask %#llx (pfn %#lx-%#lx) covers a smaller range of system memory than the DMA zone pfn 0x0-%#lx\n",
> - mask,
> - dma_to_pfn(dev, 0), dma_to_pfn(dev, mask) + 1,
> - arm_dma_pfn_limit + 1);
> + if (!__dma_supported(dev, mask, true))
> return 0;
> - }
> }
>
> return mask;
> @@ -1032,28 +1044,7 @@ void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
> */
> int dma_supported(struct device *dev, u64 mask)
> {
> - unsigned long limit;
> -
> - /*
> - * If the mask allows for more memory than we can address,
> - * and we actually have that much memory, then we must
> - * indicate that DMA to this device is not supported.
> - */
> - if (sizeof(mask) != sizeof(dma_addr_t) &&
> - mask > (dma_addr_t)~0 &&
> - dma_to_pfn(dev, ~0) > arm_dma_pfn_limit)
> - return 0;
> -
> - /*
> - * Translate the device's DMA mask to a PFN limit. This
> - * PFN number includes the page which we can DMA to.
> - */
> - limit = dma_to_pfn(dev, mask);
> -
> - if (limit < arm_dma_pfn_limit)
> - return 0;
> -
> - return 1;
> + return __dma_supported(dev, mask, false);
> }
> EXPORT_SYMBOL(dma_supported);
>
>
--
Péter
More information about the Alsa-devel
mailing list