summaryrefslogtreecommitdiffstats
path: root/target/linux/mcs814x/files-3.3/drivers/char
diff options
context:
space:
mode:
authorFlorian Fainelli <florian@openwrt.org>2012-06-19 14:48:56 +0000
committerFlorian Fainelli <florian@openwrt.org>2012-06-19 14:48:56 +0000
commitf4afa00862b7db8a2da8c012843a286716c0a534 (patch)
tree9c15efab8fd398654de98648e07f26c51d6eec66 /target/linux/mcs814x/files-3.3/drivers/char
parent7c87391c55a713a9ef9df169ab23e79177184b1a (diff)
downloadmaster-31e0f0ae-f4afa00862b7db8a2da8c012843a286716c0a534.tar.gz
master-31e0f0ae-f4afa00862b7db8a2da8c012843a286716c0a534.tar.bz2
master-31e0f0ae-f4afa00862b7db8a2da8c012843a286716c0a534.zip
add Moschip MSC814x support
This target currently only supports Moschip's MCS8140 SoC, but support for other chips in the same family (MCS8142, MCS8144) will be easy to add. Target support is entirely using Device Tree for probing peripherals. Drivers support include: - PCI - USB 1 & 2 - watchdog - random number generator - UART - timer - internal Ethernet PHY - Ethernet MAC core Support for the following boards is included using Device Tree - Devolo dLAN USB Extender - Tigal RBT-832 SVN-Revision: 32462
Diffstat (limited to 'target/linux/mcs814x/files-3.3/drivers/char')
-rw-r--r--target/linux/mcs814x/files-3.3/drivers/char/hw_random/mcs814x-rng.c128
1 files changed, 128 insertions, 0 deletions
diff --git a/target/linux/mcs814x/files-3.3/drivers/char/hw_random/mcs814x-rng.c b/target/linux/mcs814x/files-3.3/drivers/char/hw_random/mcs814x-rng.c
new file mode 100644
index 0000000000..cccab07b27
--- /dev/null
+++ b/target/linux/mcs814x/files-3.3/drivers/char/hw_random/mcs814x-rng.c
@@ -0,0 +1,128 @@
+/*
+ * 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 = __raw_readl(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;
+
+ if (!devm_request_mem_region(&pdev->dev,
+ res->start, resource_size(res),
+ pdev->name)) {
+ ret = -EBUSY;
+ goto out_rng;
+ }
+
+ priv->regs = devm_ioremap(&pdev->dev, res->start, resource_size(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 = __devexit_p(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");