123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- /* arch/arm/mach-msm/nand_partitions.c
- *
- * Code to extract partition information from ATAG set up by the
- * bootloader.
- *
- * Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2009,2011,2013 The Linux Foundation. All rights reserved.
- * Author: Brian Swetland <swetland@google.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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.
- *
- */
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/platform_device.h>
- #include <asm/mach/flash.h>
- #include <linux/io.h>
- #include <asm/setup.h>
- #include <linux/mtd/nand.h>
- #include <linux/mtd/partitions.h>
- #include <mach/msm_iomap.h>
- #include <mach/board.h>
- #ifdef CONFIG_MSM_SMD
- #include <mach/msm_smem.h>
- #endif
- /* configuration tags specific to msm */
- #define ATAG_MSM_PARTITION 0x4d534D70 /* MSMp */
- struct msm_ptbl_entry {
- char name[16];
- __u32 offset;
- __u32 size;
- __u32 flags;
- };
- #define MSM_MAX_PARTITIONS 18
- static struct mtd_partition msm_nand_partitions[MSM_MAX_PARTITIONS];
- static char msm_nand_names[MSM_MAX_PARTITIONS * 16];
- extern struct flash_platform_data msm_nand_data;
- static int __init parse_tag_msm_partition(const struct tag *tag)
- {
- struct mtd_partition *ptn = msm_nand_partitions;
- char *name = msm_nand_names;
- struct msm_ptbl_entry *entry = (void *) &tag->u;
- unsigned count, n;
- count = (tag->hdr.size - 2) /
- (sizeof(struct msm_ptbl_entry) / sizeof(__u32));
- if (count > MSM_MAX_PARTITIONS)
- count = MSM_MAX_PARTITIONS;
- for (n = 0; n < count; n++) {
- memcpy(name, entry->name, 15);
- name[15] = 0;
- ptn->name = name;
- ptn->offset = entry->offset;
- ptn->size = entry->size;
- printk(KERN_INFO "Partition (from atag) %s "
- "-- Offset:%llx Size:%llx\n",
- ptn->name, ptn->offset, ptn->size);
- name += 16;
- entry++;
- ptn++;
- }
- msm_nand_data.nr_parts = count;
- msm_nand_data.parts = msm_nand_partitions;
- return 0;
- }
- __tagtable(ATAG_MSM_PARTITION, parse_tag_msm_partition);
- #define FLASH_PART_MAGIC1 0x55EE73AA
- #define FLASH_PART_MAGIC2 0xE35EBDDB
- #define FLASH_PARTITION_VERSION 0x3
- #define LINUX_FS_PARTITION_NAME "0:EFS2APPS"
- struct flash_partition_entry {
- char name[16];
- u32 offset; /* Offset in blocks from beginning of device */
- u32 length; /* Length of the partition in blocks */
- u8 attrib1;
- u8 attrib2;
- u8 attrib3;
- u8 which_flash; /* Numeric ID (first = 0, second = 1) */
- };
- struct flash_partition_table {
- u32 magic1;
- u32 magic2;
- u32 version;
- u32 numparts;
- struct flash_partition_entry part_entry[16];
- };
- #ifdef CONFIG_MSM_SMD
- static int get_nand_partitions(void)
- {
- struct flash_partition_table *partition_table;
- struct flash_partition_entry *part_entry;
- struct mtd_partition *ptn = msm_nand_partitions;
- char *name = msm_nand_names;
- int part;
- if (msm_nand_data.nr_parts)
- return 0;
- partition_table = (struct flash_partition_table *)
- smem_alloc(SMEM_AARM_PARTITION_TABLE,
- sizeof(struct flash_partition_table));
- if (!partition_table) {
- printk(KERN_WARNING "%s: no flash partition table in shared "
- "memory\n", __func__);
- return -ENOENT;
- }
- if ((partition_table->magic1 != (u32) FLASH_PART_MAGIC1) ||
- (partition_table->magic2 != (u32) FLASH_PART_MAGIC2) ||
- (partition_table->version != (u32) FLASH_PARTITION_VERSION)) {
- printk(KERN_WARNING "%s: version mismatch -- magic1=%#x, "
- "magic2=%#x, version=%#x\n", __func__,
- partition_table->magic1,
- partition_table->magic2,
- partition_table->version);
- return -EFAULT;
- }
- msm_nand_data.nr_parts = 0;
- /* Get the LINUX FS partition info */
- for (part = 0; part < partition_table->numparts; part++) {
- part_entry = &partition_table->part_entry[part];
- /* Find a match for the Linux file system partition */
- if (strcmp(part_entry->name, LINUX_FS_PARTITION_NAME) == 0) {
- strcpy(name, part_entry->name);
- ptn->name = name;
- /*TODO: Get block count and size info */
- ptn->offset = part_entry->offset;
- /* For SMEM, -1 indicates remaining space in flash,
- * but for MTD it is 0
- */
- if (part_entry->length == (u32)-1)
- ptn->size = 0;
- else
- ptn->size = part_entry->length;
- msm_nand_data.nr_parts = 1;
- msm_nand_data.parts = msm_nand_partitions;
- printk(KERN_INFO "Partition(from smem) %s "
- "-- Offset:%llx Size:%llx\n",
- ptn->name, ptn->offset, ptn->size);
- return 0;
- }
- }
- printk(KERN_WARNING "%s: no partition table found!", __func__);
- return -ENODEV;
- }
- #else
- static int get_nand_partitions(void)
- {
- if (msm_nand_data.nr_parts)
- return 0;
- printk(KERN_WARNING "%s: no partition table found!", __func__);
- return -ENODEV;
- }
- #endif
- device_initcall(get_nand_partitions);
|