msm: pil: Add start address querying API

Almost every PIL driver needs to parse the elf header to
determine what the entry point is so they can configure hardware.
Instead of forcing every driver to copy the same code, parse the
entry point in the core PIL code and expose an API to get the
address via pil_get_start_addr().

For safety, add a check to make sure the start address lies
within the range of the segments that we load unless a 'quirk' is
filled out indicating we should skip the check.

In addition, make the init_image callback optional to reduce code
even further because most of the init_image callbacks are empty
after this change.

Change-Id: Ib721eefc41278bcf3e0d8faba642cc427e7643ec
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
diff --git a/arch/arm/mach-msm/pil-modem.c b/arch/arm/mach-msm/pil-modem.c
index 94f545e..00b5024 100644
--- a/arch/arm/mach-msm/pil-modem.c
+++ b/arch/arm/mach-msm/pil-modem.c
@@ -15,7 +15,6 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/ioport.h>
-#include <linux/elf.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/clk.h>
@@ -58,7 +57,6 @@
 struct modem_data {
 	void __iomem *base;
 	void __iomem *wdog;
-	unsigned long start_addr;
 	struct pil_device *pil;
 	struct clk *xo;
 	struct notifier_block notifier;
@@ -91,19 +89,11 @@
 	clk_disable_unprepare(drv->xo);
 }
 
-static int modem_init_image(struct pil_desc *pil, const u8 *metadata,
-		size_t size)
-{
-	const struct elf32_hdr *ehdr = (struct elf32_hdr *)metadata;
-	struct modem_data *drv = dev_get_drvdata(pil->dev);
-	drv->start_addr = ehdr->e_entry;
-	return 0;
-}
-
 static int modem_reset(struct pil_desc *pil)
 {
 	u32 reg;
 	const struct modem_data *drv = dev_get_drvdata(pil->dev);
+	unsigned long start_addr = pil_get_entry_addr(pil);
 
 	/* Put modem AHB0,1,2 clocks into reset */
 	writel_relaxed(BIT(0) | BIT(1), MAHB0_SFAB_PORT_RESET);
@@ -168,7 +158,7 @@
 	mb();
 
 	/* Setup exception vector table base address */
-	writel_relaxed(drv->start_addr | 0x1, drv->base + MARM_BOOT_CONTROL);
+	writel_relaxed(start_addr | 0x1, drv->base + MARM_BOOT_CONTROL);
 
 	/* Wait for vector table to be setup */
 	mb();
@@ -219,7 +209,6 @@
 }
 
 static struct pil_reset_ops pil_modem_ops = {
-	.init_image = modem_init_image,
 	.auth_and_reset = modem_reset,
 	.shutdown = modem_pil_shutdown,
 	.proxy_vote = make_modem_proxy_votes,