148 lines
3.4 KiB
C
148 lines
3.4 KiB
C
/* 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 <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 <asm/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>
|
|
|
|
|
|
/* 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);
|