Message ID | 201303281854.02847@pali (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
* Pali Rohár <pali.rohar@gmail.com> [130328 10:58]: > > Here is new version of patch: > > --- a/arch/arm/mach-omap2/devices.c > +++ b/arch/arm/mach-omap2/devices.c > @@ -486,6 +486,23 @@ static void omap_init_mcspi(void) > static inline void omap_init_mcspi(void) {} > #endif > > +extern u32 *omap3_rom_rng_call(u32 id, u32 proc, u32 flags, u32 va_ptr); > + > +static struct platform_device omap3_rom_rng_device = { > + .name = "omap3-rom-rng", > + .id = -1, > + .dev = { > + .platform_data = omap3_rom_rng_call, > + }, > +}; > + > +static void omap_init_rom_rng(void) > +{ > + if (!cpu_is_omap34xx() || omap_type() == OMAP2_DEVICE_TYPE_GP) > + return; > + platform_device_register(&omap3_rom_rng_device); > +} > + > /** > * omap_init_rng - bind the RNG hwmod to the RNG omap_device > * This driver probably only works on Nokia boards because of the different SMC call numbering. Until it's been verified on some other HS omap34xx, I'd probably register this only from the Nokia board-*.c file. > --- /dev/null > +++ b/drivers/char/hw_random/omap3-rom-rng.c > +static int omap3_rom_rng_probe(struct platform_device *pdev) > +{ > + printk(KERN_INFO "%s: initializing\n", omap3_rom_rng_name); > + > + omap3_rom_rng_call = pdev->dev.platform_data; > + if (!omap3_rom_rng_call) { > + printk(KERN_ERR "%s: omap3_rom_rng_call is NULL\n", > + omap3_rom_rng_name); > + return -EINVAL; > + } > + > + setup_timer(&idle_timer, omap3_rom_idle_rng, 0); > + rng_clk = clk_get_sys("omap_rng", "ick"); > + if (IS_ERR(rng_clk)) { > + printk(KERN_ERR "%s: unable to get RNG clock\n", > + omap3_rom_rng_name); > + return IS_ERR(rng_clk); > + } You can use regular clk_get if you add the alias to struct omap_clk omap3xxx_clks table. Regards, Tony -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thursday 28 March 2013 22:44:11 Tony Lindgren wrote: > * Pali Rohár <pali.rohar@gmail.com> [130328 10:58]: > > Here is new version of patch: > > > > --- a/arch/arm/mach-omap2/devices.c > > +++ b/arch/arm/mach-omap2/devices.c > > @@ -486,6 +486,23 @@ static void omap_init_mcspi(void) > > > > static inline void omap_init_mcspi(void) {} > > #endif > > > > +extern u32 *omap3_rom_rng_call(u32 id, u32 proc, u32 flags, > > u32 va_ptr); + > > +static struct platform_device omap3_rom_rng_device = { > > + .name = "omap3-rom-rng", > > + .id = -1, > > + .dev = { > > + .platform_data = omap3_rom_rng_call, > > + }, > > +}; > > + > > +static void omap_init_rom_rng(void) > > +{ > > + if (!cpu_is_omap34xx() || omap_type() == > > OMAP2_DEVICE_TYPE_GP) + return; > > + platform_device_register(&omap3_rom_rng_device); > > +} > > + > > > > /** > > > > * omap_init_rng - bind the RNG hwmod to the RNG > > omap_device * > > This driver probably only works on Nokia boards because of the > different SMC call numbering. Until it's been verified on some > other HS omap34xx, I'd probably register this only from the > Nokia board-*.c file. > Freemangordon, can you look at this smc and errara 430973 code if they could be merged? Really omap3_rom_rng_call function looks like n900 specific. Link: https://lkml.org/lkml/2013/3/28/398 > > --- /dev/null > > +++ b/drivers/char/hw_random/omap3-rom-rng.c > > +static int omap3_rom_rng_probe(struct platform_device > > *pdev) +{ > > + printk(KERN_INFO "%s: initializing\n", > > omap3_rom_rng_name); + > > + omap3_rom_rng_call = pdev->dev.platform_data; > > + if (!omap3_rom_rng_call) { > > + printk(KERN_ERR "%s: omap3_rom_rng_call is NULL\n", > > + omap3_rom_rng_name); > > + return -EINVAL; > > + } > > + > > + setup_timer(&idle_timer, omap3_rom_idle_rng, 0); > > + rng_clk = clk_get_sys("omap_rng", "ick"); > > + if (IS_ERR(rng_clk)) { > > + printk(KERN_ERR "%s: unable to get RNG clock\n", > > + omap3_rom_rng_name); > > + return IS_ERR(rng_clk); > > + } > > You can use regular clk_get if you add the alias to > struct omap_clk omap3xxx_clks table. > > Regards, > > Tony Tony, can you show me how?
* Pali Rohár <pali.rohar@gmail.com> [130331 02:32]: > On Thursday 28 March 2013 22:44:11 Tony Lindgren wrote: > > > > You can use regular clk_get if you add the alias to > > struct omap_clk omap3xxx_clks table. > > Tony, can you show me how? Take a look at the omap3xxx_clks in cclock3xxx_data.c. Note how some entries have things like "omap_hsmmc.0" and "ick". By adding those your driver can request the clock with clk_get(&pdev->dev, "ick"). Regards, Tony -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
This two patches adding support for OMAP3 ROM Random Number Generator on Nokia N900. Pali Rohár (2): hwrng: OMAP3 ROM Random Number Generator support RX-51: Add support for OMAP3 ROM Random Number Generator arch/arm/mach-omap2/board-rx51.c | 10 +++ arch/arm/mach-omap2/omap-secure.c | 11 +++ arch/arm/mach-omap2/omap-secure.h | 1 + drivers/char/hw_random/Kconfig | 13 +++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/omap3-rom-rng.c | 145 ++++++++++++++++++++++++++++++++ 6 files changed, 181 insertions(+) create mode 100644 drivers/char/hw_random/omap3-rom-rng.c
This patch series adding support for OMAP3 ROM Random Number Generator on Nokia N900. In previous version I forgot to send patch which changing clk dev id to new driver name. Pali Rohár (3): omap2: Change clk dev id for rng to omap3-rom-rng hwrng: OMAP3 ROM Random Number Generator support RX-51: Add support for OMAP3 ROM Random Number Generator arch/arm/mach-omap2/board-rx51-peripherals.c | 19 ++++ arch/arm/mach-omap2/cclock3xxx_data.c | 2 +- arch/arm/mach-omap2/omap-secure.c | 11 ++ arch/arm/mach-omap2/omap-secure.h | 1 + drivers/char/hw_random/Kconfig | 13 +++ drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/omap3-rom-rng.c | 141 ++++++++++++++++++++++++++ 7 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 drivers/char/hw_random/omap3-rom-rng.c
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 5423456..37c4e09 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -82,7 +82,7 @@ obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o ifeq ($(CONFIG_PM),y) obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o -obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o +obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o omap3-rom-rng.o obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o omap-mpuss-lowpower.o obj-$(CONFIG_SOC_OMAP5) += omap-mpuss-lowpower.o obj-$(CONFIG_PM_DEBUG) += pm-debug.o diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 1ec7f05..0b6260a1 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -486,6 +486,23 @@ static void omap_init_mcspi(void) static inline void omap_init_mcspi(void) {} #endif +extern u32 *omap3_rom_rng_call(u32 id, u32 proc, u32 flags, u32 va_ptr); + +static struct platform_device omap3_rom_rng_device = { + .name = "omap3-rom-rng", + .id = -1, + .dev = { + .platform_data = omap3_rom_rng_call, + }, +}; + +static void omap_init_rom_rng(void) +{ + if (!cpu_is_omap34xx() || omap_type() == OMAP2_DEVICE_TYPE_GP) + return; + platform_device_register(&omap3_rom_rng_device); +} + /** * omap_init_rng - bind the RNG hwmod to the RNG omap_device * @@ -767,6 +784,7 @@ static int __init omap2_init_devices(void) } omap_init_sti(); omap_init_rng(); + omap_init_rom_rng(); omap_init_sham(); omap_init_aes(); omap_init_vout(); diff --git a/arch/arm/mach-omap2/omap3-rom-rng.S b/arch/arm/mach-omap2/omap3-rom-rng.S new file mode 100644 index 0000000..5d7d886 --- /dev/null +++ b/arch/arm/mach-omap2/omap3-rom-rng.S @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2009 Nokia Corporation + * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.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/linkage.h> +#include <asm/assembler.h> + +ENTRY(omap3_rom_rng_call) + .arch_extension sec + stmfd sp!, {r4-r12, lr} + stmfd sp!, {r0-r3} + bl v7_flush_dcache_all + ldmfd sp!, {r0-r3} + mov r6, #0xff + mov r12, r0 + smc #1 + mov r12, r0 + bl v7_flush_dcache_all + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 + mov r0, r12 + ldmfd sp!, {r4-r12, pc} diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index c5a0262..2d51db6 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -153,6 +153,19 @@ config HW_RANDOM_OMAP If unsure, say Y. +config HW_RANDOM_OMAP3_ROM + tristate "OMAP3 ROM Random Number Generator support" + depends on HW_RANDOM && ARCH_OMAP3 + default HW_RANDOM + ---help--- + This driver provides kernel-side support for the Random Number + Generator hardware found on OMAP34xx processors. + + To compile this driver as a module, choose M here: the + module will be called omap3-rom-rng. + + If unsure, say Y. + config HW_RANDOM_OCTEON tristate "Octeon Random Number Generator support" depends on HW_RANDOM && CPU_CAVIUM_OCTEON diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index 1fd7eec..c53e018 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -15,6 +15,7 @@ n2-rng-y := n2-drv.o n2-asm.o obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o +obj-$(CONFIG_HW_RANDOM_OMAP3_ROM) += omap3-rom-rng.o obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c new file mode 100644 index 0000000..5343415 --- /dev/null +++ b/drivers/char/hw_random/omap3-rom-rng.c @@ -0,0 +1,165 @@ +/* + * omap3-rom-drv.c - RNG driver for TI OMAP3 CPU family + * + * Copyright (C) 2009 Nokia Corporation + * Author: Juha Yrjola <juha.yrjola@solidboot.com> + * + * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com> + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/random.h> +#include <linux/hw_random.h> +#include <linux/timer.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/platform_device.h> + +#define SEC_HAL_RNG_GENERATE 29 +#define RNG_RESET 0x01 +#define RNG_GEN_PRNG_HW_INIT 0x02 +#define RNG_GEN_HW 0x08 + +static const char *omap3_rom_rng_name = "OMAP3 ROM RNG"; + +static u32 (*omap3_rom_rng_call)(u32, u32, u32, u32); + +static int call_sec_rom(u32 appl_id, u32 proc_id, u32 flag, ...) +{ + va_list ap; + u32 ret; + u32 val; + + va_start(ap, flag); + val = *(u32 *) ≈ + local_irq_disable(); + local_fiq_disable(); + ret = omap3_rom_rng_call(appl_id, proc_id, flag, + (u32) virt_to_phys((void *) val)); + local_fiq_enable(); + local_irq_enable(); + va_end(ap); + + return ret; +} + +static struct timer_list idle_timer; +static int rng_idle; +static struct clk *rng_clk; + +static void omap3_rom_idle_rng(unsigned long data) +{ + int r; + + r = call_sec_rom(SEC_HAL_RNG_GENERATE, 0, 0, 3, NULL, 0, + RNG_RESET); + if (r != 0) { + printk(KERN_ERR "%s: reset failed: %d\n", + omap3_rom_rng_name, r); + return; + } + clk_disable_unprepare(rng_clk); + rng_idle = 1; +} + +static int omap3_rom_get_random(void *buf, unsigned int count) +{ + u32 r; + u32 ptr; + + del_timer_sync(&idle_timer); + if (rng_idle) { + clk_prepare_enable(rng_clk); + r = call_sec_rom(SEC_HAL_RNG_GENERATE, 0, 0, 3, NULL, 0, + RNG_GEN_PRNG_HW_INIT); + if (r != 0) { + clk_disable_unprepare(rng_clk); + printk(KERN_ERR "%s: HW init failed: %d\n", + omap3_rom_rng_name, r); + return -EIO; + } + rng_idle = 0; + } + + ptr = virt_to_phys(buf); + r = call_sec_rom(SEC_HAL_RNG_GENERATE, 0, 0, 3, ptr, + count, RNG_GEN_HW); + mod_timer(&idle_timer, jiffies + msecs_to_jiffies(500)); + if (r != 0) + return -EINVAL; + return 0; +} + +static int omap3_rom_rng_data_present(struct hwrng *rng, int wait) +{ + return 1; +} + +static int omap3_rom_rng_data_read(struct hwrng *rng, u32 *data) +{ + int r; + + r = omap3_rom_get_random(data, 4); + if (r < 0) + return r; + return 4; +} + +static struct hwrng omap3_rom_rng_ops = { + .name = "omap3-rom", + .data_present = omap3_rom_rng_data_present, + .data_read = omap3_rom_rng_data_read, +}; + +static int omap3_rom_rng_probe(struct platform_device *pdev) +{ + printk(KERN_INFO "%s: initializing\n", omap3_rom_rng_name); + + omap3_rom_rng_call = pdev->dev.platform_data; + if (!omap3_rom_rng_call) { + printk(KERN_ERR "%s: omap3_rom_rng_call is NULL\n", + omap3_rom_rng_name); + return -EINVAL; + } + + setup_timer(&idle_timer, omap3_rom_idle_rng, 0); + rng_clk = clk_get_sys("omap_rng", "ick"); + if (IS_ERR(rng_clk)) { + printk(KERN_ERR "%s: unable to get RNG clock\n", + omap3_rom_rng_name); + return IS_ERR(rng_clk); + } + + /* Leave the RNG in reset state. */ + clk_prepare_enable(rng_clk); + omap3_rom_idle_rng(0); + + return hwrng_register(&omap3_rom_rng_ops); +} + +static int omap3_rom_rng_remove(struct platform_device *pdev) +{ + hwrng_unregister(&omap3_rom_rng_ops); + return 0; +} + +static struct platform_driver omap3_rom_rng_driver = { + .driver = { + .name = "omap3-rom-rng", + .owner = THIS_MODULE, + }, + .probe = omap3_rom_rng_probe, + .remove = omap3_rom_rng_remove, +}; + +module_platform_driver(omap3_rom_rng_driver); + +MODULE_ALIAS("platform:omap3-rom-rng"); +MODULE_AUTHOR("Juha Yrjola"); +MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>"); +MODULE_LICENSE("GPL");