/* arch/arm/mach-msm/nand_partitions.c * * Code to extract partition information from ATAG set up by the * bootloader. * * Copyright (C) 2007 Google, Inc. * Author: Brian Swetland * * 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 #include #include #include #include #include #include #include #include #include /* 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 11 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; int emmc_partition_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { struct mtd_partition *ptn = msm_nand_partitions; char *p = page; int i; uint64_t offset; uint64_t size; p += sprintf(p, "dev: size erasesize name\n"); for (i = 0; i < MSM_MAX_PARTITIONS && ptn->name; i++, ptn++) { offset = ptn->offset; size = ptn->size; p += sprintf(p, "mmcblk0p%llu: %08llx %08x \"%s\"\n", offset, size * 512, 512, ptn->name); } return p - page; } 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; unsigned have_kpanic = 0; 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; if (!strcmp(name, "kpanic")) have_kpanic = 1; ptn->name = name; ptn->offset = entry->offset; ptn->size = entry->size; name += 16; entry++; ptn++; } #ifdef CONFIG_VIRTUAL_KPANIC_PARTITION if (!have_kpanic) { int i; uint64_t kpanic_off = 0; if (count == MSM_MAX_PARTITIONS) { printk("Cannot create virtual 'kpanic' partition\n"); goto out; } for (i = 0; i < count; i++) { ptn = &msm_nand_partitions[i]; if (!strcmp(ptn->name, CONFIG_VIRTUAL_KPANIC_SRC)) { ptn->size -= CONFIG_VIRTUAL_KPANIC_PSIZE; kpanic_off = ptn->offset + ptn->size; break; } } if (i == count) { printk(KERN_ERR "Partition %s not found\n", CONFIG_VIRTUAL_KPANIC_SRC); goto out; } ptn = &msm_nand_partitions[count]; ptn->name ="kpanic"; ptn->offset = kpanic_off; ptn->size = CONFIG_VIRTUAL_KPANIC_PSIZE; printk("Virtual mtd partition '%s' created @%llx (%llu)\n", ptn->name, ptn->offset, ptn->size); count++; } out: #endif /* CONFIG_VIRTUAL_KPANIC_SRC */ msm_nand_data.nr_parts = count; msm_nand_data.parts = msm_nand_partitions; return 0; } __tagtable(ATAG_MSM_PARTITION, parse_tag_msm_partition);