Index: powerpc/Documentation/powerpc/booting-without-of.txt =================================================================== --- powerpc.orig/Documentation/powerpc/booting-without-of.txt +++ powerpc/Documentation/powerpc/booting-without-of.txt @@ -6,6 +6,8 @@ IBM Corp. (c) 2005 Becky Bruce , Freescale Semiconductor, FSL SOC and 32-bit additions +(c) 2006 MontaVista Software, Inc. + MTD node definition May 18, 2005: Rev 0.1 - Initial draft, no chapter III yet. @@ -1442,6 +1444,42 @@ platforms are moved over to use the flat }; + h) MTD nodes + + Memory Technology Devices are flash, ROM, and similar chips, often used + for solid state file systems on embedded devices. + + Required properties: + + - device_type : has to be "mtd" + - compatible : Should be the name of the MTD driver. Currently, this is + most likely to be "physmap". + - reg : Offset and length of the register set for the device. + + Recommended properties : + + - bank-width : Width of the flash data bus in bytes. Must be specified + for the NOR flashes. + - partitions : Several pairs of 32-bit values where the first value is + partition's offset from the start of the MTD device and the second + one is partition size in bytes with LSB used to signify a read only + partititon (so, the parition size should always be an even number). + - partition-names : The list of concatenated zero terminated strings + representing the partition names. + + Example: + + flash@ff000000 { + device_type = "mtd"; + compatible = "physmap"; + reg = ; + bank-width = <4>; + partitions = <00000000 00f80000 + 00f80000 00080001>; + partition-names = "fs\0firmware"; + }; + + More devices will be defined as this spec matures. Index: powerpc/arch/powerpc/sysdev/Makefile =================================================================== --- powerpc.orig/arch/powerpc/sysdev/Makefile +++ powerpc/arch/powerpc/sysdev/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_PPC_83xx) += ipic.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o obj-$(CONFIG_PPC_TODC) += todc.o obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o +obj-$(CONFIG_MTD) += flash.o ifeq ($(CONFIG_PPC_MERGE),y) obj-$(CONFIG_PPC_I8259) += i8259.o Index: powerpc/arch/powerpc/sysdev/flash.c =================================================================== --- /dev/null +++ powerpc/arch/powerpc/sysdev/flash.c @@ -0,0 +1,104 @@ +/* + * arch/powerpc/sysdev/flash.c + * + * Flash memory registration + * + * (C) 2006 MontaVista Software, Inc. 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 +#include +#include +#include +#include + +static void parse_flash_partitions(struct device_node *node, + struct physmap_flash_data *physmap_data) +{ +#ifdef CONFIG_MTD_PARTITIONS + int i, plen, num_parts; + const u32 *part; + const char *name; + + part = get_property(node, "partitions", &plen); + if (part == NULL) + return; + + physmap_data->nr_parts = num_parts = plen / (2 * sizeof(u32)); + physmap_data->parts = kcalloc(num_parts, sizeof(struct mtd_partition), + GFP_KERNEL); + if (physmap_data->parts == NULL) { + printk(KERN_ERR "Can't allocate the flash partition data!\n"); + return; + } + + name = get_property(node, "partition-names", &plen); + + for (i = 0; i < num_parts; i++) { + physmap_data->parts[i].offset = *part++; + physmap_data->parts[i].size = *part & ~1; + if (*part++ & 1) /* bit 0 set signifies read only partition */ + physmap_data->parts[i].mask_flags = MTD_WRITEABLE; + + if (name != NULL && plen > 0) { + int len = strlen(name) + 1; + + physmap_data->parts[i].name = (char *)name; + plen -= len; + name += len; + } else + physmap_data->parts[i].name = "unnamed"; + } +#endif +} + +static int __init powerpc_flash_init(void) +{ + struct device_node *node = NULL; + int num = 0; + + while ((node = of_find_compatible_node(node, "mtd", "physmap")) != NULL) { + struct platform_device *physmap_flash; + struct physmap_flash_data physmap_data; + struct resource res; + const u32 *width; + + if (of_address_to_resource(node, 0, &res)) { + printk(KERN_ERR "Can't get the flash mapping!\n"); + continue; + } + + width = get_property(node, "bank-width", NULL); + if (width == NULL) { + printk(KERN_ERR "Can't get the flash bank width!\n"); + continue; + } + + physmap_flash = platform_device_register_simple("physmap-flash", + num, &res, 1); + if (IS_ERR(physmap_flash)) { + printk(KERN_ERR "Can't register the \"physmap-flash\" " + "platform device!\n"); + continue; + } + + memset(&physmap_data, 0, sizeof(physmap_data)); + physmap_data.width = *width; + + parse_flash_partitions(node, &physmap_data); + + if (platform_device_add_data(physmap_flash, &physmap_data, + sizeof(struct physmap_flash_data))) { + printk(KERN_ERR "Can't pass data to physmap driver!\n"); + platform_device_unregister(physmap_flash); + continue; + } + ++num; + } + return 0; +} + +arch_initcall(powerpc_flash_init);