[PATCH] MTD: Add support for the PM82x Boards.
Thomas Gleixner
tglx at linutronix.de
Wed Nov 23 09:00:08 EST 2005
On Wed, 2005-11-23 at 13:37 +0100, Heiko Schocher wrote:
> +
> +#if 0 /* Debugging turned off */
> +# define debugk(fmt,args...) printk(fmt ,##args)
> +#else
> +# define debugk(fmt,args...)
> +#endif
Please use pr_debug or DEBUG() with an appropriate MTD debug level.
+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;
Please use __iomem void *start_scan_addr to avoid the back and forth
casting.
> +#ifdef CONFIG_MTD_PARTITIONS
> +/* partition definition for first (and only) flash bank
> + * also ref. to "drivers/char/flash_config.c"
> + */
> +static struct mtd_partition pm82x_partitions_8M[] = {
> + {
> + name: "U-Boot", /* U-Boot image */
> + offset: 0x00000000,
> + size: 0x00040000, /* 256 KB */
> + },
> + {
> + name: "kernel", /* Linux kernel image */
> + offset: 0x00040000,
> + size: 0x000C0000, /* 768 KB */
> + },
> + {
> + name: "ramdisk", /* Ramdisk image */
> + offset: 0x00100000,
> + size: 0x00300000, /* 3 MB */
> + },
> + {
> + name: "user", /* User file system */
> + offset: 0x00400000,
> + size: 0x00400000, /* 4 MB */
> + },
> +};
Please use C99 initializers. You might also change the offset
initializers to MTDPART_OFS_APPEND, so a size change is automatically
propagated. Change the last partition size to MTDPAR_SIZ_FULL
> +static struct mtd_partition pm82x_partitions_32M[] = {
> + {
> + name: "U-Boot", /* U-Boot image */
> + offset: 0x00000000,
> + size: 0x00040000, /* 256 KB */
> + },
> + {
> + name: "kernel", /* Linux kernel image */
> + offset: 0x00040000,
> + size: 0x000C0000, /* 768 KB */
> + },
> + {
> + name: "ramdisk", /* Ramdisk image */
> + offset: 0x00100000,
> + size: 0x00300000, /* 3 MB */
> + },
> + {
> + name: "user", /* User file system */
> + offset: 0x00400000,
> + size: 0x01C00000, /* 28 MB */
> + },
> +};
Same as above
> +#endif /* CONFIG_MTD_PARTITIONS */
> +
> +#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
Please use ARRAY_SIZE(x) instead.
> +int __init init_pm82x_mtd(void)
> +{
> + int idx = 0, ret = 0;
> + unsigned long flash_addr, flash_size, mtd_size = 0;
> +
> + /* pointer to PM82x board info data */
> + bd_t *bd = (bd_t *)__res;
> +
> +#ifdef CONFIG_MTD_CMDLINE_PARTS
> + int n;
> + char mtdid[10];
> + 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("%s: Failed to ioremap address: 0x%lx\n",
> + __FUNCTION__, flash_addr);
printk level is missing
> + return -EIO;
> + }
> +
> + for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
> + if (mtd_size >= flash_size)
> + break;
> +
> + debugk ("%s: chip probing count %d\n", __FUNCTION__, idx);
> +
> + map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info),
> + GFP_KERNEL);
No type cast necessary
> + if (map_banks[idx] == NULL) {
> + ret = -ENOMEM;
> + goto error_mem;
> + }
> + memset((void *)map_banks[idx], 0, sizeof(struct map_info));
Same here
> + map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
Same here
Also please allocate map_info and name in one chunk.
map_banks[idx] = kmalloc(sizeof(struct map_info) + 16, GFP_KERNEL);
Less memory fragments and makes the clean up path simpler.
> + if (map_banks[idx]->name == NULL) {
> + ret = -ENOMEM;
> + goto error_mem;
> + }
> + memset((void *)map_banks[idx]->name, 0, 16);
> + sprintf(map_banks[idx]->name, "PM82x-%d", idx);
> + map_banks[idx]->size = flash_size;
> + map_banks[idx]->bankwidth = 8;
> + map_banks[idx]->read = pm82x_read64;
> + map_banks[idx]->copy_from = pm82x_copy_from;
> + map_banks[idx]->write = pm82x_write64;
> + map_banks[idx]->copy_to = pm82x_copy_to;
> + map_banks[idx]->map_priv_1=
> + start_scan_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("jedec_probe", map_banks[idx]);
> + if (mtd_banks[idx]) {
> + mtd_banks[idx]->owner = THIS_MODULE;
> + mtd_size += mtd_banks[idx]->size;
> + num_banks++;
> + debugk ("%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("PM82x: No supported flash chips found!\n");
printk level missing
> + ret = -ENXIO;
> + goto error_mem;
> + }
> +
> +#ifdef CONFIG_MTD_PARTITIONS
> + /*
> + * Select static partition definitions
> + */
> + if (flash_size == 0x800000) {
> + part_banks[0].mtd_part = pm82x_partitions_8M;
> + part_banks[0].nums = NB_OF(pm82x_partitions_8M);
> + } else {
> + part_banks[0].mtd_part = pm82x_partitions_32M;
> + part_banks[0].nums = NB_OF(pm82x_partitions_32M);
> + }
> + part_banks[0].type = "static image";
> +
> + for(idx = 0; idx < num_banks ; idx++) {
> +#ifdef CONFIG_MTD_CMDLINE_PARTS
> + sprintf(mtdid, "%d", idx);
Please move this into the debug print function, as mtdid is only used
for debug.
> + n = parse_mtd_partitions(mtd_banks[idx],
> + part_probes,
> + &part_banks[idx].mtd_part,
> + 0);
> + debugk ("%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
> + "PM82x flash bank %d: no partition info "
> + "available, registering whole device\n", idx);
> + add_mtd_device(mtd_banks[idx]);
> + } else {
> + printk (KERN_NOTICE
> + "PM82x 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 "PM82x flash: registering %d flash banks "
> + "at once\n", num_banks);
> +
> + for(idx = 0 ; idx < num_banks ; idx++) {
> + add_mtd_device(mtd_banks[idx]);
> + }
Please do not use braces for one liners
> +#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;
> + }
> + }
When allocated in one chunk, the cleanup is simply
for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
kfree(map_banks[idx]);
map_banks[idx] = NULL;
}
> +
> + iounmap((void *)start_scan_addr);
> + return ret;
> +}
> +
> +static void __exit cleanup_pm82x_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]);
> + }
See above
> + if (start_scan_addr) {
> + iounmap((void *)start_scan_addr);
> + start_scan_addr = 0;
> + }
> +}
> +
tglx
More information about the linux-mtd
mailing list