summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdoob.c
diff options
context:
space:
mode:
authorRobert Jarzmik <robert.jarzmik@free.fr>2011-12-21 22:30:43 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2011-12-22 10:11:11 +0100
commit6473b28065ba07100ea4409fd72b79d1d2db679b (patch)
tree82df5d27ce4b76f1f479891b21faa878b87aaeda /drivers/mtd/mtdoob.c
parentc6c880ecdb7b036a915bfe3d7a64bc83b978d7e0 (diff)
downloadbarebox-6473b28065ba07100ea4409fd72b79d1d2db679b.tar.gz
barebox-6473b28065ba07100ea4409fd72b79d1d2db679b.tar.xz
drivers/mtd: split mtd mtdoob devices
Split /dev/mtd and /dev/mtdoob devices. Remove from mtd structure the mtdoob character device. Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mtd/mtdoob.c')
-rw-r--r--drivers/mtd/mtdoob.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/drivers/mtd/mtdoob.c b/drivers/mtd/mtdoob.c
new file mode 100644
index 0000000000..be656a4d33
--- /dev/null
+++ b/drivers/mtd/mtdoob.c
@@ -0,0 +1,97 @@
+/*
+ * MTD oob device
+ *
+ * Copyright (C) 2011 Sascha Hauer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Adds a character devices :
+ * - mtdoob<N>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <malloc.h>
+#include <ioctl.h>
+#include <errno.h>
+#include <linux/mtd/mtd.h>
+
+#include "mtd.h"
+
+struct mtdoob {
+ struct cdev cdev;
+ struct mtd_info *mtd;
+};
+
+static struct mtd_info *to_mtd(struct cdev *cdev)
+{
+ struct mtdoob *mtdoob = cdev->priv;
+ return mtdoob->mtd;
+}
+
+static ssize_t mtd_read_oob(struct cdev *cdev, void *buf, size_t count,
+ ulong offset, ulong flags)
+{
+ struct mtd_info *mtd = to_mtd(cdev);
+ struct mtd_oob_ops ops;
+ int ret;
+
+ if (count < mtd->oobsize)
+ return -EINVAL;
+
+ ops.mode = MTD_OOB_RAW;
+ ops.ooboffs = 0;
+ ops.ooblen = mtd->oobsize;
+ ops.oobbuf = buf;
+ ops.datbuf = NULL;
+ ops.len = mtd->oobsize;
+
+ offset /= mtd->oobsize;
+ ret = mtd->read_oob(mtd, offset * mtd->writesize, &ops);
+ if (ret)
+ return ret;
+
+ return mtd->oobsize;
+}
+
+static struct file_operations mtd_ops_oob = {
+ .read = mtd_read_oob,
+ .ioctl = mtd_ioctl,
+ .lseek = dev_lseek_default,
+};
+
+static int add_mtdoob_device(struct mtd_info *mtd, char *devname)
+{
+ struct mtdoob *mtdoob;
+
+ mtdoob = xzalloc(sizeof(*mtdoob));
+ mtdoob->cdev.ops = &mtd_ops_oob;
+ mtdoob->cdev.size = (mtd->size / mtd->writesize) * mtd->oobsize;
+ mtdoob->cdev.name = asprintf("%s_oob%d", devname, mtd->class_dev.id);
+ mtdoob->cdev.priv = mtdoob;
+ mtdoob->cdev.dev = &mtd->class_dev;
+ mtdoob->mtd = mtd;
+ devfs_create(&mtdoob->cdev);
+
+ return 0;
+}
+
+static struct mtddev_hook mtdoob_hook = {
+ .add_mtd_device = add_mtdoob_device,
+};
+
+static int __init register_mtdoob(void)
+{
+ mtdcore_add_hook(&mtdoob_hook);
+ return 0;
+}
+
+coredevice_initcall(register_mtdoob);