From patchwork Thu Mar 28 17:54:02 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Pali_Roh=C3=A1r?= X-Patchwork-Id: 2359011 Return-Path: X-Original-To: patchwork-linux-omap@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 82CC3DF2A1 for ; Thu, 28 Mar 2013 17:54:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752929Ab3C1RyJ (ORCPT ); Thu, 28 Mar 2013 13:54:09 -0400 Received: from mail-ea0-f175.google.com ([209.85.215.175]:34080 "EHLO mail-ea0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752558Ab3C1RyH (ORCPT ); Thu, 28 Mar 2013 13:54:07 -0400 Received: by mail-ea0-f175.google.com with SMTP id r16so1378448ead.34 for ; Thu, 28 Mar 2013 10:54:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:subject:date:user-agent:cc:references :in-reply-to:mime-version:content-type:content-transfer-encoding :message-id; bh=ClPolhoJUjB1rOhLfPXON0Vlw3ekPpy1dE/y4X4uGQM=; b=PcDzB4EJO040bzDouGjXgCOoXCBGjnpLIUBgePNadigqtIW76LwTphOFX9MZiaFDcD Hl+0D0jNNzQtnOmDZ7DRrR3ae1li4Hvv5oF3HgIZ59iCAQHG6n4c06S7JxNaEqYVERgT MCSRfzagzScqoTUoG2wSKO9w8z7WzgxkPAQC+me9ZJnKdSC8T8TSW0Y5AtiDyscZ3NRo jfoXIPl2q2LFMMoePCD1cjAk8uabaZRqVJYAX+a/ijJmIqpR4V6smgOgUbf5um0MbcMS 6kHaVMs/zcX5cGsFvCXc3cKr3yM2OuLw2mIwJnfxo8Jaw2kpRS+Rgaw5y6bZ0yVEAnVv Nksw== X-Received: by 10.14.193.134 with SMTP id k6mr69319565een.37.1364493245397; Thu, 28 Mar 2013 10:54:05 -0700 (PDT) Received: from pali-elitebook.localnet ([2001:718:1e03:a01::1ca]) by mx.google.com with ESMTPS id d47sm39170793eem.9.2013.03.28.10.54.03 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 28 Mar 2013 10:54:04 -0700 (PDT) From: Pali =?utf-8?q?Roh=C3=A1r?= To: Tony Lindgren Subject: Re: [PATCH] OMAP3 ROM Random Number Generator support Date: Thu, 28 Mar 2013 18:54:02 +0100 User-Agent: KMail/1.13.7 (Linux/3.5.0-27-generic; KDE/4.10.1; x86_64; ; ) Cc: Juha Yrjola , Russell King , Matt Mackall , Herbert Xu , linux-omap@vger.kernel.org, linux-kernel@vger.kernel.org References: <201302281905.48546@pali> <201303272303.44420@pali> <20130327222524.GR10155@atomide.com> In-Reply-To: <20130327222524.GR10155@atomide.com> MIME-Version: 1.0 Message-Id: <201303281854.02847@pali> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org On Wednesday 27 March 2013 23:25:24 Tony Lindgren wrote: > * Pali Rohár [130327 15:08]: > > I will remove above code for checking omap type from hw rand > > driver, because same code is in omap part which creating > > platform_device for this driver. So soc.h is not needed. > > OK thanks, > > Tony Here is new version of patch: 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 + * + * 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 +#include + +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 + * + * Copyright (C) 2013 Pali Rohár + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#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 "); +MODULE_LICENSE("GPL");