--- /dev/null
+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 using struct firmware_ops
+
+       struct firmware_ops {
+               /*
+               * Enters CPU idle mode
+               */
+               int (*do_idle)(void);
+               /*
+               * Sets boot address of specified physical CPU
+               */
+               int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr);
+               /*
+               * Boots specified physical CPU
+               */
+               int (*cpu_boot)(int cpu);
+               /*
+               * Initializes L2 cache
+               */
+               int (*l2x0_init)(void);
+       };
+
+and then registered with register_firmware_ops function
+
+       void register_firmware_ops(const struct firmware_ops *ops)
+
+the ops pointer must be non-NULL.
+
+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(virt_to_phys(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);
 
--- /dev/null
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ * Tomasz Figa <t.figa@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+
+#include <asm/firmware.h>
+
+static const struct firmware_ops default_firmware_ops;
+
+const struct firmware_ops *firmware_ops = &default_firmware_ops;
 
--- /dev/null
+/*
+ * Copyright (C) 2012 Samsung Electronics.
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ * Tomasz Figa <t.figa@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARM_FIRMWARE_H
+#define __ASM_ARM_FIRMWARE_H
+
+#include <linux/bug.h>
+
+/*
+ * struct firmware_ops
+ *
+ * A structure to specify available firmware operations.
+ *
+ * A filled up structure can be registered with register_firmware_ops().
+ */
+struct firmware_ops {
+       /*
+        * Enters CPU idle mode
+        */
+       int (*do_idle)(void);
+       /*
+        * Sets boot address of specified physical CPU
+        */
+       int (*set_cpu_boot_addr)(int cpu, unsigned long boot_addr);
+       /*
+        * Boots specified physical CPU
+        */
+       int (*cpu_boot)(int cpu);
+       /*
+        * Initializes L2 cache
+        */
+       int (*l2x0_init)(void);
+};
+
+/* Global pointer for current firmware_ops structure, can't be NULL. */
+extern const struct firmware_ops *firmware_ops;
+
+/*
+ * call_firmware_op(op, ...)
+ *
+ * Checks if firmware operation is present and calls it,
+ * otherwise returns -ENOSYS
+ */
+#define call_firmware_op(op, ...)                                      \
+       ((firmware_ops->op) ? firmware_ops->op(__VA_ARGS__) : (-ENOSYS))
+
+/*
+ * register_firmware_ops(ops)
+ *
+ * A function to register platform firmware_ops struct.
+ */
+static inline void register_firmware_ops(const struct firmware_ops *ops)
+{
+       BUG_ON(!ops);
+
+       firmware_ops = ops;
+}
+
+#endif