-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Alexander Clouter
authored and
Herbert Xu
committed
Feb 22, 2009
1 parent
935cedf
commit fc7a665
Showing
5 changed files
with
188 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 0a2e821d627ad5ced23cf31137625b81cc205e0f | ||
refs/heads/master: 9c3c133b1ed6e6d01bfabb6de29bf3d0f0886354 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
/* | ||
* drivers/char/hw_random/timeriomem-rng.c | ||
* | ||
* Copyright (C) 2009 Alexander Clouter <alex@digriz.org.uk> | ||
* | ||
* Derived from drivers/char/hw_random/omap-rng.c | ||
* Copyright 2005 (c) MontaVista Software, Inc. | ||
* Author: Deepak Saxena <dsaxena@plexity.net> | ||
* | ||
* 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. | ||
* | ||
* Overview: | ||
* This driver is useful for platforms that have an IO range that provides | ||
* periodic random data from a single IO memory address. All the platform | ||
* has to do is provide the address and 'wait time' that new data becomes | ||
* available. | ||
* | ||
* TODO: add support for reading sizes other than 32bits and masking | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/kernel.h> | ||
#include <linux/platform_device.h> | ||
#include <linux/hw_random.h> | ||
#include <linux/io.h> | ||
#include <linux/timeriomem-rng.h> | ||
#include <linux/jiffies.h> | ||
#include <linux/sched.h> | ||
#include <linux/timer.h> | ||
#include <linux/completion.h> | ||
|
||
static struct timeriomem_rng_data *timeriomem_rng_data; | ||
|
||
static void timeriomem_rng_trigger(unsigned long); | ||
static DEFINE_TIMER(timeriomem_rng_timer, timeriomem_rng_trigger, 0, 0); | ||
|
||
/* | ||
* have data return 1, however return 0 if we have nothing | ||
*/ | ||
static int timeriomem_rng_data_present(struct hwrng *rng, int wait) | ||
{ | ||
if (rng->priv == 0) | ||
return 1; | ||
|
||
if (!wait || timeriomem_rng_data->present) | ||
return timeriomem_rng_data->present; | ||
|
||
wait_for_completion(&timeriomem_rng_data->completion); | ||
|
||
return 1; | ||
} | ||
|
||
static int timeriomem_rng_data_read(struct hwrng *rng, u32 *data) | ||
{ | ||
unsigned long cur; | ||
s32 delay; | ||
|
||
*data = readl(timeriomem_rng_data->address); | ||
|
||
if (rng->priv != 0) { | ||
cur = jiffies; | ||
|
||
delay = cur - timeriomem_rng_timer.expires; | ||
delay = rng->priv - (delay % rng->priv); | ||
|
||
timeriomem_rng_timer.expires = cur + delay; | ||
timeriomem_rng_data->present = 0; | ||
|
||
init_completion(&timeriomem_rng_data->completion); | ||
add_timer(&timeriomem_rng_timer); | ||
} | ||
|
||
return 4; | ||
} | ||
|
||
static void timeriomem_rng_trigger(unsigned long dummy) | ||
{ | ||
timeriomem_rng_data->present = 1; | ||
complete(&timeriomem_rng_data->completion); | ||
} | ||
|
||
static struct hwrng timeriomem_rng_ops = { | ||
.name = "timeriomem", | ||
.data_present = timeriomem_rng_data_present, | ||
.data_read = timeriomem_rng_data_read, | ||
.priv = 0, | ||
}; | ||
|
||
static int __init timeriomem_rng_probe(struct platform_device *pdev) | ||
{ | ||
int ret; | ||
|
||
timeriomem_rng_data = pdev->dev.platform_data; | ||
|
||
if (timeriomem_rng_data->period != 0 | ||
&& usecs_to_jiffies(timeriomem_rng_data->period) > 0) { | ||
timeriomem_rng_timer.expires = jiffies; | ||
|
||
timeriomem_rng_ops.priv = usecs_to_jiffies( | ||
timeriomem_rng_data->period); | ||
} | ||
timeriomem_rng_data->present = 1; | ||
|
||
ret = hwrng_register(&timeriomem_rng_ops); | ||
if (ret) { | ||
dev_err(&pdev->dev, "problem registering\n"); | ||
return ret; | ||
} | ||
|
||
dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n", | ||
timeriomem_rng_data->address, | ||
timeriomem_rng_data->period); | ||
|
||
return 0; | ||
} | ||
|
||
static int __devexit timeriomem_rng_remove(struct platform_device *pdev) | ||
{ | ||
del_timer_sync(&timeriomem_rng_timer); | ||
hwrng_unregister(&timeriomem_rng_ops); | ||
|
||
return 0; | ||
} | ||
|
||
static struct platform_driver timeriomem_rng_driver = { | ||
.driver = { | ||
.name = "timeriomem_rng", | ||
.owner = THIS_MODULE, | ||
}, | ||
.probe = timeriomem_rng_probe, | ||
.remove = __devexit_p(timeriomem_rng_remove), | ||
}; | ||
|
||
static int __init timeriomem_rng_init(void) | ||
{ | ||
return platform_driver_register(&timeriomem_rng_driver); | ||
} | ||
|
||
static void __exit timeriomem_rng_exit(void) | ||
{ | ||
platform_driver_unregister(&timeriomem_rng_driver); | ||
} | ||
|
||
module_init(timeriomem_rng_init); | ||
module_exit(timeriomem_rng_exit); | ||
|
||
MODULE_LICENSE("GPL"); | ||
MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>"); | ||
MODULE_DESCRIPTION("Timer IOMEM H/W RNG driver"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* linux/include/linux/timeriomem-rng.h | ||
* | ||
* Copyright (c) 2009 Alexander Clouter <alex@digriz.org.uk> | ||
* | ||
* 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/completion.h> | ||
|
||
struct timeriomem_rng_data { | ||
struct completion completion; | ||
unsigned int present:1; | ||
|
||
u32 __iomem *address; | ||
|
||
/* measures in usecs */ | ||
unsigned int period; | ||
}; |