summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-23 18:49:36 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-23 18:49:36 -0800
commit0ba3307a8ec35252f7b1e222e32889a6f3d9ceb3 (patch)
tree26126ed7a2080a706f0488c215549fc9f5f76a59 /arch/arm
parent903a9f77d1d00c8621bc37afd959ac45a4b3ebec (diff)
parentcd2f43a1f7400a74a084094502f70df2e169c6e8 (diff)
Merge tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM driver updates from Olof Johansson: "Updates of SoC-near drivers and other driver updates that makes more sense to take through our tree. The largest part of this is a conversion of device registration for some renesas shmobile/sh devices over to use resources. This has required coordination with the corresponding arch/sh changes, and we've agreed to merge the arch/sh changes through our tree. Added in this branch is support for Trusted Foundations secure firmware, which is what is used on many of the commercial Nvidia Tegra products that are in the market, including the Nvidia Shield. The code is local to arch/arm at this time since it's uncertain whether it will be shared with arm64 longer-term, if needed we will refactor later. A couple of new RTC drivers used on ARM boards, merged through our tree on request by the RTC maintainer. ... plus a bunch of smaller updates across the board, gpio conversions for davinci, etc" * tag 'drivers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (45 commits) watchdog: davinci: rename platform driver to davinci-wdt tty: serial: Limit msm_serial_hs driver to platforms that use it mmc: msm_sdcc: Limit driver to platforms that use it usb: phy: msm: Move mach dependent code to platform data clk: versatile: fixup IM-PD1 clock implementation clk: versatile: pass a name to ICST clock provider ARM: integrator: pass parent IRQ to the SIC irqchip: versatile FPGA: support cascaded interrupts from DT gpio: davinci: don't create irq_domain in case of unbanked irqs gpio: davinci: use chained_irq_enter/chained_irq_exit API gpio: davinci: add OF support gpio: davinci: remove unused variable intc_irq_num gpio: davinci: convert to use irqdomain support. gpio: introduce GPIO_DAVINCI kconfig option gpio: davinci: get rid of DAVINCI_N_GPIO gpio: davinci: use {readl|writel}_relaxed() instead of __raw_* serial: sh-sci: Add OF support serial: sh-sci: Add device tree bindings documentation serial: sh-sci: Remove platform data mapbase and irqs fields serial: sh-sci: Remove platform data scbrr_algo_id field ...
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/dts/integratorcp.dts3
-rw-r--r--arch/arm/configs/tegra_defconfig1
-rw-r--r--arch/arm/firmware/Kconfig28
-rw-r--r--arch/arm/firmware/Makefile1
-rw-r--r--arch/arm/firmware/trusted_foundations.c81
-rw-r--r--arch/arm/include/asm/trusted_foundations.h67
-rw-r--r--arch/arm/mach-davinci/da830.c3
-rw-r--r--arch/arm/mach-davinci/da850.c3
-rw-r--r--arch/arm/mach-davinci/da8xx-dt.c2
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c4
-rw-r--r--arch/arm/mach-davinci/devices.c2
-rw-r--r--arch/arm/mach-davinci/dm355.c3
-rw-r--r--arch/arm/mach-davinci/dm365.c3
-rw-r--r--arch/arm/mach-davinci/dm644x.c3
-rw-r--r--arch/arm/mach-davinci/dm646x.c3
-rw-r--r--arch/arm/mach-msm/board-msm7x30.c35
-rw-r--r--arch/arm/mach-msm/board-qsd8x50.c35
-rw-r--r--arch/arm/mach-tegra/Kconfig1
-rw-r--r--arch/arm/mach-tegra/reset.c40
-rw-r--r--arch/arm/mach-tegra/tegra.c2
22 files changed, 298 insertions, 27 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 35e6d6b5d7d1..f9b0fd387c6f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -317,6 +317,8 @@ config ARCH_INTEGRATOR
bool "ARM Ltd. Integrator family"
select ARCH_HAS_CPUFREQ
select ARM_AMBA
+ select ARM_PATCH_PHYS_VIRT
+ select AUTO_ZRELADDR
select COMMON_CLK
select COMMON_CLK_VERSATILE
select GENERIC_CLOCKEVENTS
@@ -1084,6 +1086,8 @@ config ARM_TIMER_SP804
select CLKSRC_MMIO
select CLKSRC_OF if OF
+source "arch/arm/firmware/Kconfig"
+
source arch/arm/mm/Kconfig
config ARM_NR_BANKS
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index d8605046792c..23d5e3946589 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -267,6 +267,7 @@ core-$(CONFIG_KVM_ARM_HOST) += arch/arm/kvm/
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
core-y += arch/arm/net/
core-y += arch/arm/crypto/
+core-y += arch/arm/firmware/
core-y += $(machdirs) $(platdirs)
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts
index 7deb3a3182b4..a21c17de9a5e 100644
--- a/arch/arm/boot/dts/integratorcp.dts
+++ b/arch/arm/boot/dts/integratorcp.dts
@@ -47,8 +47,11 @@
valid-mask = <0x00000007>;
};
+ /* The SIC is cascaded off IRQ 26 on the PIC */
sic: sic@ca000000 {
compatible = "arm,versatile-fpga-irq";
+ interrupt-parent = <&pic>;
+ interrupts = <26>;
#interrupt-cells = <1>;
interrupt-controller;
reg = <0xca000000 0x100>;
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index e38653876541..5fdc9a09d339 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -33,6 +33,7 @@ CONFIG_PCI=y
CONFIG_PCI_MSI=y
CONFIG_PCI_TEGRA=y
CONFIG_PCIEPORTBUS=y
+CONFIG_TRUSTED_FOUNDATIONS=y
CONFIG_SMP=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
diff --git a/arch/arm/firmware/Kconfig b/arch/arm/firmware/Kconfig
new file mode 100644
index 000000000000..bb00ccf00d66
--- /dev/null
+++ b/arch/arm/firmware/Kconfig
@@ -0,0 +1,28 @@
+config ARCH_SUPPORTS_FIRMWARE
+ bool
+
+config ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
+ bool
+ select ARCH_SUPPORTS_FIRMWARE
+
+menu "Firmware options"
+ depends on ARCH_SUPPORTS_FIRMWARE
+
+config TRUSTED_FOUNDATIONS
+ bool "Trusted Foundations secure monitor support"
+ depends on ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
+ help
+ Some devices (including most Tegra-based consumer devices on the
+ market) are booted with the Trusted Foundations secure monitor
+ active, requiring some core operations to be performed by the secure
+ monitor instead of the kernel.
+
+ This option allows the kernel to invoke the secure monitor whenever
+ required on devices using Trusted Foundations. See
+ arch/arm/include/asm/trusted_foundations.h or the
+ tl,trusted-foundations device tree binding documentation for details
+ on how to use it.
+
+ Say n if you don't know what this is about.
+
+endmenu
diff --git a/arch/arm/firmware/Makefile b/arch/arm/firmware/Makefile
new file mode 100644
index 000000000000..a71f16536b6c
--- /dev/null
+++ b/arch/arm/firmware/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
diff --git a/arch/arm/firmware/trusted_foundations.c b/arch/arm/firmware/trusted_foundations.c
new file mode 100644
index 000000000000..ef1e3d8f4af0
--- /dev/null
+++ b/arch/arm/firmware/trusted_foundations.c
@@ -0,0 +1,81 @@
+/*
+ * Trusted Foundations support for ARM CPUs
+ *
+ * Copyright (c) 2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <asm/firmware.h>
+#include <asm/trusted_foundations.h>
+
+#define TF_SET_CPU_BOOT_ADDR_SMC 0xfffff200
+
+static void __naked tf_generic_smc(u32 type, u32 arg1, u32 arg2)
+{
+ asm volatile(
+ ".arch_extension sec\n\t"
+ "stmfd sp!, {r4 - r11, lr}\n\t"
+ __asmeq("%0", "r0")
+ __asmeq("%1", "r1")
+ __asmeq("%2", "r2")
+ "mov r3, #0\n\t"
+ "mov r4, #0\n\t"
+ "smc #0\n\t"
+ "ldmfd sp!, {r4 - r11, pc}"
+ :
+ : "r" (type), "r" (arg1), "r" (arg2)
+ : "memory");
+}
+
+static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
+{
+ tf_generic_smc(TF_SET_CPU_BOOT_ADDR_SMC, boot_addr, 0);
+
+ return 0;
+}
+
+static const struct firmware_ops trusted_foundations_ops = {
+ .set_cpu_boot_addr = tf_set_cpu_boot_addr,
+};
+
+void register_trusted_foundations(struct trusted_foundations_platform_data *pd)
+{
+ /*
+ * we are not using version information for now since currently
+ * supported SMCs are compatible with all TF releases
+ */
+ register_firmware_ops(&trusted_foundations_ops);
+}
+
+void of_register_trusted_foundations(void)
+{
+ struct device_node *node;
+ struct trusted_foundations_platform_data pdata;
+ int err;
+
+ node = of_find_compatible_node(NULL, NULL, "tlm,trusted-foundations");
+ if (!node)
+ return;
+
+ err = of_property_read_u32(node, "tlm,version-major",
+ &pdata.version_major);
+ if (err != 0)
+ panic("Trusted Foundation: missing version-major property\n");
+ err = of_property_read_u32(node, "tlm,version-minor",
+ &pdata.version_minor);
+ if (err != 0)
+ panic("Trusted Foundation: missing version-minor property\n");
+ register_trusted_foundations(&pdata);
+}
diff --git a/arch/arm/include/asm/trusted_foundations.h b/arch/arm/include/asm/trusted_foundations.h
new file mode 100644
index 000000000000..3bd36e2c5f2e
--- /dev/null
+++ b/arch/arm/include/asm/trusted_foundations.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+/*
+ * Support for the Trusted Foundations secure monitor.
+ *
+ * Trusted Foundation comes active on some ARM consumer devices (most
+ * Tegra-based devices sold on the market are concerned). Such devices can only
+ * perform some basic operations, like setting the CPU reset vector, through
+ * SMC calls to the secure monitor. The calls are completely specific to
+ * Trusted Foundations, and do *not* follow the SMC calling convention or the
+ * PSCI standard.
+ */
+
+#ifndef __ASM_ARM_TRUSTED_FOUNDATIONS_H
+#define __ASM_ARM_TRUSTED_FOUNDATIONS_H
+
+#include <linux/kconfig.h>
+#include <linux/printk.h>
+#include <linux/bug.h>
+#include <linux/of.h>
+
+struct trusted_foundations_platform_data {
+ unsigned int version_major;
+ unsigned int version_minor;
+};
+
+#if IS_ENABLED(CONFIG_TRUSTED_FOUNDATIONS)
+
+void register_trusted_foundations(struct trusted_foundations_platform_data *pd);
+void of_register_trusted_foundations(void);
+
+#else /* CONFIG_TRUSTED_FOUNDATIONS */
+
+static inline void register_trusted_foundations(
+ struct trusted_foundations_platform_data *pd)
+{
+ /*
+ * If we try to register TF, this means the system needs it to continue.
+ * Its absence if thus a fatal error.
+ */
+ panic("No support for Trusted Foundations, stopping...\n");
+}
+
+static inline void of_register_trusted_foundations(void)
+{
+ /*
+ * If we find the target should enable TF but does not support it,
+ * fail as the system won't be able to do much anyway
+ */
+ if (of_find_compatible_node(NULL, NULL, "tl,trusted-foundations"))
+ register_trusted_foundations(NULL);
+}
+#endif /* CONFIG_TRUSTED_FOUNDATIONS */
+
+#endif
diff --git a/arch/arm/mach-davinci/da830.c b/arch/arm/mach-davinci/da830.c
index 0813b5167e05..115d5736da80 100644
--- a/arch/arm/mach-davinci/da830.c
+++ b/arch/arm/mach-davinci/da830.c
@@ -385,7 +385,7 @@ static struct clk_lookup da830_clks[] = {
CLK(NULL, "pll0_sysclk7", &pll0_sysclk7),
CLK("i2c_davinci.1", NULL, &i2c0_clk),
CLK(NULL, "timer0", &timerp64_0_clk),
- CLK("watchdog", NULL, &timerp64_1_clk),
+ CLK("davinci-wdt", NULL, &timerp64_1_clk),
CLK(NULL, "arm_rom", &arm_rom_clk),
CLK(NULL, "scr0_ss", &scr0_ss_clk),
CLK(NULL, "scr1_ss", &scr1_ss_clk),
@@ -1153,7 +1153,6 @@ static struct davinci_id da830_ids[] = {
static struct davinci_gpio_platform_data da830_gpio_platform_data = {
.ngpio = 128,
- .intc_irq_num = DA830_N_CP_INTC_IRQ,
};
int __init da830_register_gpio(void)
diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 352984e1528a..2ab00434b2eb 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -443,7 +443,7 @@ static struct clk_lookup da850_clks[] = {
CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
CLK("i2c_davinci.1", NULL, &i2c0_clk),
CLK(NULL, "timer0", &timerp64_0_clk),
- CLK("watchdog", NULL, &timerp64_1_clk),
+ CLK("davinci-wdt", NULL, &timerp64_1_clk),
CLK(NULL, "arm_rom", &arm_rom_clk),
CLK(NULL, "tpcc0", &tpcc0_clk),
CLK(NULL, "tptc0", &tptc0_clk),
@@ -1283,7 +1283,6 @@ int __init da850_register_vpif_capture(struct vpif_capture_config
static struct davinci_gpio_platform_data da850_gpio_platform_data = {
.ngpio = 144,
- .intc_irq_num = DA850_N_CP_INTC_IRQ,
};
int __init da850_register_gpio(void)
diff --git a/arch/arm/mach-davinci/da8xx-dt.c b/arch/arm/mach-davinci/da8xx-dt.c
index d2bc574ae172..ed1928740b5f 100644
--- a/arch/arm/mach-davinci/da8xx-dt.c
+++ b/arch/arm/mach-davinci/da8xx-dt.c
@@ -32,7 +32,7 @@ static void __init da8xx_init_irq(void)
static struct of_dev_auxdata da850_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("ti,davinci-i2c", 0x01c22000, "i2c_davinci.1", NULL),
- OF_DEV_AUXDATA("ti,davinci-wdt", 0x01c21000, "watchdog", NULL),
+ OF_DEV_AUXDATA("ti,davinci-wdt", 0x01c21000, "davinci-wdt", NULL),
OF_DEV_AUXDATA("ti,da830-mmc", 0x01c40000, "da830-mmc.0", NULL),
OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f00000, "ehrpwm", NULL),
OF_DEV_AUXDATA("ti,da850-ehrpwm", 0x01f02000, "ehrpwm", NULL),
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 78829c513fdc..0486cdf28c8d 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -389,7 +389,7 @@ static struct resource da8xx_watchdog_resources[] = {
};
static struct platform_device da8xx_wdt_device = {
- .name = "watchdog",
+ .name = "davinci-wdt",
.id = -1,
.num_resources = ARRAY_SIZE(da8xx_watchdog_resources),
.resource = da8xx_watchdog_resources,
@@ -399,7 +399,7 @@ void da8xx_restart(enum reboot_mode mode, const char *cmd)
{
struct device *dev;
- dev = bus_find_device_by_name(&platform_bus_type, NULL, "watchdog");
+ dev = bus_find_device_by_name(&platform_bus_type, NULL, "davinci-wdt");
if (!dev) {
pr_err("%s: failed to find watchdog device\n", __func__);
return;
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index 3996e98f52fb..5cf9a027dcc6 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -302,7 +302,7 @@ static struct resource wdt_resources[] = {
};
struct platform_device davinci_wdt_device = {
- .name = "watchdog",
+ .name = "davinci-wdt",
.id = -1,
.num_resources = ARRAY_SIZE(wdt_resources),
.resource = wdt_resources,
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index 6117fc644188..4668c0e19767 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -375,7 +375,7 @@ static struct clk_lookup dm355_clks[] = {
CLK(NULL, "pwm3", &pwm3_clk),
CLK(NULL, "timer0", &timer0_clk),
CLK(NULL, "timer1", &timer1_clk),
- CLK("watchdog", NULL, &timer2_clk),
+ CLK("davinci-wdt", NULL, &timer2_clk),
CLK(NULL, "timer3", &timer3_clk),
CLK(NULL, "rto", &rto_clk),
CLK(NULL, "usb", &usb_clk),
@@ -901,7 +901,6 @@ static struct resource dm355_gpio_resources[] = {
static struct davinci_gpio_platform_data dm355_gpio_platform_data = {
.ngpio = 104,
- .intc_irq_num = DAVINCI_N_AINTC_IRQ,
};
int __init dm355_gpio_register(void)
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index d7c6f85d3fc9..b44b49e2801a 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -473,7 +473,7 @@ static struct clk_lookup dm365_clks[] = {
CLK(NULL, "pwm3", &pwm3_clk),
CLK(NULL, "timer0", &timer0_clk),
CLK(NULL, "timer1", &timer1_clk),
- CLK("watchdog", NULL, &timer2_clk),
+ CLK("davinci-wdt", NULL, &timer2_clk),
CLK(NULL, "timer3", &timer3_clk),
CLK(NULL, "usb", &usb_clk),
CLK("davinci_emac.1", NULL, &emac_clk),
@@ -713,7 +713,6 @@ static struct resource dm365_gpio_resources[] = {
static struct davinci_gpio_platform_data dm365_gpio_platform_data = {
.ngpio = 104,
- .intc_irq_num = DAVINCI_N_AINTC_IRQ,
.gpio_unbanked = 8,
};
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 3ce47997bb46..5c3e0be95ef3 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -322,7 +322,7 @@ static struct clk_lookup dm644x_clks[] = {
CLK(NULL, "pwm2", &pwm2_clk),
CLK(NULL, "timer0", &timer0_clk),
CLK(NULL, "timer1", &timer1_clk),
- CLK("watchdog", NULL, &timer2_clk),
+ CLK("davinci-wdt", NULL, &timer2_clk),
CLK(NULL, NULL, NULL),
};
@@ -787,7 +787,6 @@ static struct resource dm644_gpio_resources[] = {
static struct davinci_gpio_platform_data dm644_gpio_platform_data = {
.ngpio = 71,
- .intc_irq_num = DAVINCI_N_AINTC_IRQ,
};
int __init dm644x_gpio_register(void)
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 0e81fea65e7f..81768dd47096 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -356,7 +356,7 @@ static struct clk_lookup dm646x_clks[] = {
CLK(NULL, "pwm1", &pwm1_clk),
CLK(NULL, "timer0", &timer0_clk),
CLK(NULL, "timer1", &timer1_clk),
- CLK("watchdog", NULL, &timer2_clk),
+ CLK("davinci-wdt", NULL, &timer2_clk),
CLK("palm_bk3710", NULL, &ide_clk),
CLK(NULL, "vpif0", &vpif0_clk),
CLK(NULL, "vpif1", &vpif1_clk),
@@ -763,7 +763,6 @@ static struct resource dm646x_gpio_resources[] = {
static struct davinci_gpio_platform_data dm646x_gpio_platform_data = {
.ngpio = 43,
- .intc_irq_num = DAVINCI_N_AINTC_IRQ,
};
int __init dm646x_gpio_register(void)
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index f9af5a46e8b6..46de789ad3ae 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -30,6 +30,7 @@
#include <asm/memory.h>
#include <asm/setup.h>
+#include <mach/clk.h>
#include <mach/msm_iomap.h>
#include <mach/dma.h>
@@ -60,10 +61,44 @@ static int hsusb_phy_init_seq[] = {
-1
};
+static int hsusb_link_clk_reset(struct clk *link_clk, bool assert)
+{
+ int ret;
+
+ if (assert) {
+ ret = clk_reset(link_clk, CLK_RESET_ASSERT);
+ if (ret)
+ pr_err("usb hs_clk assert failed\n");
+ } else {
+ ret = clk_reset(link_clk, CLK_RESET_DEASSERT);
+ if (ret)
+ pr_err("usb hs_clk deassert failed\n");
+ }
+ return ret;
+}
+
+static int hsusb_phy_clk_reset(struct clk *phy_clk)
+{
+ int ret;
+
+ ret = clk_reset(phy_clk, CLK_RESET_ASSERT);
+ if (ret) {
+ pr_err("usb phy clk assert failed\n");
+ return ret;
+ }
+ usleep_range(10000, 12000);
+ ret = clk_reset(phy_clk, CLK_RESET_DEASSERT);
+ if (ret)
+ pr_err("usb phy clk deassert failed\n");
+ return ret;
+}
+
static struct msm_otg_platform_data msm_otg_pdata = {
.phy_init_seq = hsusb_phy_init_seq,
.mode = USB_PERIPHERAL,
.otg_control = OTG_PHY_CONTROL,
+ .link_clk_reset = hsusb_link_clk_reset,
+ .phy_clk_reset = hsusb_phy_clk_reset,
};
struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index 5f933bc50783..9169ec324a43 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -31,6 +31,7 @@
#include <mach/irqs.h>
#include <mach/sirc.h>
#include <mach/vreg.h>
+#include <mach/clk.h>
#include <linux/platform_data/mmc-msm_sdcc.h>
#include "devices.h"
@@ -81,10 +82,44 @@ static int hsusb_phy_init_seq[] = {
-1
};
+static int hsusb_link_clk_reset(struct clk *link_clk, bool assert)
+{
+ int ret;
+
+ if (assert) {
+ ret = clk_reset(link_clk, CLK_RESET_ASSERT);
+ if (ret)
+ pr_err("usb hs_clk assert failed\n");
+ } else {
+ ret = clk_reset(link_clk, CLK_RESET_DEASSERT);
+ if (ret)
+ pr_err("usb hs_clk deassert failed\n");
+ }
+ return ret;
+}
+
+static int hsusb_phy_clk_reset(struct clk *phy_clk)
+{
+ int ret;
+
+ ret = clk_reset(phy_clk, CLK_RESET_ASSERT);
+ if (ret) {
+ pr_err("usb phy clk assert failed\n");
+ return ret;
+ }
+ usleep_range(10000, 12000);
+ ret = clk_reset(phy_clk, CLK_RESET_DEASSERT);
+ if (ret)
+ pr_err("usb phy clk deassert failed\n");
+ return ret;
+}
+
static struct msm_otg_platform_data msm_otg_pdata = {
.phy_init_seq = hsusb_phy_init_seq,
.mode = USB_PERIPHERAL,
.otg_control = OTG_PHY_CONTROL,
+ .link_clk_reset = hsusb_link_clk_reset,
+ .phy_clk_reset = hsusb_phy_clk_reset,
};
static struct platform_device *devices[] __initdata = {
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index d1a12a496525..b1232d8be6f5 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -2,6 +2,7 @@ config ARCH_TEGRA
bool "NVIDIA Tegra" if ARCH_MULTI_V7
select ARCH_HAS_CPUFREQ
select ARCH_REQUIRE_GPIOLIB
+ select ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
select ARM_GIC
select CLKSRC_MMIO
select CLKSRC_OF
diff --git a/arch/arm/mach-tegra/reset.c b/arch/arm/mach-tegra/reset.c
index 568f5bbf979d..146fe8e0ae7c 100644
--- a/arch/arm/mach-tegra/reset.c
+++ b/arch/arm/mach-tegra/reset.c
@@ -21,6 +21,7 @@
#include <asm/cacheflush.h>
#include <asm/hardware/cache-l2x0.h>
+#include <asm/firmware.h>
#include "iomap.h"
#include "irammap.h"
@@ -33,26 +34,18 @@
static bool is_enabled;
-static void __init tegra_cpu_reset_handler_enable(void)
+static void __init tegra_cpu_reset_handler_set(const u32 reset_address)
{
- void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
void __iomem *evp_cpu_reset =
IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE + 0x100);
void __iomem *sb_ctrl = IO_ADDRESS(TEGRA_SB_BASE);
u32 reg;
- BUG_ON(is_enabled);
- BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
-
- memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
- tegra_cpu_reset_handler_size);
-
/*
* NOTE: This must be the one and only write to the EVP CPU reset
* vector in the entire system.
*/
- writel(TEGRA_IRAM_RESET_BASE + tegra_cpu_reset_handler_offset,
- evp_cpu_reset);
+ writel(reset_address, evp_cpu_reset);
wmb();
reg = readl(evp_cpu_reset);
@@ -66,8 +59,33 @@ static void __init tegra_cpu_reset_handler_enable(void)
writel(reg, sb_ctrl);
wmb();
}
+}
+
+static void __init tegra_cpu_reset_handler_enable(void)
+{
+ void __iomem *iram_base = IO_ADDRESS(TEGRA_IRAM_RESET_BASE);
+ const u32 reset_address = TEGRA_IRAM_RESET_BASE +
+ tegra_cpu_reset_handler_offset;
+ int err;
+
+ BUG_ON(is_enabled);
+ BUG_ON(tegra_cpu_reset_handler_size > TEGRA_IRAM_RESET_HANDLER_SIZE);
- is_enabled = true;
+ memcpy(iram_base, (void *)__tegra_cpu_reset_handler_start,
+ tegra_cpu_reset_handler_size);
+
+ err = call_firmware_op(set_cpu_boot_addr, 0, reset_address);
+ switch (err) {
+ case -ENOSYS:
+ tegra_cpu_reset_handler_set(reset_address);
+ /* pass-through */
+ case 0:
+ is_enabled = true;
+ break;
+ default:
+ pr_crit("Cannot set CPU reset handler: %d\n", err);
+ BUG();
+ }
}
void __init tegra_cpu_reset_handler_init(void)
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
index ea14d380fc0c..303a285d80fd 100644
--- a/arch/arm/mach-tegra/tegra.c
+++ b/arch/arm/mach-tegra/tegra.c
@@ -40,6 +40,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <asm/setup.h>
+#include <asm/trusted_foundations.h>
#include "apbio.h"
#include "board.h"
@@ -88,6 +89,7 @@ static void __init tegra_init_cache(void)
static void __init tegra_init_early(void)
{
+ of_register_trusted_foundations();
tegra_apb_io_init();
tegra_init_fuse();
tegra_cpu_reset_handler_init();