[PATCH 2/5] ARM: Add interface for registering and calling firmware-specific operations

Kyungmin Park kyungmin.park at samsung.com
Sat Sep 22 02:01:56 EDT 2012


On 9/22/12, Olof Johansson <olof at lixom.net> wrote:
> On Thu, Sep 13, 2012 at 10:13:35AM +0200, Tomasz Figa wrote:
>> Some boards are running with secure firmware running in TrustZone secure
>> world, which changes the way some things have to be initialized.
>>
>> This patch adds an interface for platforms to specify available firmware
>> operations and call them.
>>
>> A wrapper macro, call_firmware_op(), checks if the operation is provided
>> and calls it if so, otherwise returns 0.
>>
>> By default no operations are provided.
>>
>> This is a follow-up on the patch by Kyungmin Park:
>> [PATCH v5 1/2] ARM: Make a compile firmware conditionally
>> http://thread.gmane.org/gmane.linux.ports.arm.kernel/183607/focus=183988
>>
>> Example of use:
>>
>> In code using firmware ops:
>>
>> 	__raw_writel(virt_to_phys(exynos4_secondary_startup),
>> 		CPU1_BOOT_REG);
>>
>> 	/* Call Exynos specific smc call */
>> 	do_firmware_op(cpu_boot, cpu);
>>
>> 	gic_raise_softirq(cpumask_of(cpu), 1);
>>
>> In board-/platform-specific code:
>>
>> 	static int platformX_do_idle(void)
>> 	{
>> 		/* tell platformX firmware to enter idle */
>> 	        return 0;
>> 	}
>>
>> 	static void platformX_cpu_boot(int i)
>> 	{
>> 		/* tell platformX firmware to boot CPU i */
>> 	}
>>
>> 	static const struct firmware_ops platformX_firmware_ops __initdata = {
>> 		.do_idle	= exynos_do_idle,
>> 		.cpu_boot	= exynos_cpu_boot,
>> 		/* cpu_boot_reg not available on platformX */
>> 	};
>>
>> 	static void __init board_init_early(void)
>> 	{
>> 	        register_firmware_ops(&platformX_firmware_ops);
>> 	}
>>
>> Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
>> Signed-off-by: Tomasz Figa <t.figa at samsung.com>
>> ---
>>  arch/arm/common/Makefile        |  2 ++
>>  arch/arm/common/firmware.c      | 18 ++++++++++++++++++
>>  arch/arm/include/asm/firmware.h | 30 ++++++++++++++++++++++++++++++
>>  3 files changed, 50 insertions(+)
>>  create mode 100644 arch/arm/common/firmware.c
>>  create mode 100644 arch/arm/include/asm/firmware.h
>>
>> diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
>> index e8a4e58..55d4182 100644
>> --- a/arch/arm/common/Makefile
>> +++ b/arch/arm/common/Makefile
>> @@ -2,6 +2,8 @@
>>  # Makefile for the linux kernel.
>>  #
>>
>> +obj-y += firmware.o
>> +
>>  obj-$(CONFIG_ARM_GIC)		+= gic.o
>>  obj-$(CONFIG_ARM_VIC)		+= vic.o
>>  obj-$(CONFIG_ICST)		+= icst.o
>> diff --git a/arch/arm/common/firmware.c b/arch/arm/common/firmware.c
>> new file mode 100644
>> index 0000000..27ddccb
>> --- /dev/null
>> +++ b/arch/arm/common/firmware.c
>> @@ -0,0 +1,18 @@
>> +/*
>> + * Copyright (C) 2012 Samsung Electronics.
>> + * Kyungmin Park <kyungmin.park at samsung.com>
>> + * Tomasz Figa <t.figa at 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;
>> diff --git a/arch/arm/include/asm/firmware.h
>> b/arch/arm/include/asm/firmware.h
>> new file mode 100644
>> index 0000000..ed51b02
>> --- /dev/null
>> +++ b/arch/arm/include/asm/firmware.h
>> @@ -0,0 +1,30 @@
>> +/*
>> + * Copyright (C) 2012 Samsung Electronics.
>> + * Kyungmin Park <kyungmin.park at samsung.com>
>> + * Tomasz Figa <t.figa at 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
>> +
>> +struct firmware_ops {
>> +	int (*do_idle)(void);
>> +	void (*cpu_boot)(int cpu);
>> +	void __iomem *(*cpu_boot_reg)(int cpu);
>> +};
>> +
>> +extern const struct firmware_ops *firmware_ops;
>> +
>> +#define call_firmware_op(op, ...)					\
>> +	((firmware_ops->op) ? firmware_ops->op(__VA_ARGS__) : 0)
>
> I think this will cause sparse warnings for call_firmware_op(cpu_boot_reg)
> if there are no ops defined, since the '0' isn't annotated as __iomem. And
> you can't annotate it since the other function pointers don't need it.
>
> I think you might be better off with stub functions as fallbacks instead of
> allowing and checking for NULL here.
do you mean like this?

#Ifdef CONFIG_ARM_FIRMWARE
#define call_firmware_op(op, ...) ((firmware_ops->op) ?
firmware_ops->op(__VA_ARGS__) : 0)
#else
#define call_firmware_op(op, ...) do { } while (0)
#endif

No problem to modify it.

Thank you,
Kyungmin Park
>
>
> -Olof
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc"
> in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



More information about the linux-arm-kernel mailing list