aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/mach-ux500/tee_ta_start_modem_svp.c
blob: 12337b93154a09ece80d0c323d355950346d4209 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
 * Trusted application for starting the modem.
 *
 * Copyright (C) ST-Ericsson SA 2010
 * Author: Shujuan Chen <shujuan.chen@stericsson.com>
 * License terms: GNU General Public License (GPL) version 2
 */

#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/elf.h>
#include <mach/hardware.h>

#include "mach/tee_ta_start_modem.h"

static int reset_modem(unsigned long modem_start_addr)
{
	void __iomem *base = ioremap(U5500_ACCCON_BASE_SEC, 0x2FF);
	if (!base)
		return -ENOMEM;

	pr_info("[%s] Setting modem start address!\n", __func__);
	writel(base + (U5500_ACCCON_CPUVEC_RESET_ADDR_OFFSET/sizeof(uint32_t)),
	       modem_start_addr);

	pr_info("[%s] resetting the modem!\n", __func__);
	writel(base + (U5500_ACCCON_ACC_CPU_CTRL_OFFSET/sizeof(uint32_t)), 1);

	iounmap(base);

	return 0;
}

int tee_ta_start_modem(struct tee_ta_start_modem *data)
{
	int ret = 0;
	struct elfhdr *elfhdr;
	void __iomem *vaddr;

	vaddr = ioremap((unsigned long)data->access_image_descr.elf_hdr,
			sizeof(struct elfhdr));
	if (!vaddr)
		return -ENOMEM;

	elfhdr = (struct elfhdr *)readl(vaddr);
	pr_info("Reading in kernel:elfhdr 0x%x:elfhdr->entry=0x%x\n",
			(uint32_t)elfhdr, (uint32_t)elfhdr->e_entry);

	pr_info("[%s] reset modem()...\n", __func__);
	ret = reset_modem(elfhdr->e_entry);

	iounmap(vaddr);

	return ret;
}