aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 15:33:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-04 15:33:36 -0400
commite3d98847ded1d183111ff7c4d1ef56b161c7f13e (patch)
tree8ec2b298eef4f1695ca612014b7f75b85badae45 /Documentation/arm
parent22b154365fbc096a46d936ec1f462ef8b9bd1f05 (diff)
parent721e0205b07589223343737a9c421d8118d87bba (diff)
Merge tag 'firmware-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM platform specific firmware interfaces from Olof Johansson: "Two platforms, bcm and exynos have their own firmware interfaces using the "secure monitor call", this adds support for those. We had originally planned to have a third set of patches in here, which would extend support for the existing generic "psci" call that is used on multiple platforms as well as Xen and KVM guests, but that ended up getting dropped because the patches were not ready in time." * tag 'firmware-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: ARM: bcm: mark bcm_kona_smc_init as __init ARM: bcm281xx: Add DT support for SMC handler ARM: bcm281xx: Add L2 cache enable code ARM: EXYNOS: Add secure firmware support to secondary CPU bring-up ARM: EXYNOS: Add IO mapping for non-secure SYSRAM. ARM: EXYNOS: Add support for Exynos secure firmware ARM: EXYNOS: Add support for secure monitor calls ARM: Add interface for registering and calling firmware-specific operations
Diffstat (limited to 'Documentation/arm')
-rw-r--r--Documentation/arm/firmware.txt88
1 files changed, 88 insertions, 0 deletions
diff --git a/Documentation/arm/firmware.txt b/Documentation/arm/firmware.txt
new file mode 100644
index 000000000000..c2e468fe7b0b
--- /dev/null
+++ b/Documentation/arm/firmware.txt
@@ -0,0 +1,88 @@
1Interface for registering and calling firmware-specific operations for ARM.
2----
3Written by Tomasz Figa <t.figa@samsung.com>
4
5Some boards are running with secure firmware running in TrustZone secure
6world, which changes the way some things have to be initialized. This makes
7a need to provide an interface for such platforms to specify available firmware
8operations and call them when needed.
9
10Firmware operations can be specified using struct firmware_ops
11
12 struct firmware_ops {
13 /*
14 * Enters CPU idle mode
15 */
16 int (*do_idle)(void);
17 /*
18 * Sets boot address of specified physical CPU
19 */
20 int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr);
21 /*
22 * Boots specified physical CPU
23 */
24 int (*cpu_boot)(int cpu);
25 /*
26 * Initializes L2 cache
27 */
28 int (*l2x0_init)(void);
29 };
30
31and then registered with register_firmware_ops function
32
33 void register_firmware_ops(const struct firmware_ops *ops)
34
35the ops pointer must be non-NULL.
36
37There is a default, empty set of operations provided, so there is no need to
38set anything if platform does not require firmware operations.
39
40To call a firmware operation, a helper macro is provided
41
42 #define call_firmware_op(op, ...) \
43 ((firmware_ops->op) ? firmware_ops->op(__VA_ARGS__) : (-ENOSYS))
44
45the macro checks if the operation is provided and calls it or otherwise returns
46-ENOSYS to signal that given operation is not available (for example, to allow
47fallback to legacy operation).
48
49Example of registering firmware operations:
50
51 /* board file */
52
53 static int platformX_do_idle(void)
54 {
55 /* tell platformX firmware to enter idle */
56 return 0;
57 }
58
59 static int platformX_cpu_boot(int i)
60 {
61 /* tell platformX firmware to boot CPU i */
62 return 0;
63 }
64
65 static const struct firmware_ops platformX_firmware_ops = {
66 .do_idle = exynos_do_idle,
67 .cpu_boot = exynos_cpu_boot,
68 /* other operations not available on platformX */
69 };
70
71 /* init_early callback of machine descriptor */
72 static void __init board_init_early(void)
73 {
74 register_firmware_ops(&platformX_firmware_ops);
75 }
76
77Example of using a firmware operation:
78
79 /* some platform code, e.g. SMP initialization */
80
81 __raw_writel(virt_to_phys(exynos4_secondary_startup),
82 CPU1_BOOT_REG);
83
84 /* Call Exynos specific smc call */
85 if (call_firmware_op(cpu_boot, cpu) == -ENOSYS)
86 cpu_boot_legacy(...); /* Try legacy way */
87
88 gic_raise_softirq(cpumask_of(cpu), 1);