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