remoteproc: Move qcom_mdt_loader into drivers/soc/qcom
authorBjorn Andersson <bjorn.andersson@linaro.org>
Fri, 27 Jan 2017 11:12:57 +0000 (03:12 -0800)
committerBjorn Andersson <bjorn.andersson@linaro.org>
Mon, 6 Feb 2017 16:57:25 +0000 (08:57 -0800)
With the remoteproc parts cleaned out of the MDT loader we can move it
to drivers/soc/qcom.

Acked-by: Andy Gross <andy.gross@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
drivers/remoteproc/Kconfig
drivers/remoteproc/Makefile
drivers/remoteproc/qcom_adsp_pil.c
drivers/remoteproc/qcom_mdt_loader.c [deleted file]
drivers/remoteproc/qcom_mdt_loader.h [deleted file]
drivers/remoteproc/qcom_q6v5_pil.c
drivers/remoteproc/qcom_wcnss.c
drivers/soc/qcom/Kconfig
drivers/soc/qcom/Makefile
drivers/soc/qcom/mdt_loader.c [new file with mode: 0644]
include/linux/soc/qcom/mdt_loader.h [new file with mode: 0644]

index 71ea703190c6520a5cebe15ba493e03b994a16ee..555dba04b5ae272fa060d58956d851ba6826a33c 100644 (file)
@@ -87,9 +87,6 @@ config QCOM_ADSP_PIL
 config QCOM_RPROC_COMMON
        tristate
 
-config QCOM_MDT_LOADER
-       tristate
-
 config QCOM_Q6V5_PIL
        tristate "Qualcomm Hexagon V5 Peripherial Image Loader"
        depends on OF && ARCH_QCOM
index d4f9525a226d88f9f41a2593ec756251c847bad1..ffc5e430df279a451a7d96313b3fe8107b301a02 100644 (file)
@@ -12,7 +12,6 @@ obj-$(CONFIG_OMAP_REMOTEPROC)         += omap_remoteproc.o
 obj-$(CONFIG_WKUP_M3_RPROC)            += wkup_m3_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC)         += da8xx_remoteproc.o
 obj-$(CONFIG_QCOM_ADSP_PIL)            += qcom_adsp_pil.o
-obj-$(CONFIG_QCOM_MDT_LOADER)          += qcom_mdt_loader.o
 obj-$(CONFIG_QCOM_RPROC_COMMON)                += qcom_common.o
 obj-$(CONFIG_QCOM_Q6V5_PIL)            += qcom_q6v5_pil.o
 obj-$(CONFIG_QCOM_WCNSS_PIL)           += qcom_wcnss_pil.o
index c1ee5c818b4222166811bed27ae4a76be1888194..301b820216f64998c678882f9b11b787144d35db 100644 (file)
 #include <linux/qcom_scm.h>
 #include <linux/regulator/consumer.h>
 #include <linux/remoteproc.h>
+#include <linux/soc/qcom/mdt_loader.h>
 #include <linux/soc/qcom/smem.h>
 #include <linux/soc/qcom/smem_state.h>
 
 #include "qcom_common.h"
-#include "qcom_mdt_loader.h"
 #include "remoteproc_internal.h"
 
 struct adsp_data {
diff --git a/drivers/remoteproc/qcom_mdt_loader.c b/drivers/remoteproc/qcom_mdt_loader.c
deleted file mode 100644 (file)
index 790ab31..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Qualcomm Peripheral Image Loader
- *
- * Copyright (C) 2016 Linaro Ltd
- * Copyright (C) 2015 Sony Mobile Communications Inc
- * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/device.h>
-#include <linux/elf.h>
-#include <linux/firmware.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/qcom_scm.h>
-#include <linux/sizes.h>
-#include <linux/slab.h>
-
-#include "qcom_mdt_loader.h"
-
-static bool mdt_phdr_valid(const struct elf32_phdr *phdr)
-{
-       if (phdr->p_type != PT_LOAD)
-               return false;
-
-       if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH)
-               return false;
-
-       if (!phdr->p_memsz)
-               return false;
-
-       return true;
-}
-
-/**
- * qcom_mdt_get_size() - acquire size of the memory region needed to load mdt
- * @fw:                firmware object for the mdt file
- *
- * Returns size of the loaded firmware blob, or -EINVAL on failure.
- */
-ssize_t qcom_mdt_get_size(const struct firmware *fw)
-{
-       const struct elf32_phdr *phdrs;
-       const struct elf32_phdr *phdr;
-       const struct elf32_hdr *ehdr;
-       phys_addr_t min_addr = (phys_addr_t)ULLONG_MAX;
-       phys_addr_t max_addr = 0;
-       int i;
-
-       ehdr = (struct elf32_hdr *)fw->data;
-       phdrs = (struct elf32_phdr *)(ehdr + 1);
-
-       for (i = 0; i < ehdr->e_phnum; i++) {
-               phdr = &phdrs[i];
-
-               if (!mdt_phdr_valid(phdr))
-                       continue;
-
-               if (phdr->p_paddr < min_addr)
-                       min_addr = phdr->p_paddr;
-
-               if (phdr->p_paddr + phdr->p_memsz > max_addr)
-                       max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K);
-       }
-
-       return min_addr < max_addr ? max_addr - min_addr : -EINVAL;
-}
-EXPORT_SYMBOL_GPL(qcom_mdt_get_size);
-
-/**
- * qcom_mdt_load() - load the firmware which header is loaded as fw
- * @dev:       device handle to associate resources with
- * @fw:                firmware object for the mdt file
- * @firmware:  name of the firmware, for construction of segment file names
- * @pas_id:    PAS identifier
- * @mem_region:        allocated memory region to load firmware into
- * @mem_phys:  physical address of allocated memory region
- * @mem_size:  size of the allocated memory region
- *
- * Returns 0 on success, negative errno otherwise.
- */
-int qcom_mdt_load(struct device *dev, const struct firmware *fw,
-                 const char *firmware, int pas_id, void *mem_region,
-                 phys_addr_t mem_phys, size_t mem_size)
-{
-       const struct elf32_phdr *phdrs;
-       const struct elf32_phdr *phdr;
-       const struct elf32_hdr *ehdr;
-       const struct firmware *seg_fw;
-       phys_addr_t mem_reloc;
-       phys_addr_t min_addr = (phys_addr_t)ULLONG_MAX;
-       phys_addr_t max_addr = 0;
-       size_t fw_name_len;
-       size_t offset;
-       char *fw_name;
-       bool relocate = false;
-       void *ptr;
-       int ret;
-       int i;
-
-       if (!fw || !mem_region || !mem_phys || !mem_size)
-               return -EINVAL;
-
-       ehdr = (struct elf32_hdr *)fw->data;
-       phdrs = (struct elf32_phdr *)(ehdr + 1);
-
-       fw_name_len = strlen(firmware);
-       if (fw_name_len <= 4)
-               return -EINVAL;
-
-       fw_name = kstrdup(firmware, GFP_KERNEL);
-       if (!fw_name)
-               return -ENOMEM;
-
-       ret = qcom_scm_pas_init_image(pas_id, fw->data, fw->size);
-       if (ret) {
-               dev_err(dev, "invalid firmware metadata\n");
-               goto out;
-       }
-
-       for (i = 0; i < ehdr->e_phnum; i++) {
-               phdr = &phdrs[i];
-
-               if (!mdt_phdr_valid(phdr))
-                       continue;
-
-               if (phdr->p_flags & QCOM_MDT_RELOCATABLE)
-                       relocate = true;
-
-               if (phdr->p_paddr < min_addr)
-                       min_addr = phdr->p_paddr;
-
-               if (phdr->p_paddr + phdr->p_memsz > max_addr)
-                       max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K);
-       }
-
-       if (relocate) {
-               ret = qcom_scm_pas_mem_setup(pas_id, mem_phys, max_addr - min_addr);
-               if (ret) {
-                       dev_err(dev, "unable to setup relocation\n");
-                       goto out;
-               }
-
-               /*
-                * The image is relocatable, so offset each segment based on
-                * the lowest segment address.
-                */
-               mem_reloc = min_addr;
-       } else {
-               /*
-                * Image is not relocatable, so offset each segment based on
-                * the allocated physical chunk of memory.
-                */
-               mem_reloc = mem_phys;
-       }
-
-       for (i = 0; i < ehdr->e_phnum; i++) {
-               phdr = &phdrs[i];
-
-               if (!mdt_phdr_valid(phdr))
-                       continue;
-
-               offset = phdr->p_paddr - mem_reloc;
-               if (offset < 0 || offset + phdr->p_memsz > mem_size) {
-                       dev_err(dev, "segment outside memory range\n");
-                       ret = -EINVAL;
-                       break;
-               }
-
-               ptr = mem_region + offset;
-
-               if (phdr->p_filesz) {
-                       sprintf(fw_name + fw_name_len - 3, "b%02d", i);
-                       ret = request_firmware(&seg_fw, fw_name, dev);
-                       if (ret) {
-                               dev_err(dev, "failed to load %s\n", fw_name);
-                               break;
-                       }
-
-                       memcpy(ptr, seg_fw->data, seg_fw->size);
-
-                       release_firmware(seg_fw);
-               }
-
-               if (phdr->p_memsz > phdr->p_filesz)
-                       memset(ptr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
-       }
-
-out:
-       kfree(fw_name);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(qcom_mdt_load);
-
-MODULE_DESCRIPTION("Firmware parser for Qualcomm MDT format");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/remoteproc/qcom_mdt_loader.h b/drivers/remoteproc/qcom_mdt_loader.h
deleted file mode 100644 (file)
index ff6e45b..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __QCOM_MDT_LOADER_H__
-#define __QCOM_MDT_LOADER_H__
-
-#define QCOM_MDT_TYPE_MASK     (7 << 24)
-#define QCOM_MDT_TYPE_HASH     (2 << 24)
-#define QCOM_MDT_RELOCATABLE   BIT(27)
-
-ssize_t qcom_mdt_get_size(const struct firmware *fw);
-int qcom_mdt_load(struct device *dev, const struct firmware *fw,
-                 const char *fw_name, int pas_id, void *mem_region,
-                 phys_addr_t mem_phys, size_t mem_size);
-
-#endif
index 2e44c06e604a183ffb72d0f35a9c30b6a6f51fbd..b129261d7e5e9f3cf961d20aee1e1dc410672cbb 100644 (file)
 #include <linux/regulator/consumer.h>
 #include <linux/remoteproc.h>
 #include <linux/reset.h>
+#include <linux/soc/qcom/mdt_loader.h>
 #include <linux/soc/qcom/smem.h>
 #include <linux/soc/qcom/smem_state.h>
 
 #include "remoteproc_internal.h"
 #include "qcom_common.h"
-#include "qcom_mdt_loader.h"
 
 #include <linux/qcom_scm.h>
 
index fbb25ea4ae8a6feb42aabf452674becc36f6f027..781211c144c6c608201d6b7bae352a7a365c389a 100644 (file)
 #include <linux/qcom_scm.h>
 #include <linux/regulator/consumer.h>
 #include <linux/remoteproc.h>
+#include <linux/soc/qcom/mdt_loader.h>
 #include <linux/soc/qcom/smem.h>
 #include <linux/soc/qcom/smem_state.h>
 #include <linux/rpmsg/qcom_smd.h>
 
 #include "qcom_common.h"
-#include "qcom_mdt_loader.h"
 #include "remoteproc_internal.h"
 #include "qcom_wcnss.h"
 
index 461b387d03cce53b658dd762a1587b11dc5aec01..78b1bb7bcf20ab1e3c39d7d3817b3ae3570825be 100644 (file)
@@ -10,6 +10,10 @@ config QCOM_GSBI
           functions for connecting the underlying serial UART, SPI, and I2C
           devices to the output pins.
 
+config QCOM_MDT_LOADER
+       tristate
+       select QCOM_SCM
+
 config QCOM_PM
        bool "Qualcomm Power Management"
        depends on ARCH_QCOM && !ARM64
index fdd664edf0bdf3cdc7e468ccec62eae5770fae3a..1f30260b06b8f39ffa04d51e9b13b41c19c7b988 100644 (file)
@@ -1,4 +1,5 @@
 obj-$(CONFIG_QCOM_GSBI)        +=      qcom_gsbi.o
+obj-$(CONFIG_QCOM_MDT_LOADER)  += mdt_loader.o
 obj-$(CONFIG_QCOM_PM)  +=      spm.o
 obj-$(CONFIG_QCOM_SMD) +=      smd.o
 obj-$(CONFIG_QCOM_SMD_RPM)     += smd-rpm.o
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
new file mode 100644 (file)
index 0000000..98b2373
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Qualcomm Peripheral Image Loader
+ *
+ * Copyright (C) 2016 Linaro Ltd
+ * Copyright (C) 2015 Sony Mobile Communications Inc
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/elf.h>
+#include <linux/firmware.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/qcom_scm.h>
+#include <linux/sizes.h>
+#include <linux/slab.h>
+#include <linux/soc/qcom/mdt_loader.h>
+
+static bool mdt_phdr_valid(const struct elf32_phdr *phdr)
+{
+       if (phdr->p_type != PT_LOAD)
+               return false;
+
+       if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH)
+               return false;
+
+       if (!phdr->p_memsz)
+               return false;
+
+       return true;
+}
+
+/**
+ * qcom_mdt_get_size() - acquire size of the memory region needed to load mdt
+ * @fw:                firmware object for the mdt file
+ *
+ * Returns size of the loaded firmware blob, or -EINVAL on failure.
+ */
+ssize_t qcom_mdt_get_size(const struct firmware *fw)
+{
+       const struct elf32_phdr *phdrs;
+       const struct elf32_phdr *phdr;
+       const struct elf32_hdr *ehdr;
+       phys_addr_t min_addr = (phys_addr_t)ULLONG_MAX;
+       phys_addr_t max_addr = 0;
+       int i;
+
+       ehdr = (struct elf32_hdr *)fw->data;
+       phdrs = (struct elf32_phdr *)(ehdr + 1);
+
+       for (i = 0; i < ehdr->e_phnum; i++) {
+               phdr = &phdrs[i];
+
+               if (!mdt_phdr_valid(phdr))
+                       continue;
+
+               if (phdr->p_paddr < min_addr)
+                       min_addr = phdr->p_paddr;
+
+               if (phdr->p_paddr + phdr->p_memsz > max_addr)
+                       max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K);
+       }
+
+       return min_addr < max_addr ? max_addr - min_addr : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(qcom_mdt_get_size);
+
+/**
+ * qcom_mdt_load() - load the firmware which header is loaded as fw
+ * @dev:       device handle to associate resources with
+ * @fw:                firmware object for the mdt file
+ * @firmware:  name of the firmware, for construction of segment file names
+ * @pas_id:    PAS identifier
+ * @mem_region:        allocated memory region to load firmware into
+ * @mem_phys:  physical address of allocated memory region
+ * @mem_size:  size of the allocated memory region
+ *
+ * Returns 0 on success, negative errno otherwise.
+ */
+int qcom_mdt_load(struct device *dev, const struct firmware *fw,
+                 const char *firmware, int pas_id, void *mem_region,
+                 phys_addr_t mem_phys, size_t mem_size)
+{
+       const struct elf32_phdr *phdrs;
+       const struct elf32_phdr *phdr;
+       const struct elf32_hdr *ehdr;
+       const struct firmware *seg_fw;
+       phys_addr_t mem_reloc;
+       phys_addr_t min_addr = (phys_addr_t)ULLONG_MAX;
+       phys_addr_t max_addr = 0;
+       size_t fw_name_len;
+       size_t offset;
+       char *fw_name;
+       bool relocate = false;
+       void *ptr;
+       int ret;
+       int i;
+
+       if (!fw || !mem_region || !mem_phys || !mem_size)
+               return -EINVAL;
+
+       ehdr = (struct elf32_hdr *)fw->data;
+       phdrs = (struct elf32_phdr *)(ehdr + 1);
+
+       fw_name_len = strlen(firmware);
+       if (fw_name_len <= 4)
+               return -EINVAL;
+
+       fw_name = kstrdup(firmware, GFP_KERNEL);
+       if (!fw_name)
+               return -ENOMEM;
+
+       ret = qcom_scm_pas_init_image(pas_id, fw->data, fw->size);
+       if (ret) {
+               dev_err(dev, "invalid firmware metadata\n");
+               goto out;
+       }
+
+       for (i = 0; i < ehdr->e_phnum; i++) {
+               phdr = &phdrs[i];
+
+               if (!mdt_phdr_valid(phdr))
+                       continue;
+
+               if (phdr->p_flags & QCOM_MDT_RELOCATABLE)
+                       relocate = true;
+
+               if (phdr->p_paddr < min_addr)
+                       min_addr = phdr->p_paddr;
+
+               if (phdr->p_paddr + phdr->p_memsz > max_addr)
+                       max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K);
+       }
+
+       if (relocate) {
+               ret = qcom_scm_pas_mem_setup(pas_id, mem_phys, max_addr - min_addr);
+               if (ret) {
+                       dev_err(dev, "unable to setup relocation\n");
+                       goto out;
+               }
+
+               /*
+                * The image is relocatable, so offset each segment based on
+                * the lowest segment address.
+                */
+               mem_reloc = min_addr;
+       } else {
+               /*
+                * Image is not relocatable, so offset each segment based on
+                * the allocated physical chunk of memory.
+                */
+               mem_reloc = mem_phys;
+       }
+
+       for (i = 0; i < ehdr->e_phnum; i++) {
+               phdr = &phdrs[i];
+
+               if (!mdt_phdr_valid(phdr))
+                       continue;
+
+               offset = phdr->p_paddr - mem_reloc;
+               if (offset < 0 || offset + phdr->p_memsz > mem_size) {
+                       dev_err(dev, "segment outside memory range\n");
+                       ret = -EINVAL;
+                       break;
+               }
+
+               ptr = mem_region + offset;
+
+               if (phdr->p_filesz) {
+                       sprintf(fw_name + fw_name_len - 3, "b%02d", i);
+                       ret = request_firmware(&seg_fw, fw_name, dev);
+                       if (ret) {
+                               dev_err(dev, "failed to load %s\n", fw_name);
+                               break;
+                       }
+
+                       memcpy(ptr, seg_fw->data, seg_fw->size);
+
+                       release_firmware(seg_fw);
+               }
+
+               if (phdr->p_memsz > phdr->p_filesz)
+                       memset(ptr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
+       }
+
+out:
+       kfree(fw_name);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_mdt_load);
+
+MODULE_DESCRIPTION("Firmware parser for Qualcomm MDT format");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/soc/qcom/mdt_loader.h b/include/linux/soc/qcom/mdt_loader.h
new file mode 100644 (file)
index 0000000..f423001
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __QCOM_MDT_LOADER_H__
+#define __QCOM_MDT_LOADER_H__
+
+#include <linux/types.h>
+
+#define QCOM_MDT_TYPE_MASK     (7 << 24)
+#define QCOM_MDT_TYPE_HASH     (2 << 24)
+#define QCOM_MDT_RELOCATABLE   BIT(27)
+
+struct device;
+struct firmware;
+
+ssize_t qcom_mdt_get_size(const struct firmware *fw);
+int qcom_mdt_load(struct device *dev, const struct firmware *fw,
+                 const char *fw_name, int pas_id, void *mem_region,
+                 phys_addr_t mem_phys, size_t mem_size);
+
+#endif