Based on kernel version 4.16.1. Page generated on 2018-04-09 11:52 EST.
1 Interface for registering and calling firmware-specific operations for ARM. 2 ---- 3 Written by Tomasz Figa <t.figa@samsung.com> 4 5 Some boards are running with secure firmware running in TrustZone secure 6 world, which changes the way some things have to be initialized. This makes 7 a need to provide an interface for such platforms to specify available firmware 8 operations and call them when needed. 9 10 Firmware operations can be specified by filling in a struct firmware_ops 11 with appropriate callbacks and then registering it with register_firmware_ops() 12 function. 13 14 void register_firmware_ops(const struct firmware_ops *ops) 15 16 The ops pointer must be non-NULL. More information about struct firmware_ops 17 and its members can be found in arch/arm/include/asm/firmware.h header. 18 19 There is a default, empty set of operations provided, so there is no need to 20 set anything if platform does not require firmware operations. 21 22 To call a firmware operation, a helper macro is provided 23 24 #define call_firmware_op(op, ...) \ 25 ((firmware_ops->op) ? firmware_ops->op(__VA_ARGS__) : (-ENOSYS)) 26 27 the macro checks if the operation is provided and calls it or otherwise returns 28 -ENOSYS to signal that given operation is not available (for example, to allow 29 fallback to legacy operation). 30 31 Example of registering firmware operations: 32 33 /* board file */ 34 35 static int platformX_do_idle(void) 36 { 37 /* tell platformX firmware to enter idle */ 38 return 0; 39 } 40 41 static int platformX_cpu_boot(int i) 42 { 43 /* tell platformX firmware to boot CPU i */ 44 return 0; 45 } 46 47 static const struct firmware_ops platformX_firmware_ops = { 48 .do_idle = exynos_do_idle, 49 .cpu_boot = exynos_cpu_boot, 50 /* other operations not available on platformX */ 51 }; 52 53 /* init_early callback of machine descriptor */ 54 static void __init board_init_early(void) 55 { 56 register_firmware_ops(&platformX_firmware_ops); 57 } 58 59 Example of using a firmware operation: 60 61 /* some platform code, e.g. SMP initialization */ 62 63 __raw_writel(__pa_symbol(exynos4_secondary_startup), 64 CPU1_BOOT_REG); 65 66 /* Call Exynos specific smc call */ 67 if (call_firmware_op(cpu_boot, cpu) == -ENOSYS) 68 cpu_boot_legacy(...); /* Try legacy way */ 69 70 gic_raise_softirq(cpumask_of(cpu), 1);