diff options
Diffstat (limited to 'target/linux/ipq806x/patches/0005-ARM-qcom-Split-Qualcomm-support-into-legacy-and-mult.patch')
-rw-r--r-- | target/linux/ipq806x/patches/0005-ARM-qcom-Split-Qualcomm-support-into-legacy-and-mult.patch | 1423 |
1 files changed, 0 insertions, 1423 deletions
diff --git a/target/linux/ipq806x/patches/0005-ARM-qcom-Split-Qualcomm-support-into-legacy-and-mult.patch b/target/linux/ipq806x/patches/0005-ARM-qcom-Split-Qualcomm-support-into-legacy-and-mult.patch deleted file mode 100644 index 4cd4c4757f..0000000000 --- a/target/linux/ipq806x/patches/0005-ARM-qcom-Split-Qualcomm-support-into-legacy-and-mult.patch +++ /dev/null @@ -1,1423 +0,0 @@ -From 8c2a00c0129d6f718245f7a613c2bb28976b7973 Mon Sep 17 00:00:00 2001 -From: Kumar Gala <galak@codeaurora.org> -Date: Tue, 21 Jan 2014 17:14:10 -0600 -Subject: [PATCH 005/182] ARM: qcom: Split Qualcomm support into legacy and - multiplatform - -Introduce a new mach-qcom that will support SoCs that intend to be -multiplatform compatible while keeping mach-msm to legacy SoC/board -support that will not transition over to multiplatform. - -As part of this, we move support for MSM8X60, MSM8960 and MSM8974 over -to mach-qcom. - -Signed-off-by: Kumar Gala <galak@codeaurora.org> ---- - MAINTAINERS | 8 ++ - arch/arm/Kconfig | 7 +- - arch/arm/Kconfig.debug | 2 +- - arch/arm/Makefile | 1 + - arch/arm/boot/dts/Makefile | 6 +- - arch/arm/mach-msm/Kconfig | 45 +------ - arch/arm/mach-msm/Makefile | 6 - - arch/arm/mach-msm/board-dt.c | 41 ------ - arch/arm/mach-msm/platsmp.c | 137 ------------------- - arch/arm/mach-msm/scm-boot.c | 39 ------ - arch/arm/mach-msm/scm-boot.h | 22 --- - arch/arm/mach-msm/scm.c | 299 ----------------------------------------- - arch/arm/mach-msm/scm.h | 25 ---- - arch/arm/mach-qcom/Kconfig | 33 +++++ - arch/arm/mach-qcom/Makefile | 5 + - arch/arm/mach-qcom/board.c | 40 ++++++ - arch/arm/mach-qcom/platsmp.c | 137 +++++++++++++++++++ - arch/arm/mach-qcom/scm-boot.c | 39 ++++++ - arch/arm/mach-qcom/scm-boot.h | 22 +++ - arch/arm/mach-qcom/scm.c | 299 +++++++++++++++++++++++++++++++++++++++++ - arch/arm/mach-qcom/scm.h | 25 ++++ - 21 files changed, 619 insertions(+), 619 deletions(-) - delete mode 100644 arch/arm/mach-msm/board-dt.c - delete mode 100644 arch/arm/mach-msm/platsmp.c - delete mode 100644 arch/arm/mach-msm/scm-boot.c - delete mode 100644 arch/arm/mach-msm/scm-boot.h - delete mode 100644 arch/arm/mach-msm/scm.c - delete mode 100644 arch/arm/mach-msm/scm.h - create mode 100644 arch/arm/mach-qcom/Kconfig - create mode 100644 arch/arm/mach-qcom/Makefile - create mode 100644 arch/arm/mach-qcom/board.c - create mode 100644 arch/arm/mach-qcom/platsmp.c - create mode 100644 arch/arm/mach-qcom/scm-boot.c - create mode 100644 arch/arm/mach-qcom/scm-boot.h - create mode 100644 arch/arm/mach-qcom/scm.c - create mode 100644 arch/arm/mach-qcom/scm.h - ---- a/MAINTAINERS -+++ b/MAINTAINERS -@@ -1168,6 +1168,14 @@ L: linux-arm-kernel@lists.infradead.org - W: http://www.arm.linux.org.uk/ - S: Maintained - -+ARM/QUALCOMM SUPPORT -+M: Kumar Gala <galak@codeaurora.org> -+M: David Brown <davidb@codeaurora.org> -+L: linux-arm-msm@vger.kernel.org -+S: Maintained -+F: arch/arm/mach-qcom/ -+T: git git://git.kernel.org/pub/scm/linux/kernel/git/galak/linux-qcom.git -+ - ARM/RADISYS ENP2611 MACHINE SUPPORT - M: Lennert Buytenhek <kernel@wantstofly.org> - L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) ---- a/arch/arm/Kconfig -+++ b/arch/arm/Kconfig -@@ -658,9 +658,8 @@ config ARCH_PXA - help - Support for Intel/Marvell's PXA2xx/PXA3xx processor line. - --config ARCH_MSM_NODT -- bool "Qualcomm MSM" -- select ARCH_MSM -+config ARCH_MSM -+ bool "Qualcomm MSM (non-multiplatform)" - select ARCH_REQUIRE_GPIOLIB - select COMMON_CLK - select GENERIC_CLOCKEVENTS -@@ -1006,6 +1005,8 @@ source "arch/arm/plat-pxa/Kconfig" - - source "arch/arm/mach-mmp/Kconfig" - -+source "arch/arm/mach-qcom/Kconfig" -+ - source "arch/arm/mach-realview/Kconfig" - - source "arch/arm/mach-rockchip/Kconfig" ---- a/arch/arm/Kconfig.debug -+++ b/arch/arm/Kconfig.debug -@@ -956,7 +956,7 @@ config DEBUG_STI_UART - - config DEBUG_MSM_UART - bool -- depends on ARCH_MSM -+ depends on ARCH_MSM || ARCH_QCOM - - config DEBUG_LL_INCLUDE - string ---- a/arch/arm/Makefile -+++ b/arch/arm/Makefile -@@ -185,6 +185,7 @@ machine-$(CONFIG_ARCH_OMAP2PLUS) += omap - machine-$(CONFIG_ARCH_ORION5X) += orion5x - machine-$(CONFIG_ARCH_PICOXCELL) += picoxcell - machine-$(CONFIG_ARCH_PXA) += pxa -+machine-$(CONFIG_ARCH_QCOM) += qcom - machine-$(CONFIG_ARCH_REALVIEW) += realview - machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip - machine-$(CONFIG_ARCH_RPC) += rpc ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -119,9 +119,6 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood- - kirkwood-ts219-6282.dtb - dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb - dtb-$(CONFIG_ARCH_MOXART) += moxart-uc7112lx.dtb --dtb-$(CONFIG_ARCH_MSM) += qcom-msm8660-surf.dtb \ -- qcom-msm8960-cdp.dtb \ -- qcom-apq8074-dragonboard.dtb - dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ - armada-370-mirabox.dtb \ - armada-370-netgear-rn102.dtb \ -@@ -234,6 +231,9 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420 - dra7-evm.dtb - dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb - dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb -+dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \ -+ qcom-msm8960-cdp.dtb \ -+ qcom-apq8074-dragonboard.dtb - dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \ - ste-hrefprev60-stuib.dtb \ - ste-hrefprev60-tvk.dtb \ ---- a/arch/arm/mach-msm/Kconfig -+++ b/arch/arm/mach-msm/Kconfig -@@ -1,50 +1,9 @@ --config ARCH_MSM -- bool -- --config ARCH_MSM_DT -- bool "Qualcomm MSM DT Support" if ARCH_MULTI_V7 -- select ARCH_MSM -- select ARCH_REQUIRE_GPIOLIB -- select CLKSRC_OF -- select GENERIC_CLOCKEVENTS -- help -- Support for Qualcomm's devicetree based MSM systems. -- - if ARCH_MSM - --menu "Qualcomm MSM SoC Selection" -- depends on ARCH_MSM_DT -- --config ARCH_MSM8X60 -- bool "Enable support for MSM8X60" -- select ARM_GIC -- select CPU_V7 -- select HAVE_SMP -- select MSM_SCM if SMP -- select CLKSRC_QCOM -- --config ARCH_MSM8960 -- bool "Enable support for MSM8960" -- select ARM_GIC -- select CPU_V7 -- select HAVE_SMP -- select MSM_SCM if SMP -- select CLKSRC_QCOM -- --config ARCH_MSM8974 -- bool "Enable support for MSM8974" -- select ARM_GIC -- select CPU_V7 -- select HAVE_ARM_ARCH_TIMER -- select HAVE_SMP -- select MSM_SCM if SMP -- --endmenu -- - choice - prompt "Qualcomm MSM SoC Type" - default ARCH_MSM7X00A -- depends on ARCH_MSM_NODT -+ depends on ARCH_MSM - - config ARCH_MSM7X00A - bool "MSM7x00A / MSM7x01A" -@@ -99,7 +58,7 @@ config MSM_VIC - bool - - menu "Qualcomm MSM Board Type" -- depends on ARCH_MSM_NODT -+ depends on ARCH_MSM - - config MACH_HALIBUT - depends on ARCH_MSM ---- a/arch/arm/mach-msm/Makefile -+++ b/arch/arm/mach-msm/Makefile -@@ -13,17 +13,11 @@ obj-$(CONFIG_ARCH_QSD8X50) += dma.o io.o - - obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o - obj-$(CONFIG_MSM_SMD) += last_radio_log.o --obj-$(CONFIG_MSM_SCM) += scm.o scm-boot.o -- --CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) -- --obj-$(CONFIG_SMP) += platsmp.o - - obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o - obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o board-trout-panel.o devices-msm7x00.o - obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o - obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o - obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o --obj-$(CONFIG_ARCH_MSM_DT) += board-dt.o - obj-$(CONFIG_MSM_GPIOMUX) += gpiomux.o - obj-$(CONFIG_ARCH_QSD8X50) += gpiomux-8x50.o ---- a/arch/arm/mach-msm/board-dt.c -+++ /dev/null -@@ -1,41 +0,0 @@ --/* Copyright (c) 2010-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 and -- * only 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/init.h> --#include <linux/of.h> --#include <linux/of_platform.h> -- --#include <asm/mach/arch.h> --#include <asm/mach/map.h> -- --#include "common.h" -- --static const char * const msm_dt_match[] __initconst = { -- "qcom,msm8660-fluid", -- "qcom,msm8660-surf", -- "qcom,msm8960-cdp", -- NULL --}; -- --static const char * const apq8074_dt_match[] __initconst = { -- "qcom,apq8074-dragonboard", -- NULL --}; -- --DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)") -- .smp = smp_ops(msm_smp_ops), -- .dt_compat = msm_dt_match, --MACHINE_END -- --DT_MACHINE_START(APQ_DT, "Qualcomm MSM (Flattened Device Tree)") -- .dt_compat = apq8074_dt_match, --MACHINE_END ---- a/arch/arm/mach-msm/platsmp.c -+++ /dev/null -@@ -1,137 +0,0 @@ --/* -- * Copyright (C) 2002 ARM Ltd. -- * All Rights Reserved -- * Copyright (c) 2010, Code Aurora Forum. 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. -- */ -- --#include <linux/init.h> --#include <linux/errno.h> --#include <linux/delay.h> --#include <linux/device.h> --#include <linux/smp.h> --#include <linux/io.h> -- --#include <asm/cputype.h> --#include <asm/smp_plat.h> -- --#include "scm-boot.h" --#include "common.h" -- --#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0 --#define SCSS_CPU1CORE_RESET 0xD80 --#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64 -- --extern void secondary_startup(void); -- --static DEFINE_SPINLOCK(boot_lock); -- --#ifdef CONFIG_HOTPLUG_CPU --static void __ref msm_cpu_die(unsigned int cpu) --{ -- wfi(); --} --#endif -- --static inline int get_core_count(void) --{ -- /* 1 + the PART[1:0] field of MIDR */ -- return ((read_cpuid_id() >> 4) & 3) + 1; --} -- --static void msm_secondary_init(unsigned int cpu) --{ -- /* -- * Synchronise with the boot thread. -- */ -- spin_lock(&boot_lock); -- spin_unlock(&boot_lock); --} -- --static void prepare_cold_cpu(unsigned int cpu) --{ -- int ret; -- ret = scm_set_boot_addr(virt_to_phys(secondary_startup), -- SCM_FLAG_COLDBOOT_CPU1); -- if (ret == 0) { -- void __iomem *sc1_base_ptr; -- sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2); -- if (sc1_base_ptr) { -- writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL); -- writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET); -- writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP); -- iounmap(sc1_base_ptr); -- } -- } else -- printk(KERN_DEBUG "Failed to set secondary core boot " -- "address\n"); --} -- --static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle) --{ -- static int cold_boot_done; -- -- /* Only need to bring cpu out of reset this way once */ -- if (cold_boot_done == false) { -- prepare_cold_cpu(cpu); -- cold_boot_done = true; -- } -- -- /* -- * set synchronisation state between this boot processor -- * and the secondary one -- */ -- spin_lock(&boot_lock); -- -- /* -- * Send the secondary CPU a soft interrupt, thereby causing -- * the boot monitor to read the system wide flags register, -- * and branch to the address found there. -- */ -- arch_send_wakeup_ipi_mask(cpumask_of(cpu)); -- -- /* -- * now the secondary core is starting up let it run its -- * calibrations, then wait for it to finish -- */ -- spin_unlock(&boot_lock); -- -- return 0; --} -- --/* -- * Initialise the CPU possible map early - this describes the CPUs -- * which may be present or become present in the system. The msm8x60 -- * does not support the ARM SCU, so just set the possible cpu mask to -- * NR_CPUS. -- */ --static void __init msm_smp_init_cpus(void) --{ -- unsigned int i, ncores = get_core_count(); -- -- if (ncores > nr_cpu_ids) { -- pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", -- ncores, nr_cpu_ids); -- ncores = nr_cpu_ids; -- } -- -- for (i = 0; i < ncores; i++) -- set_cpu_possible(i, true); --} -- --static void __init msm_smp_prepare_cpus(unsigned int max_cpus) --{ --} -- --struct smp_operations msm_smp_ops __initdata = { -- .smp_init_cpus = msm_smp_init_cpus, -- .smp_prepare_cpus = msm_smp_prepare_cpus, -- .smp_secondary_init = msm_secondary_init, -- .smp_boot_secondary = msm_boot_secondary, --#ifdef CONFIG_HOTPLUG_CPU -- .cpu_die = msm_cpu_die, --#endif --}; ---- a/arch/arm/mach-msm/scm-boot.c -+++ /dev/null -@@ -1,39 +0,0 @@ --/* Copyright (c) 2010, Code Aurora Forum. 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 and -- * only 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -- * 02110-1301, USA. -- */ -- --#include <linux/module.h> --#include <linux/slab.h> -- --#include "scm.h" --#include "scm-boot.h" -- --/* -- * Set the cold/warm boot address for one of the CPU cores. -- */ --int scm_set_boot_addr(phys_addr_t addr, int flags) --{ -- struct { -- unsigned int flags; -- phys_addr_t addr; -- } cmd; -- -- cmd.addr = addr; -- cmd.flags = flags; -- return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR, -- &cmd, sizeof(cmd), NULL, 0); --} --EXPORT_SYMBOL(scm_set_boot_addr); ---- a/arch/arm/mach-msm/scm-boot.h -+++ /dev/null -@@ -1,22 +0,0 @@ --/* Copyright (c) 2010, Code Aurora Forum. 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 and -- * only 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. -- */ --#ifndef __MACH_SCM_BOOT_H --#define __MACH_SCM_BOOT_H -- --#define SCM_BOOT_ADDR 0x1 --#define SCM_FLAG_COLDBOOT_CPU1 0x1 --#define SCM_FLAG_WARMBOOT_CPU1 0x2 --#define SCM_FLAG_WARMBOOT_CPU0 0x4 -- --int scm_set_boot_addr(phys_addr_t addr, int flags); -- --#endif ---- a/arch/arm/mach-msm/scm.c -+++ /dev/null -@@ -1,299 +0,0 @@ --/* Copyright (c) 2010, Code Aurora Forum. 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 and -- * only 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. -- * -- * You should have received a copy of the GNU General Public License -- * along with this program; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -- * 02110-1301, USA. -- */ -- --#include <linux/slab.h> --#include <linux/io.h> --#include <linux/module.h> --#include <linux/mutex.h> --#include <linux/errno.h> --#include <linux/err.h> -- --#include <asm/cacheflush.h> -- --#include "scm.h" -- --/* Cache line size for msm8x60 */ --#define CACHELINESIZE 32 -- --#define SCM_ENOMEM -5 --#define SCM_EOPNOTSUPP -4 --#define SCM_EINVAL_ADDR -3 --#define SCM_EINVAL_ARG -2 --#define SCM_ERROR -1 --#define SCM_INTERRUPTED 1 -- --static DEFINE_MUTEX(scm_lock); -- --/** -- * struct scm_command - one SCM command buffer -- * @len: total available memory for command and response -- * @buf_offset: start of command buffer -- * @resp_hdr_offset: start of response buffer -- * @id: command to be executed -- * @buf: buffer returned from scm_get_command_buffer() -- * -- * An SCM command is laid out in memory as follows: -- * -- * ------------------- <--- struct scm_command -- * | command header | -- * ------------------- <--- scm_get_command_buffer() -- * | command buffer | -- * ------------------- <--- struct scm_response and -- * | response header | scm_command_to_response() -- * ------------------- <--- scm_get_response_buffer() -- * | response buffer | -- * ------------------- -- * -- * There can be arbitrary padding between the headers and buffers so -- * you should always use the appropriate scm_get_*_buffer() routines -- * to access the buffers in a safe manner. -- */ --struct scm_command { -- u32 len; -- u32 buf_offset; -- u32 resp_hdr_offset; -- u32 id; -- u32 buf[0]; --}; -- --/** -- * struct scm_response - one SCM response buffer -- * @len: total available memory for response -- * @buf_offset: start of response data relative to start of scm_response -- * @is_complete: indicates if the command has finished processing -- */ --struct scm_response { -- u32 len; -- u32 buf_offset; -- u32 is_complete; --}; -- --/** -- * alloc_scm_command() - Allocate an SCM command -- * @cmd_size: size of the command buffer -- * @resp_size: size of the response buffer -- * -- * Allocate an SCM command, including enough room for the command -- * and response headers as well as the command and response buffers. -- * -- * Returns a valid &scm_command on success or %NULL if the allocation fails. -- */ --static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size) --{ -- struct scm_command *cmd; -- size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size + -- resp_size; -- -- cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL); -- if (cmd) { -- cmd->len = len; -- cmd->buf_offset = offsetof(struct scm_command, buf); -- cmd->resp_hdr_offset = cmd->buf_offset + cmd_size; -- } -- return cmd; --} -- --/** -- * free_scm_command() - Free an SCM command -- * @cmd: command to free -- * -- * Free an SCM command. -- */ --static inline void free_scm_command(struct scm_command *cmd) --{ -- kfree(cmd); --} -- --/** -- * scm_command_to_response() - Get a pointer to a scm_response -- * @cmd: command -- * -- * Returns a pointer to a response for a command. -- */ --static inline struct scm_response *scm_command_to_response( -- const struct scm_command *cmd) --{ -- return (void *)cmd + cmd->resp_hdr_offset; --} -- --/** -- * scm_get_command_buffer() - Get a pointer to a command buffer -- * @cmd: command -- * -- * Returns a pointer to the command buffer of a command. -- */ --static inline void *scm_get_command_buffer(const struct scm_command *cmd) --{ -- return (void *)cmd->buf; --} -- --/** -- * scm_get_response_buffer() - Get a pointer to a response buffer -- * @rsp: response -- * -- * Returns a pointer to a response buffer of a response. -- */ --static inline void *scm_get_response_buffer(const struct scm_response *rsp) --{ -- return (void *)rsp + rsp->buf_offset; --} -- --static int scm_remap_error(int err) --{ -- switch (err) { -- case SCM_ERROR: -- return -EIO; -- case SCM_EINVAL_ADDR: -- case SCM_EINVAL_ARG: -- return -EINVAL; -- case SCM_EOPNOTSUPP: -- return -EOPNOTSUPP; -- case SCM_ENOMEM: -- return -ENOMEM; -- } -- return -EINVAL; --} -- --static u32 smc(u32 cmd_addr) --{ -- int context_id; -- register u32 r0 asm("r0") = 1; -- register u32 r1 asm("r1") = (u32)&context_id; -- register u32 r2 asm("r2") = cmd_addr; -- do { -- asm volatile( -- __asmeq("%0", "r0") -- __asmeq("%1", "r0") -- __asmeq("%2", "r1") -- __asmeq("%3", "r2") --#ifdef REQUIRES_SEC -- ".arch_extension sec\n" --#endif -- "smc #0 @ switch to secure world\n" -- : "=r" (r0) -- : "r" (r0), "r" (r1), "r" (r2) -- : "r3"); -- } while (r0 == SCM_INTERRUPTED); -- -- return r0; --} -- --static int __scm_call(const struct scm_command *cmd) --{ -- int ret; -- u32 cmd_addr = virt_to_phys(cmd); -- -- /* -- * Flush the entire cache here so callers don't have to remember -- * to flush the cache when passing physical addresses to the secure -- * side in the buffer. -- */ -- flush_cache_all(); -- ret = smc(cmd_addr); -- if (ret < 0) -- ret = scm_remap_error(ret); -- -- return ret; --} -- --/** -- * scm_call() - Send an SCM command -- * @svc_id: service identifier -- * @cmd_id: command identifier -- * @cmd_buf: command buffer -- * @cmd_len: length of the command buffer -- * @resp_buf: response buffer -- * @resp_len: length of the response buffer -- * -- * Sends a command to the SCM and waits for the command to finish processing. -- */ --int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len, -- void *resp_buf, size_t resp_len) --{ -- int ret; -- struct scm_command *cmd; -- struct scm_response *rsp; -- -- cmd = alloc_scm_command(cmd_len, resp_len); -- if (!cmd) -- return -ENOMEM; -- -- cmd->id = (svc_id << 10) | cmd_id; -- if (cmd_buf) -- memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len); -- -- mutex_lock(&scm_lock); -- ret = __scm_call(cmd); -- mutex_unlock(&scm_lock); -- if (ret) -- goto out; -- -- rsp = scm_command_to_response(cmd); -- do { -- u32 start = (u32)rsp; -- u32 end = (u32)scm_get_response_buffer(rsp) + resp_len; -- start &= ~(CACHELINESIZE - 1); -- while (start < end) { -- asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start) -- : "memory"); -- start += CACHELINESIZE; -- } -- } while (!rsp->is_complete); -- -- if (resp_buf) -- memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len); --out: -- free_scm_command(cmd); -- return ret; --} --EXPORT_SYMBOL(scm_call); -- --u32 scm_get_version(void) --{ -- int context_id; -- static u32 version = -1; -- register u32 r0 asm("r0"); -- register u32 r1 asm("r1"); -- -- if (version != -1) -- return version; -- -- mutex_lock(&scm_lock); -- -- r0 = 0x1 << 8; -- r1 = (u32)&context_id; -- do { -- asm volatile( -- __asmeq("%0", "r0") -- __asmeq("%1", "r1") -- __asmeq("%2", "r0") -- __asmeq("%3", "r1") --#ifdef REQUIRES_SEC -- ".arch_extension sec\n" --#endif -- "smc #0 @ switch to secure world\n" -- : "=r" (r0), "=r" (r1) -- : "r" (r0), "r" (r1) -- : "r2", "r3"); -- } while (r0 == SCM_INTERRUPTED); -- -- version = r1; -- mutex_unlock(&scm_lock); -- -- return version; --} --EXPORT_SYMBOL(scm_get_version); ---- a/arch/arm/mach-msm/scm.h -+++ /dev/null -@@ -1,25 +0,0 @@ --/* Copyright (c) 2010, Code Aurora Forum. 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 and -- * only 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. -- */ --#ifndef __MACH_SCM_H --#define __MACH_SCM_H -- --#define SCM_SVC_BOOT 0x1 --#define SCM_SVC_PIL 0x2 -- --extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len, -- void *resp_buf, size_t resp_len); -- --#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF)) -- --extern u32 scm_get_version(void); -- --#endif ---- /dev/null -+++ b/arch/arm/mach-qcom/Kconfig -@@ -0,0 +1,33 @@ -+config ARCH_QCOM -+ bool "Qualcomm Support" if ARCH_MULTI_V7 -+ select ARCH_REQUIRE_GPIOLIB -+ select ARM_GIC -+ select CLKSRC_OF -+ select GENERIC_CLOCKEVENTS -+ select HAVE_SMP -+ select QCOM_SCM if SMP -+ help -+ Support for Qualcomm's devicetree based systems. -+ -+if ARCH_QCOM -+ -+menu "Qualcomm SoC Selection" -+ -+config ARCH_MSM8X60 -+ bool "Enable support for MSM8X60" -+ select CLKSRC_QCOM -+ -+config ARCH_MSM8960 -+ bool "Enable support for MSM8960" -+ select CLKSRC_QCOM -+ -+config ARCH_MSM8974 -+ bool "Enable support for MSM8974" -+ select HAVE_ARM_ARCH_TIMER -+ -+endmenu -+ -+config QCOM_SCM -+ bool -+ -+endif ---- /dev/null -+++ b/arch/arm/mach-qcom/Makefile -@@ -0,0 +1,5 @@ -+obj-y := board.o -+obj-$(CONFIG_SMP) += platsmp.o -+obj-$(CONFIG_QCOM_SCM) += scm.o scm-boot.o -+ -+CFLAGS_scm.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1) ---- /dev/null -+++ b/arch/arm/mach-qcom/board.c -@@ -0,0 +1,40 @@ -+/* Copyright (c) 2010-2014 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 and -+ * only 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/init.h> -+#include <linux/of.h> -+#include <linux/of_platform.h> -+ -+#include <asm/mach/arch.h> -+#include <asm/mach/map.h> -+ -+extern struct smp_operations msm_smp_ops; -+ -+static const char * const qcom_dt_match[] __initconst = { -+ "qcom,msm8660-surf", -+ "qcom,msm8960-cdp", -+ NULL -+}; -+ -+static const char * const apq8074_dt_match[] __initconst = { -+ "qcom,apq8074-dragonboard", -+ NULL -+}; -+ -+DT_MACHINE_START(QCOM_DT, "Qualcomm (Flattened Device Tree)") -+ .smp = smp_ops(msm_smp_ops), -+ .dt_compat = qcom_dt_match, -+MACHINE_END -+ -+DT_MACHINE_START(APQ_DT, "Qualcomm (Flattened Device Tree)") -+ .dt_compat = apq8074_dt_match, -+MACHINE_END ---- /dev/null -+++ b/arch/arm/mach-qcom/platsmp.c -@@ -0,0 +1,137 @@ -+/* -+ * Copyright (C) 2002 ARM Ltd. -+ * All Rights Reserved -+ * Copyright (c) 2010, Code Aurora Forum. All rights reserved. -+ * Copyright (c) 2014 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. -+ */ -+ -+#include <linux/init.h> -+#include <linux/errno.h> -+#include <linux/delay.h> -+#include <linux/device.h> -+#include <linux/smp.h> -+#include <linux/io.h> -+ -+#include <asm/cputype.h> -+#include <asm/smp_plat.h> -+ -+#include "scm-boot.h" -+ -+#define VDD_SC1_ARRAY_CLAMP_GFS_CTL 0x15A0 -+#define SCSS_CPU1CORE_RESET 0xD80 -+#define SCSS_DBG_STATUS_CORE_PWRDUP 0xE64 -+ -+extern void secondary_startup(void); -+ -+static DEFINE_SPINLOCK(boot_lock); -+ -+#ifdef CONFIG_HOTPLUG_CPU -+static void __ref msm_cpu_die(unsigned int cpu) -+{ -+ wfi(); -+} -+#endif -+ -+static inline int get_core_count(void) -+{ -+ /* 1 + the PART[1:0] field of MIDR */ -+ return ((read_cpuid_id() >> 4) & 3) + 1; -+} -+ -+static void msm_secondary_init(unsigned int cpu) -+{ -+ /* -+ * Synchronise with the boot thread. -+ */ -+ spin_lock(&boot_lock); -+ spin_unlock(&boot_lock); -+} -+ -+static void prepare_cold_cpu(unsigned int cpu) -+{ -+ int ret; -+ ret = scm_set_boot_addr(virt_to_phys(secondary_startup), -+ SCM_FLAG_COLDBOOT_CPU1); -+ if (ret == 0) { -+ void __iomem *sc1_base_ptr; -+ sc1_base_ptr = ioremap_nocache(0x00902000, SZ_4K*2); -+ if (sc1_base_ptr) { -+ writel(0, sc1_base_ptr + VDD_SC1_ARRAY_CLAMP_GFS_CTL); -+ writel(0, sc1_base_ptr + SCSS_CPU1CORE_RESET); -+ writel(3, sc1_base_ptr + SCSS_DBG_STATUS_CORE_PWRDUP); -+ iounmap(sc1_base_ptr); -+ } -+ } else -+ printk(KERN_DEBUG "Failed to set secondary core boot " -+ "address\n"); -+} -+ -+static int msm_boot_secondary(unsigned int cpu, struct task_struct *idle) -+{ -+ static int cold_boot_done; -+ -+ /* Only need to bring cpu out of reset this way once */ -+ if (cold_boot_done == false) { -+ prepare_cold_cpu(cpu); -+ cold_boot_done = true; -+ } -+ -+ /* -+ * set synchronisation state between this boot processor -+ * and the secondary one -+ */ -+ spin_lock(&boot_lock); -+ -+ /* -+ * Send the secondary CPU a soft interrupt, thereby causing -+ * the boot monitor to read the system wide flags register, -+ * and branch to the address found there. -+ */ -+ arch_send_wakeup_ipi_mask(cpumask_of(cpu)); -+ -+ /* -+ * now the secondary core is starting up let it run its -+ * calibrations, then wait for it to finish -+ */ -+ spin_unlock(&boot_lock); -+ -+ return 0; -+} -+ -+/* -+ * Initialise the CPU possible map early - this describes the CPUs -+ * which may be present or become present in the system. The msm8x60 -+ * does not support the ARM SCU, so just set the possible cpu mask to -+ * NR_CPUS. -+ */ -+static void __init msm_smp_init_cpus(void) -+{ -+ unsigned int i, ncores = get_core_count(); -+ -+ if (ncores > nr_cpu_ids) { -+ pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", -+ ncores, nr_cpu_ids); -+ ncores = nr_cpu_ids; -+ } -+ -+ for (i = 0; i < ncores; i++) -+ set_cpu_possible(i, true); -+} -+ -+static void __init msm_smp_prepare_cpus(unsigned int max_cpus) -+{ -+} -+ -+struct smp_operations msm_smp_ops __initdata = { -+ .smp_init_cpus = msm_smp_init_cpus, -+ .smp_prepare_cpus = msm_smp_prepare_cpus, -+ .smp_secondary_init = msm_secondary_init, -+ .smp_boot_secondary = msm_boot_secondary, -+#ifdef CONFIG_HOTPLUG_CPU -+ .cpu_die = msm_cpu_die, -+#endif -+}; ---- /dev/null -+++ b/arch/arm/mach-qcom/scm-boot.c -@@ -0,0 +1,39 @@ -+/* Copyright (c) 2010, Code Aurora Forum. 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 and -+ * only 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA. -+ */ -+ -+#include <linux/module.h> -+#include <linux/slab.h> -+ -+#include "scm.h" -+#include "scm-boot.h" -+ -+/* -+ * Set the cold/warm boot address for one of the CPU cores. -+ */ -+int scm_set_boot_addr(phys_addr_t addr, int flags) -+{ -+ struct { -+ unsigned int flags; -+ phys_addr_t addr; -+ } cmd; -+ -+ cmd.addr = addr; -+ cmd.flags = flags; -+ return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR, -+ &cmd, sizeof(cmd), NULL, 0); -+} -+EXPORT_SYMBOL(scm_set_boot_addr); ---- /dev/null -+++ b/arch/arm/mach-qcom/scm-boot.h -@@ -0,0 +1,22 @@ -+/* Copyright (c) 2010, Code Aurora Forum. 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 and -+ * only 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. -+ */ -+#ifndef __MACH_SCM_BOOT_H -+#define __MACH_SCM_BOOT_H -+ -+#define SCM_BOOT_ADDR 0x1 -+#define SCM_FLAG_COLDBOOT_CPU1 0x1 -+#define SCM_FLAG_WARMBOOT_CPU1 0x2 -+#define SCM_FLAG_WARMBOOT_CPU0 0x4 -+ -+int scm_set_boot_addr(phys_addr_t addr, int flags); -+ -+#endif ---- /dev/null -+++ b/arch/arm/mach-qcom/scm.c -@@ -0,0 +1,299 @@ -+/* Copyright (c) 2010, Code Aurora Forum. 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 and -+ * only 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. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA. -+ */ -+ -+#include <linux/slab.h> -+#include <linux/io.h> -+#include <linux/module.h> -+#include <linux/mutex.h> -+#include <linux/errno.h> -+#include <linux/err.h> -+ -+#include <asm/cacheflush.h> -+ -+#include "scm.h" -+ -+/* Cache line size for msm8x60 */ -+#define CACHELINESIZE 32 -+ -+#define SCM_ENOMEM -5 -+#define SCM_EOPNOTSUPP -4 -+#define SCM_EINVAL_ADDR -3 -+#define SCM_EINVAL_ARG -2 -+#define SCM_ERROR -1 -+#define SCM_INTERRUPTED 1 -+ -+static DEFINE_MUTEX(scm_lock); -+ -+/** -+ * struct scm_command - one SCM command buffer -+ * @len: total available memory for command and response -+ * @buf_offset: start of command buffer -+ * @resp_hdr_offset: start of response buffer -+ * @id: command to be executed -+ * @buf: buffer returned from scm_get_command_buffer() -+ * -+ * An SCM command is laid out in memory as follows: -+ * -+ * ------------------- <--- struct scm_command -+ * | command header | -+ * ------------------- <--- scm_get_command_buffer() -+ * | command buffer | -+ * ------------------- <--- struct scm_response and -+ * | response header | scm_command_to_response() -+ * ------------------- <--- scm_get_response_buffer() -+ * | response buffer | -+ * ------------------- -+ * -+ * There can be arbitrary padding between the headers and buffers so -+ * you should always use the appropriate scm_get_*_buffer() routines -+ * to access the buffers in a safe manner. -+ */ -+struct scm_command { -+ u32 len; -+ u32 buf_offset; -+ u32 resp_hdr_offset; -+ u32 id; -+ u32 buf[0]; -+}; -+ -+/** -+ * struct scm_response - one SCM response buffer -+ * @len: total available memory for response -+ * @buf_offset: start of response data relative to start of scm_response -+ * @is_complete: indicates if the command has finished processing -+ */ -+struct scm_response { -+ u32 len; -+ u32 buf_offset; -+ u32 is_complete; -+}; -+ -+/** -+ * alloc_scm_command() - Allocate an SCM command -+ * @cmd_size: size of the command buffer -+ * @resp_size: size of the response buffer -+ * -+ * Allocate an SCM command, including enough room for the command -+ * and response headers as well as the command and response buffers. -+ * -+ * Returns a valid &scm_command on success or %NULL if the allocation fails. -+ */ -+static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size) -+{ -+ struct scm_command *cmd; -+ size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size + -+ resp_size; -+ -+ cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL); -+ if (cmd) { -+ cmd->len = len; -+ cmd->buf_offset = offsetof(struct scm_command, buf); -+ cmd->resp_hdr_offset = cmd->buf_offset + cmd_size; -+ } -+ return cmd; -+} -+ -+/** -+ * free_scm_command() - Free an SCM command -+ * @cmd: command to free -+ * -+ * Free an SCM command. -+ */ -+static inline void free_scm_command(struct scm_command *cmd) -+{ -+ kfree(cmd); -+} -+ -+/** -+ * scm_command_to_response() - Get a pointer to a scm_response -+ * @cmd: command -+ * -+ * Returns a pointer to a response for a command. -+ */ -+static inline struct scm_response *scm_command_to_response( -+ const struct scm_command *cmd) -+{ -+ return (void *)cmd + cmd->resp_hdr_offset; -+} -+ -+/** -+ * scm_get_command_buffer() - Get a pointer to a command buffer -+ * @cmd: command -+ * -+ * Returns a pointer to the command buffer of a command. -+ */ -+static inline void *scm_get_command_buffer(const struct scm_command *cmd) -+{ -+ return (void *)cmd->buf; -+} -+ -+/** -+ * scm_get_response_buffer() - Get a pointer to a response buffer -+ * @rsp: response -+ * -+ * Returns a pointer to a response buffer of a response. -+ */ -+static inline void *scm_get_response_buffer(const struct scm_response *rsp) -+{ -+ return (void *)rsp + rsp->buf_offset; -+} -+ -+static int scm_remap_error(int err) -+{ -+ switch (err) { -+ case SCM_ERROR: -+ return -EIO; -+ case SCM_EINVAL_ADDR: -+ case SCM_EINVAL_ARG: -+ return -EINVAL; -+ case SCM_EOPNOTSUPP: -+ return -EOPNOTSUPP; -+ case SCM_ENOMEM: -+ return -ENOMEM; -+ } -+ return -EINVAL; -+} -+ -+static u32 smc(u32 cmd_addr) -+{ -+ int context_id; -+ register u32 r0 asm("r0") = 1; -+ register u32 r1 asm("r1") = (u32)&context_id; -+ register u32 r2 asm("r2") = cmd_addr; -+ do { -+ asm volatile( -+ __asmeq("%0", "r0") -+ __asmeq("%1", "r0") -+ __asmeq("%2", "r1") -+ __asmeq("%3", "r2") -+#ifdef REQUIRES_SEC -+ ".arch_extension sec\n" -+#endif -+ "smc #0 @ switch to secure world\n" -+ : "=r" (r0) -+ : "r" (r0), "r" (r1), "r" (r2) -+ : "r3"); -+ } while (r0 == SCM_INTERRUPTED); -+ -+ return r0; -+} -+ -+static int __scm_call(const struct scm_command *cmd) -+{ -+ int ret; -+ u32 cmd_addr = virt_to_phys(cmd); -+ -+ /* -+ * Flush the entire cache here so callers don't have to remember -+ * to flush the cache when passing physical addresses to the secure -+ * side in the buffer. -+ */ -+ flush_cache_all(); -+ ret = smc(cmd_addr); -+ if (ret < 0) -+ ret = scm_remap_error(ret); -+ -+ return ret; -+} -+ -+/** -+ * scm_call() - Send an SCM command -+ * @svc_id: service identifier -+ * @cmd_id: command identifier -+ * @cmd_buf: command buffer -+ * @cmd_len: length of the command buffer -+ * @resp_buf: response buffer -+ * @resp_len: length of the response buffer -+ * -+ * Sends a command to the SCM and waits for the command to finish processing. -+ */ -+int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len, -+ void *resp_buf, size_t resp_len) -+{ -+ int ret; -+ struct scm_command *cmd; -+ struct scm_response *rsp; -+ -+ cmd = alloc_scm_command(cmd_len, resp_len); -+ if (!cmd) -+ return -ENOMEM; -+ -+ cmd->id = (svc_id << 10) | cmd_id; -+ if (cmd_buf) -+ memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len); -+ -+ mutex_lock(&scm_lock); -+ ret = __scm_call(cmd); -+ mutex_unlock(&scm_lock); -+ if (ret) -+ goto out; -+ -+ rsp = scm_command_to_response(cmd); -+ do { -+ u32 start = (u32)rsp; -+ u32 end = (u32)scm_get_response_buffer(rsp) + resp_len; -+ start &= ~(CACHELINESIZE - 1); -+ while (start < end) { -+ asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start) -+ : "memory"); -+ start += CACHELINESIZE; -+ } -+ } while (!rsp->is_complete); -+ -+ if (resp_buf) -+ memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len); -+out: -+ free_scm_command(cmd); -+ return ret; -+} -+EXPORT_SYMBOL(scm_call); -+ -+u32 scm_get_version(void) -+{ -+ int context_id; -+ static u32 version = -1; -+ register u32 r0 asm("r0"); -+ register u32 r1 asm("r1"); -+ -+ if (version != -1) -+ return version; -+ -+ mutex_lock(&scm_lock); -+ -+ r0 = 0x1 << 8; -+ r1 = (u32)&context_id; -+ do { -+ asm volatile( -+ __asmeq("%0", "r0") -+ __asmeq("%1", "r1") -+ __asmeq("%2", "r0") -+ __asmeq("%3", "r1") -+#ifdef REQUIRES_SEC -+ ".arch_extension sec\n" -+#endif -+ "smc #0 @ switch to secure world\n" -+ : "=r" (r0), "=r" (r1) -+ : "r" (r0), "r" (r1) -+ : "r2", "r3"); -+ } while (r0 == SCM_INTERRUPTED); -+ -+ version = r1; -+ mutex_unlock(&scm_lock); -+ -+ return version; -+} -+EXPORT_SYMBOL(scm_get_version); ---- /dev/null -+++ b/arch/arm/mach-qcom/scm.h -@@ -0,0 +1,25 @@ -+/* Copyright (c) 2010, Code Aurora Forum. 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 and -+ * only 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. -+ */ -+#ifndef __MACH_SCM_H -+#define __MACH_SCM_H -+ -+#define SCM_SVC_BOOT 0x1 -+#define SCM_SVC_PIL 0x2 -+ -+extern int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len, -+ void *resp_buf, size_t resp_len); -+ -+#define SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF)) -+ -+extern u32 scm_get_version(void); -+ -+#endif |