From: Stefan Roese <sr@denx.de>
To: linux-mtd@lists.infradead.org
Subject: [PATCH] MTD: Add TQM85xx MTD support
Date: Thu, 1 Dec 2005 14:32:31 +0100 [thread overview]
Message-ID: <200512011432.31650.sr@denx.de> (raw)
[-- Attachment #1: Type: text/plain, Size: 168 bytes --]
This patch adds MTD support (NOR FLASH) for the TQ Components
TQM85xx (TQM8540/8541/8555/8560) modules.
Signed-off-by: Stefan Roese <sr@denx.de>
Best regards,
Stefan
[-- Attachment #2: add-tqm85xx-mtd-support-3.patch --]
[-- Type: text/x-diff, Size: 10208 bytes --]
[PATCH] MTD: Add TQM85xx MTD support
This patch adds MTD support (NOR FLASH) for the TQ Components
TQM85xx (TQM8540/8541/8555/8560) modules.
Signed-off-by: Stefan Roese <sr@denx.de>
---
commit e244182c95d0ce73df079b89521f45e5f92a29fb
tree 11b6549966b9fe0a85674ba5a9ed9dcdd512459c
parent 5666c0947ede0432ba5148570aa66ffb9febff5b
author Stefan Roese <sr@denx.de> Thu, 01 Dec 2005 14:26:33 +0100
committer Stefan Roese <sr@denx.de> Thu, 01 Dec 2005 14:26:33 +0100
drivers/mtd/maps/Kconfig | 8 +
drivers/mtd/maps/Makefile | 1
drivers/mtd/maps/tqm85xx.c | 301 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 310 insertions(+), 0 deletions(-)
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 452ccd5..5e4f983 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -355,6 +355,14 @@ config MTD_TQM834x
TQ Components TQM834x boards. If you have one of these boards
and would like to use the flash chips on it, say 'Y'.
+ config MTD_TQM85xx
+ tristate "Flash device mapped on TQ Components TQM85xx Boards"
+ depends on MTD_CFI && (TQM8540 || TQM8541 || TQM8555 || TQM8560)
+ help
+ This enables access routines for the flash chips on the
+ TQ Components TQM85xx boards. If you have one of these boards
+ and would like to use the flash chips on it, say 'Y'.
+
config MTD_CSTM_MIPS_IXX
tristate "Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board"
depends on MIPS && MTD_CFI && MTD_JEDECPROBE && MTD_PARTITIONS
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 2f7e254..acd2f6d 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -72,3 +72,4 @@ obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o
obj-$(CONFIG_MTD_TQM834x) += tqm834x.o
+obj-$(CONFIG_MTD_TQM85xx) += tqm85xx.o
diff --git a/drivers/mtd/maps/tqm85xx.c b/drivers/mtd/maps/tqm85xx.c
new file mode 100644
index 0000000..39d9c58
--- /dev/null
+++ b/drivers/mtd/maps/tqm85xx.c
@@ -0,0 +1,301 @@
+/*
+ * drivers/mtd/maps/tqm85xx.c
+ *
+ * MTD mapping driver for TQM85xx boards
+ *
+ * Copyright 2005 Wolfgang Denk, DENX Software Engineering, <wd@denx.de>.
+ *
+ * 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/config.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+#include <asm/ppcboot.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#define FLASH_BANK_MAX 2
+
+extern unsigned char __res[];
+
+/* trivial struct to describe partition information */
+struct mtd_part_def
+{
+ int nums;
+ unsigned char *type;
+ struct mtd_partition* mtd_part;
+};
+
+static struct mtd_info* mtd_banks[FLASH_BANK_MAX];
+static struct map_info* map_banks[FLASH_BANK_MAX];
+static struct mtd_part_def part_banks[FLASH_BANK_MAX];
+
+static unsigned long num_banks;
+static unsigned long start_scan_addr;
+
+#ifdef CONFIG_MTD_PARTITIONS
+/*
+ * The following defines the partition layout of TQM85xx boards.
+ *
+ * See include/linux/mtd/partitions.h for definition of the
+ * mtd_partition structure.
+ *
+ * Assume minimal initial size of 4 MiB per bank, will be updated
+ * later in init_tqm85xx_mtd() routine.
+ */
+
+#define RW_PART0_OF 0
+#define RW_PART0_SZ 0x180000
+#define RW_PART1_SZ 0x280000
+/* Partition 2 will be autosized dynamically... */
+#define RW_PART3_SZ 0x40000
+#define RW_PART4_SZ 0x40000
+
+/* Partition definition for the first flash bank which is always present. */
+static struct mtd_partition tqm85xx_partitions_bank1[] = {
+ {
+ .name = "kernel",
+ .offset = RW_PART0_OF,
+ .size = RW_PART0_SZ
+ },
+ {
+ .name = "root",
+ .offset = MTDPART_OFS_APPEND,
+ .size = RW_PART1_SZ,
+ },
+ {
+ .name = "user",
+ .offset = MTDPART_OFS_APPEND,
+ /* NOTE: this partion size is re-calcated in */
+ /* init_tqm85xx_mtd() to cover actual device size. */
+ },
+ {
+ .name = "env",
+ .offset = MTDPART_OFS_APPEND,
+ .size = RW_PART3_SZ,
+ },
+ {
+ .name = "u-boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = RW_PART4_SZ,
+ }
+};
+
+/* Partition definition for the second flash bank which may be present on some
+ * TQM85xx boards.
+ */
+static struct mtd_partition tqm85xx_partitions_bank2[] = {
+ {
+ .name = "jffs2", /* jffs2 filesystem */
+ .offset = 0x00000000,
+ /* NOTE: this partion size is re-calcated in */
+ /* init_tqm85xx_mtd() to cover actual device size. */
+ },
+};
+
+#endif /* CONFIG_MTD_PARTITIONS */
+
+static int __init init_tqm85xx_mtd(void)
+{
+ int idx = 0, ret = 0;
+ unsigned long flash_addr, flash_size, mtd_size = 0;
+
+ /* pointer to TQM85xx board info data */
+ bd_t *bd = (bd_t *)__res;
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+ int n;
+ char mtdid[4];
+ const char *part_probes[] = { "cmdlinepart", NULL };
+#endif
+
+ flash_addr = bd->bi_flashstart;
+ flash_size = bd->bi_flashsize;
+
+ /* request maximum flash size address space */
+ start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size);
+ if (!start_scan_addr) {
+ printk(KERN_NOTICE "%s: Failed to ioremap address: 0x%lx\n",
+ __FUNCTION__, flash_addr);
+ return -EIO;
+ }
+
+ for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
+ if (mtd_size >= flash_size)
+ break;
+
+ pr_debug("%s: chip probing count %d\n", __FUNCTION__, idx);
+
+ map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info),
+ GFP_KERNEL);
+ if (map_banks[idx] == NULL) {
+ ret = -ENOMEM;
+ goto error_mem;
+ }
+ memset((void *)map_banks[idx], 0, sizeof(struct map_info));
+ map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
+ if (map_banks[idx]->name == NULL) {
+ ret = -ENOMEM;
+ goto error_mem;
+ }
+ memset((void *)map_banks[idx]->name, 0, 16);
+
+ sprintf(map_banks[idx]->name, "TQM85xx-%d", idx);
+ map_banks[idx]->size = flash_size;
+ map_banks[idx]->bankwidth = 4;
+
+ simple_map_init(map_banks[idx]);
+
+ map_banks[idx]->virt = (void __iomem *)
+ (start_scan_addr + ((idx > 0) ?
+ (mtd_banks[idx-1] ?
+ mtd_banks[idx-1]->size : 0) : 0));
+ map_banks[idx]->phys =
+ flash_addr + ((idx > 0) ?
+ (mtd_banks[idx-1] ?
+ mtd_banks[idx-1]->size : 0) : 0);
+
+ /* start to probe flash chips */
+ mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]);
+ if (mtd_banks[idx]) {
+ mtd_banks[idx]->owner = THIS_MODULE;
+ mtd_size += mtd_banks[idx]->size;
+ num_banks++;
+ pr_debug("%s: bank %ld, name: %s, size: %d bytes \n",
+ __FUNCTION__, num_banks,
+ mtd_banks[idx]->name, mtd_banks[idx]->size);
+ }
+ }
+
+ /* no supported flash chips found */
+ if (!num_banks) {
+ printk(KERN_NOTICE "TQM85xx: No supported flash chips found!\n");
+ ret = -ENXIO;
+ goto error_mem;
+ }
+
+#ifdef CONFIG_MTD_PARTITIONS
+ /*
+ * Select static partition definitions
+ */
+ n = ARRAY_SIZE(tqm85xx_partitions_bank1);
+ part_banks[0].mtd_part = tqm85xx_partitions_bank1;
+ part_banks[0].type = "static image bank1";
+ part_banks[0].nums = n;
+
+ /* check if we have second bank? */
+ if (num_banks == 2) {
+ n = ARRAY_SIZE(tqm85xx_partitions_bank2);
+ part_banks[1].mtd_part = tqm85xx_partitions_bank2;
+ part_banks[1].type = "static image bank2";
+ part_banks[1].nums = n;
+
+ /* update last partition size to cover actual remaining space */
+ tqm85xx_partitions_bank2[n - 1].size =
+ mtd_banks[1]->size -
+ tqm85xx_partitions_bank2[n - 1].offset;
+
+ /*
+ * If 2 banks are available, both are the same size.
+ * -> Size of bank 1 is flash_size / 2.
+ */
+ flash_size = flash_size >> 1;
+ }
+
+ /*
+ * Adjust partitions to flash size
+ */
+ tqm85xx_partitions_bank1[2].size = flash_size -
+ RW_PART0_SZ - RW_PART1_SZ - RW_PART3_SZ - RW_PART4_SZ;
+
+ for(idx = 0; idx < num_banks ; idx++) {
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+ sprintf(mtdid, "%d", idx);
+ n = parse_mtd_partitions(mtd_banks[idx],
+ part_probes,
+ &part_banks[idx].mtd_part,
+ 0);
+ pr_debug("%s: %d command line partitions on bank %s\n",
+ __FUNCTION__, n, mtdid);
+ if (n > 0) {
+ part_banks[idx].type = "command line";
+ part_banks[idx].nums = n;
+ }
+#endif /* CONFIG_MTD_CMDLINE_PARTS */
+ if (part_banks[idx].nums == 0) {
+ printk(KERN_NOTICE
+ "TQM85xx flash bank %d: no partition info "
+ "available, registering whole device\n", idx);
+ add_mtd_device(mtd_banks[idx]);
+ } else {
+ printk(KERN_NOTICE
+ "TQM85xx flash bank %d: Using %s partition "
+ "definition\n", idx, part_banks[idx].type);
+ add_mtd_partitions(mtd_banks[idx],
+ part_banks[idx].mtd_part,
+ part_banks[idx].nums);
+ }
+ }
+#else /* ! CONFIG_MTD_PARTITIONS */
+ printk(KERN_NOTICE "TQM85xx flash: registering %d flash banks "
+ "at once\n", num_banks);
+
+ for(idx = 0 ; idx < num_banks ; idx++)
+ add_mtd_device(mtd_banks[idx]);
+
+#endif /* CONFIG_MTD_PARTITIONS */
+
+ return 0;
+error_mem:
+ for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
+ if (map_banks[idx] != NULL) {
+ if (map_banks[idx]->name != NULL) {
+ kfree(map_banks[idx]->name);
+ map_banks[idx]->name = NULL;
+ }
+ kfree(map_banks[idx]);
+ map_banks[idx] = NULL;
+ }
+ }
+
+ iounmap((void *)start_scan_addr);
+
+ return ret;
+}
+
+static void __exit cleanup_tqm85xx_mtd(void)
+{
+ unsigned int idx = 0;
+ for(idx = 0 ; idx < num_banks ; idx++) {
+ /* destroy mtd_info previously allocated */
+ if (mtd_banks[idx]) {
+ del_mtd_partitions(mtd_banks[idx]);
+ map_destroy(mtd_banks[idx]);
+ }
+
+ /* release map_info not used anymore */
+ kfree(map_banks[idx]->name);
+ kfree(map_banks[idx]);
+ }
+
+ if (start_scan_addr) {
+ iounmap((void *)start_scan_addr);
+ start_scan_addr = 0;
+ }
+}
+
+module_init(init_tqm85xx_mtd);
+module_exit(cleanup_tqm85xx_mtd);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Wolfgang Denk <wd@denx.de>");
+MODULE_DESCRIPTION("MTD map driver for TQM85xx boards");
\f
!-------------------------------------------------------------flip-
reply other threads:[~2005-12-01 13:32 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200512011432.31650.sr@denx.de \
--to=sr@denx.de \
--cc=linux-mtd@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.