diff options
author | Florian Fainelli <florian@openwrt.org> | 2015-04-04 18:01:07 +0000 |
---|---|---|
committer | Florian Fainelli <florian@openwrt.org> | 2015-04-04 18:01:07 +0000 |
commit | b1ba4c50963db865b57092cd2ff9676e629aacf1 (patch) | |
tree | 605e14b700c9dacd60dc44b322fb2cc1b30b59d5 /target/linux/mcs814x/files-3.18/drivers/char | |
parent | c31df6e995c36e2b14b74f727b8392e6c1c10afc (diff) | |
download | upstream-b1ba4c50963db865b57092cd2ff9676e629aacf1.tar.gz upstream-b1ba4c50963db865b57092cd2ff9676e629aacf1.tar.bz2 upstream-b1ba4c50963db865b57092cd2ff9676e629aacf1.zip |
mcs814x: add support for 3.18
Signed-off-by: Florian Fainelli <florian@openwrt.org>
SVN-Revision: 45273
Diffstat (limited to 'target/linux/mcs814x/files-3.18/drivers/char')
-rw-r--r-- | target/linux/mcs814x/files-3.18/drivers/char/hw_random/mcs814x-rng.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/target/linux/mcs814x/files-3.18/drivers/char/hw_random/mcs814x-rng.c b/target/linux/mcs814x/files-3.18/drivers/char/hw_random/mcs814x-rng.c new file mode 100644 index 0000000000..cb3f339e3b --- /dev/null +++ b/target/linux/mcs814x/files-3.18/drivers/char/hw_random/mcs814x-rng.c @@ -0,0 +1,121 @@ +/* + * RNG driver for Moschip MCS814x SoC + * + * Copyright 2012 (C), Florian Fainelli <florian@openwrt.org> + * + * 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/kernel.h> +#include <linux/slab.h> +#include <linux/module.h> +#include <linux/types.h> +#include <linux/platform_device.h> +#include <linux/hw_random.h> +#include <linux/io.h> +#include <linux/of.h> + +#define STAT 0x00 +#define RND 0x04 + +struct mcs814x_rng_priv { + void __iomem *regs; +}; + +static int mcs814x_rng_data_read(struct hwrng *rng, u32 *buffer) +{ + struct mcs814x_rng_priv *priv = (struct mcs814x_rng_priv *)rng->priv; + + *buffer = readl_relaxed(priv->regs + RND); + + return 4; +} + +static int mcs814x_rng_probe(struct platform_device *pdev) +{ + struct resource *res; + struct mcs814x_rng_priv *priv; + struct hwrng *rng; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; + goto out; + } + + rng = kzalloc(sizeof(*rng), GFP_KERNEL); + if (!rng) { + ret = -ENOMEM; + goto out_priv; + } + + platform_set_drvdata(pdev, rng); + rng->priv = (unsigned long)priv; + rng->name = pdev->name; + rng->data_read = mcs814x_rng_data_read; + + priv->regs = devm_ioremap_resource(&pdev->dev, res); + if (!priv->regs) { + ret = -ENOMEM; + goto out_rng; + } + + ret = hwrng_register(rng); + if (ret) { + dev_err(&pdev->dev, "failed to register hwrng driver\n"); + goto out; + } + + dev_info(&pdev->dev, "registered\n"); + + return ret; + +out_rng: + platform_set_drvdata(pdev, NULL); + kfree(rng); +out_priv: + kfree(priv); +out: + return ret; +} + +static int mcs814x_rng_remove(struct platform_device *pdev) +{ + struct hwrng *rng = platform_get_drvdata(pdev); + struct mcs814x_rng_priv *priv = (struct mcs814x_rng_priv *)rng->priv; + + hwrng_unregister(rng); + kfree(priv); + kfree(rng); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static const struct of_device_id mcs814x_rng_ids[] = { + { .compatible = "moschip,mcs814x-rng", }, + { /* sentinel */ }, +}; + +static struct platform_driver mcs814x_rng_driver = { + .driver = { + .name = "mcs814x-rng", + .owner = THIS_MODULE, + .of_match_table = mcs814x_rng_ids, + }, + .probe = mcs814x_rng_probe, + .remove = mcs814x_rng_remove, +}; + +module_platform_driver(mcs814x_rng_driver); + +MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); +MODULE_DESCRIPTION("H/W Random Number Generator (RNG) for Moschip MCS814x"); +MODULE_LICENSE("GPL"); |