Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1e780e6e authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: pil: Use dma_alloc_coherent instead of Ion"

parents d1886f80 910ab193
Loading
Loading
Loading
Loading
+52 −43
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@
#include <linux/jiffies.h>
#include <linux/wakelock.h>
#include <linux/err.h>
#include <linux/msm_ion.h>
#include <linux/list.h>
#include <linux/list_sort.h>
#include <linux/idr.h>
@@ -33,6 +32,7 @@
#include <linux/of_gpio.h>
#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <soc/qcom/ramdump.h>
#include <soc/qcom/subsystem_restart.h>

@@ -133,10 +133,11 @@ struct pil_priv {
	phys_addr_t base_addr;
	phys_addr_t region_start;
	phys_addr_t region_end;
	struct ion_handle *region;
	void *region;
	struct pil_image_info __iomem *info;
	int id;
	int unvoted_flag;
	size_t region_size;
};

/**
@@ -175,8 +176,6 @@ int pil_do_ramdump(struct pil_desc *desc, void *ramdump_dev)
}
EXPORT_SYMBOL(pil_do_ramdump);

static struct ion_client *ion;

/**
 * pil_get_entry_addr() - Retrieve the entry address of a peripheral image
 * @desc: descriptor from pil_desc_init()
@@ -361,10 +360,10 @@ static int pil_init_entry_addr(struct pil_priv *priv, const struct pil_mdt *mdt)
static int pil_alloc_region(struct pil_priv *priv, phys_addr_t min_addr,
				phys_addr_t max_addr, size_t align)
{
	struct ion_handle *region;
	int ret;
	unsigned int mask;
	void *region;
	size_t size = max_addr - min_addr;
	size_t aligned_size;
	DEFINE_DMA_ATTRS(attrs);

	/* Don't reallocate due to fragmentation concerns, just sanity check */
	if (priv->region) {
@@ -374,36 +373,24 @@ static int pil_alloc_region(struct pil_priv *priv, phys_addr_t min_addr,
		return 0;
	}

	if (!ion) {
		WARN_ON_ONCE("No ION client, can't support relocation\n");
		return -ENOMEM;
	}
	if (align > SZ_4M)
		aligned_size = ALIGN(size, SZ_4M);
	else
		aligned_size = ALIGN(size, SZ_1M);

	/* Force alignment due to linker scripts not getting it right */
	if (align > SZ_1M) {
		mask = ION_HEAP(ION_PIL2_HEAP_ID);
		align = SZ_4M;
	} else {
		mask = ION_HEAP(ION_PIL1_HEAP_ID);
		align = SZ_1M;
	}
	region = dma_alloc_attrs(priv->desc->dev, aligned_size,
				&priv->region_start, GFP_KERNEL, &attrs);

	region = ion_alloc(ion, size, align, mask, 0);
	if (IS_ERR(region)) {
		pil_err(priv->desc, "Failed to allocate relocatable region\n");
		return PTR_ERR(region);
	}

	ret = ion_phys(ion, region, (ion_phys_addr_t *)&priv->region_start,
			&size);
	if (ret) {
		ion_free(ion, region);
		return ret;
	if (region == NULL) {
		pil_err(priv->desc, "Failed to allocate relocatable region of size %zx\n",
					size);
		return -ENOMEM;
	}

	priv->region = region;
	priv->region_end = priv->region_start + size;
	priv->base_addr = min_addr;
	priv->region_size = aligned_size;

	return 0;
}
@@ -534,13 +521,29 @@ static void pil_release_mmap(struct pil_desc *desc)

#define IOMAP_SIZE SZ_1M

struct pil_map_fw_info {
	int relocated;
	void *region;
	phys_addr_t base_addr;
};

static void *map_fw_mem(phys_addr_t paddr, size_t size, void *data)
{
	struct pil_map_fw_info *info = data;

	if (info && info->relocated && info->region)
		return info->region + (paddr - info->base_addr);

	return ioremap(paddr, size);
}

static void unmap_fw_mem(void *vaddr, void *data)
{
	struct pil_map_fw_info *info = data;

	if (info && info->relocated && info->region)
		return;

	iounmap(vaddr);
}

@@ -550,13 +553,19 @@ static int pil_load_seg(struct pil_desc *desc, struct pil_seg *seg)
	phys_addr_t paddr;
	char fw_name[30];
	int num = seg->num;
	struct pil_map_fw_info map_fw_info = {
		.relocated = seg->relocated,
		.region = desc->priv->region,
		.base_addr = desc->priv->region_start,
	};
	void *map_data = desc->map_data ? desc->map_data : &map_fw_info;

	if (seg->filesz) {
		snprintf(fw_name, ARRAY_SIZE(fw_name), "%s.b%02d",
				desc->name, num);
		ret = request_firmware_direct(fw_name, desc->dev, seg->paddr,
					      seg->filesz, desc->map_fw_mem,
					      desc->unmap_fw_mem, NULL);
					      desc->unmap_fw_mem, map_data);
		if (ret < 0) {
			pil_err(desc, "Failed to locate blob %s or blob is too big.\n",
				fw_name);
@@ -581,7 +590,7 @@ static int pil_load_seg(struct pil_desc *desc, struct pil_seg *seg)
		u8 bytes_after;

		orig_size = size = min_t(size_t, IOMAP_SIZE, count);
		buf = ioremap(paddr, size);
		buf = desc->map_fw_mem(paddr, size, map_data);
		if (!buf) {
			pil_err(desc, "Failed to map memory\n");
			return -ENOMEM;
@@ -601,7 +610,8 @@ static int pil_load_seg(struct pil_desc *desc, struct pil_seg *seg)
		}

		memset(buf, 0, size);
		iounmap(buf);

		desc->unmap_fw_mem(buf, map_data);

		count -= orig_size;
		paddr += orig_size;
@@ -754,7 +764,8 @@ out:
	up_read(&pil_pm_rwsem);
	if (ret) {
		if (priv->region) {
			ion_free(ion, priv->region);
			dma_free_coherent(desc->dev, priv->region_size,
					priv->region, priv->region_start);
			priv->region = NULL;
		}
		pil_release_mmap(desc);
@@ -778,13 +789,16 @@ void pil_shutdown(struct pil_desc *desc)
		disable_irq(desc->proxy_unvote_irq);
		if (!desc->priv->unvoted_flag)
			pil_proxy_unvote(desc, 1);
		return;
	}

	if (!proxy_timeout_ms)
	} else if (!proxy_timeout_ms)
		pil_proxy_unvote(desc, 1);
	else
		flush_delayed_work(&priv->proxy);

	if (priv->region) {
		dma_free_coherent(desc->dev, priv->region_size,
				priv->region, priv->region_start);
		priv->region = NULL;
	}
}
EXPORT_SYMBOL(pil_shutdown);

@@ -922,9 +936,6 @@ static int __init msm_pil_init(void)
		pr_warn("pil: failed to find qcom,msm-imem-pil node\n");
	}

	ion = msm_ion_client_create(UINT_MAX, "pil");
	if (IS_ERR(ion)) /* Can't support relocatable images */
		ion = NULL;
	return register_pm_notifier(&pil_pm_notifier);
}
device_initcall(msm_pil_init);
@@ -932,8 +943,6 @@ device_initcall(msm_pil_init);
static void __exit msm_pil_exit(void)
{
	unregister_pm_notifier(&pil_pm_notifier);
	if (ion)
		ion_client_destroy(ion);
	if (pil_info_base)
		iounmap(pil_info_base);
}
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ struct pil_desc {
	unsigned int proxy_unvote_irq;
	void * (*map_fw_mem)(phys_addr_t phys, size_t size, void *data);
	void (*unmap_fw_mem)(void *virt, void *data);
	void *map_data;
};

/**