summaryrefslogtreecommitdiffstats
path: root/Documentation/arm/firmware.rst
diff options
context:
space:
mode:
authorLinus Torvalds2019-07-16 21:21:41 +0200
committerLinus Torvalds2019-07-16 21:21:41 +0200
commitc309b6f24222246c18a8b65d3950e6e755440865 (patch)
tree11893170f5c246bb0dee8066e85878af04162ab0 /Documentation/arm/firmware.rst
parentMerge tag 'xtensa-20190715' of git://github.com/jcmvbkbc/linux-xtensa (diff)
parentdocs: kbuild: fix build with pdf and fix some minor issues (diff)
downloadkernel-qcow2-linux-c309b6f24222246c18a8b65d3950e6e755440865.tar.gz
kernel-qcow2-linux-c309b6f24222246c18a8b65d3950e6e755440865.tar.xz
kernel-qcow2-linux-c309b6f24222246c18a8b65d3950e6e755440865.zip
Merge tag 'docs/v5.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull rst conversion of docs from Mauro Carvalho Chehab: "As agreed with Jon, I'm sending this big series directly to you, c/c him, as this series required a special care, in order to avoid conflicts with other trees" * tag 'docs/v5.3-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (77 commits) docs: kbuild: fix build with pdf and fix some minor issues docs: block: fix pdf output docs: arm: fix a breakage with pdf output docs: don't use nested tables docs: gpio: add sysfs interface to the admin-guide docs: locking: add it to the main index docs: add some directories to the main documentation index docs: add SPDX tags to new index files docs: add a memory-devices subdir to driver-api docs: phy: place documentation under driver-api docs: serial: move it to the driver-api docs: driver-api: add remaining converted dirs to it docs: driver-api: add xilinx driver API documentation docs: driver-api: add a series of orphaned documents docs: admin-guide: add a series of orphaned documents docs: cgroup-v1: add it to the admin-guide book docs: aoe: add it to the driver-api book docs: add some documentation dirs to the driver-api book docs: driver-model: move it to the driver-api book docs: lp855x-driver.rst: add it to the driver-api book ...
Diffstat (limited to 'Documentation/arm/firmware.rst')
-rw-r--r--Documentation/arm/firmware.rst72
1 files changed, 72 insertions, 0 deletions
diff --git a/Documentation/arm/firmware.rst b/Documentation/arm/firmware.rst
new file mode 100644
index 000000000000..efd844baec1d
--- /dev/null
+++ b/Documentation/arm/firmware.rst
@@ -0,0 +1,72 @@
+==========================================================================
+Interface for registering and calling firmware-specific operations for ARM
+==========================================================================
+
+Written by Tomasz Figa <t.figa@samsung.com>
+
+Some boards are running with secure firmware running in TrustZone secure
+world, which changes the way some things have to be initialized. This makes
+a need to provide an interface for such platforms to specify available firmware
+operations and call them when needed.
+
+Firmware operations can be specified by filling in a struct firmware_ops
+with appropriate callbacks and then registering it with register_firmware_ops()
+function::
+
+ void register_firmware_ops(const struct firmware_ops *ops)
+
+The ops pointer must be non-NULL. More information about struct firmware_ops
+and its members can be found in arch/arm/include/asm/firmware.h header.
+
+There is a default, empty set of operations provided, so there is no need to
+set anything if platform does not require firmware operations.
+
+To call a firmware operation, a helper macro is provided::
+
+ #define call_firmware_op(op, ...) \
+ ((firmware_ops->op) ? firmware_ops->op(__VA_ARGS__) : (-ENOSYS))
+
+the macro checks if the operation is provided and calls it or otherwise returns
+-ENOSYS to signal that given operation is not available (for example, to allow
+fallback to legacy operation).
+
+Example of registering firmware operations::
+
+ /* board file */
+
+ static int platformX_do_idle(void)
+ {
+ /* tell platformX firmware to enter idle */
+ return 0;
+ }
+
+ static int platformX_cpu_boot(int i)
+ {
+ /* tell platformX firmware to boot CPU i */
+ return 0;
+ }
+
+ static const struct firmware_ops platformX_firmware_ops = {
+ .do_idle = exynos_do_idle,
+ .cpu_boot = exynos_cpu_boot,
+ /* other operations not available on platformX */
+ };
+
+ /* init_early callback of machine descriptor */
+ static void __init board_init_early(void)
+ {
+ register_firmware_ops(&platformX_firmware_ops);
+ }
+
+Example of using a firmware operation::
+
+ /* some platform code, e.g. SMP initialization */
+
+ __raw_writel(__pa_symbol(exynos4_secondary_startup),
+ CPU1_BOOT_REG);
+
+ /* Call Exynos specific smc call */
+ if (call_firmware_op(cpu_boot, cpu) == -ENOSYS)
+ cpu_boot_legacy(...); /* Try legacy way */
+
+ gic_raise_softirq(cpumask_of(cpu), 1);