block: partitions: add rockchip partition support

This commit is contained in:
lintao
2014-07-30 11:16:42 +08:00
parent 3091bb6494
commit 7fc89efff7
8 changed files with 134 additions and 120 deletions

View File

@@ -32,6 +32,7 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_RK_PARTITION=y
CONFIG_BLOCK_RKNAND=y
CONFIG_ARM_ERRATA_720789=y
CONFIG_PL310_ERRATA_753970=y

View File

@@ -34,6 +34,7 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_ROCKCHIP=y
CONFIG_RK_PARTITION=y
CONFIG_RK_USB_UART=y
CONFIG_BLOCK_RKNAND=y
CONFIG_ARM_ERRATA_720789=y

View File

@@ -249,3 +249,14 @@ config SYSV68_PARTITION
partition table format used by Motorola Delta machines (using
sysv68).
Otherwise, say N.
config RK_PARTITION
bool "Rockchip partition table support" if PARTITION_ADVANCED
default y if ARCH_ROCKCHIP
---help---
Like most systems, Rockchip use its own hard disk partition table
format,incompatible with all others. Say Y here if you would like
to be able to read the hard diskpartition table format used by Rockchip
Soc inside machines with eMMC as main storage disk. Otherwise, as well
as you don't know what all this about, say N.

View File

@@ -18,6 +18,4 @@ obj-$(CONFIG_IBM_PARTITION) += ibm.o
obj-$(CONFIG_EFI_PARTITION) += efi.o
obj-$(CONFIG_KARMA_PARTITION) += karma.o
obj-$(CONFIG_SYSV68_PARTITION) += sysv68.o
#added for emmc in Rockchip project.
obj-$(CONFIG_MMC_DW_ROCKCHIP) += mtdpart.o
obj-$(CONFIG_RK_PARTITION) += rk.o

View File

@@ -19,8 +19,6 @@
#include <linux/genhd.h>
#include "check.h"
#include "mtdpart.h"
#include "acorn.h"
#include "amiga.h"
#include "atari.h"
@@ -35,6 +33,7 @@
#include "efi.h"
#include "karma.h"
#include "sysv68.h"
#include "rk.h"
int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
@@ -105,9 +104,8 @@ static int (*check_part[])(struct parsed_partitions *) = {
#ifdef CONFIG_SYSV68_PARTITION
sysv68_partition,
#endif
#if CONFIG_MMC_DW_ROCKCHIP
mtdpart_partition,
#ifdef CONFIG_RK_PARTITION
rkpart_partition,
#endif
NULL
@@ -163,10 +161,12 @@ check_partition(struct gendisk *hd, struct block_device *bdev)
sprintf(state->name, "p");
i = res = err = 0;
//if the disk is eMMC,then skip directly the check_part to mtdpart_partition; added by xbw, at 2014-03-24
if((179 == MAJOR(bdev->bd_dev)&& (1 == hd->emmc_disk)))
i=sizeof(check_part)/sizeof(struct parsed_partitions *)-2;
/* Rockchip partition table ONLY used by eMMC disk */
#ifdef CONFIG_RK_PARTITION
if ((179 == MAJOR(bdev->bd_dev) && (1 == hd->emmc_disk)))
i = sizeof(check_part) / sizeof(struct parsed_partitions *) - 2;
#endif
while (!res && check_part[i]) {
memset(state->parts, 0, state->limit * sizeof(state->parts[0]));

View File

@@ -1,5 +0,0 @@
/*
* fs/partitions/mtdpart.h
*/
int mtdpart_partition(struct parsed_partitions *state);

View File

@@ -1,62 +1,31 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/bootmem.h>
#include "check.h"
#include "mtdpart.h"
/* error message prefix */
#define ERRP "mtd: "
/* debug macro */
#if 0
#define dbg(x) do { printk("DEBUG-CMDLINE-PART: "); printk x; } while(0)
#else
#define dbg(x)
#endif
#define SECTOR_1G 0x200000 // 0x200000 * 512 = 1G
#define FROM_OFFSET 0x2000 // 4MB
/* special size referring to all the remaining space in a partition */
#define SIZE_REMAINING UINT_MAX
#define OFFSET_CONTINUOUS UINT_MAX
struct mtd_partition{
char *name;
sector_t from;
sector_t size;
};
struct cmdline_mtd_partition {
struct cmdline_mtd_partition *next;
char *mtd_id;
int num_parts;
struct mtd_partition *parts;
};
/* mtdpart_setup() parses into here */
static struct cmdline_mtd_partition *partitions;
#include "rk.h"
/* rkpart_setup() parses into here */
static struct cmdline_rk_partition *partitions;
/* the command line passed to mtdpart_setupd() */
static char *cmdline;
static int cmdline_parsed = 0;
static int cmdline_parsed;
/*
* Parse one partition definition for an MTD. Since there can be many
* Parse one partition definition for an rkpart. Since there can be many
* comma separated partition definitions, this function calls itself
* recursively until no more partition definitions are found. Nice side
* effect: the memory to keep the mtd_partition structs and the names
* effect: the memory to keep the rk_partition structs and the names
* is allocated upon the last definition being found. At that point the
* syntax has been verified ok.
*/
static struct mtd_partition * newpart(char *s,
char **retptr,
int *num_parts,
int this_part,
unsigned char **extra_mem_ptr,
int extra_mem_size)
static struct rk_partition *newpart(char *s,
char **retptr,
int *num_parts,
int this_part,
unsigned char **extra_mem_ptr,
int extra_mem_size)
{
struct mtd_partition *parts;
struct rk_partition *parts;
sector_t size;
sector_t from = OFFSET_CONTINUOUS;
char *name;
@@ -73,7 +42,8 @@ static struct mtd_partition * newpart(char *s,
else
{
size = memparse(s, &s);
if (size < (PAGE_SIZE)>>9)
/* No sense support partition less than 8B */
if (size < ((PAGE_SIZE) >> 9))
{
printk(KERN_ERR ERRP "partition size too small (%llx)\n", size);
return NULL;
@@ -136,7 +106,7 @@ static struct mtd_partition * newpart(char *s,
int alloc_size;
*num_parts = this_part + 1;
alloc_size = *num_parts * sizeof(struct mtd_partition) +
alloc_size = *num_parts * sizeof(struct rk_partition) +
extra_mem_size;
parts = kzalloc(alloc_size, GFP_KERNEL);
if (!parts)
@@ -180,28 +150,28 @@ static struct mtd_partition * newpart(char *s,
/*
* Parse the command line.
*/
static int mtdpart_setup_real(char *s)
static int rkpart_setup_real(char *s)
{
cmdline_parsed = 1;
for( ; s != NULL; )
{
struct cmdline_mtd_partition *this_mtd;
struct mtd_partition *parts;
int mtd_id_len;
struct cmdline_rk_partition *this_rk;
struct rk_partition *parts;
int rk_id_len;
int num_parts;
char *p, *mtd_id;
char *p, *rk_id;
mtd_id = s;
/* fetch <mtd-id> */
rk_id = s;
/* fetch <rk-id> */
if (!(p = strchr(s, ':')))
{
dbg(( "no mtd-id\n"));
dbg(( "no rk-id\n"));
return 0;
}
mtd_id_len = p - mtd_id;
rk_id_len = p - rk_id;
dbg(("parsing <%s>\n", p+1));
dbg(("parsing <%s>\n", p + 1));
/*
* parse one mtd. have it reserve memory for the
@@ -211,8 +181,8 @@ static int mtdpart_setup_real(char *s)
&s, /* out: updated cmdline ptr */
&num_parts, /* out: number of parts */
0, /* first partition */
(unsigned char**)&this_mtd, /* out: extra mem */
mtd_id_len + 1 + sizeof(*this_mtd) +
(unsigned char**)&this_rk, /* out: extra mem */
rk_id_len + 1 + sizeof(*this_rk) +
sizeof(void*)-1 /*alignment*/);
if(!parts)
{
@@ -226,33 +196,25 @@ static int mtdpart_setup_real(char *s)
return 0;
}
/* align this_mtd */
this_mtd = (struct cmdline_mtd_partition *)
ALIGN((unsigned long)this_mtd, sizeof(void*));
/* align this_rk */
this_rk = (struct cmdline_rk_partition *)
ALIGN((unsigned long)this_rk, sizeof(void*));
/* enter results */
this_mtd->parts = parts;
this_mtd->num_parts = num_parts;
this_mtd->mtd_id = (char*)(this_mtd + 1);
strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1);
this_rk->parts = parts;
this_rk->num_parts = num_parts;
this_rk->rk_id = (char*)(this_rk + 1);
strlcpy(this_rk->rk_id, rk_id, rk_id_len + 1);
/* link into chain */
this_mtd->next = partitions;
partitions = this_mtd;
this_rk->next = partitions;
partitions = this_rk;
dbg(("mtdid=<%s> num_parts=<%d>\n",
this_mtd->mtd_id, this_mtd->num_parts));
dbg(("rkid=<%s> num_parts=<%d>\n",
this_rk->mtd_id, this_rk->num_parts));
/* EOS - we're done */
if (*s == 0)
break;
#if 0
/* does another spec follow? */
if (*s != ';')
{
printk(KERN_ERR ERRP "bad character after partition (%c)\n", *s);
return 0;
}
#endif
s++;
}
return 1;
@@ -266,21 +228,22 @@ static int mtdpart_setup_real(char *s)
* the first one in the chain if a NULL mtd_id is passed in.
*/
static int parse_cmdline_partitions(sector_t n,
struct mtd_partition **pparts,
struct rk_partition **pparts,
unsigned long origin)
{
unsigned long from;
int i;
struct cmdline_mtd_partition *part;
const char *mtd_id = "rk29xxnand";
struct cmdline_rk_partition *part;
/* Fixme: parameter should be coherence with part table id */
const char *rk_id = "rk29xxnand";
/* parse command line */
if (!cmdline_parsed)
mtdpart_setup_real(cmdline);
rkpart_setup_real(cmdline);
for(part = partitions; part; part = part->next)
{
if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id)))
if ((!rk_id) || (!strcmp(part->rk_id, rk_id)))
{
for(i = 0, from = 0; i < part->num_parts; i++)
{
@@ -294,7 +257,7 @@ static int parse_cmdline_partitions(sector_t n,
{
printk(KERN_WARNING ERRP
"%s: partitioning exceeds flash size, truncating\n",
part->mtd_id);
part->rk_id);
part->parts[i].size = n - from;
part->num_parts = i;
}
@@ -311,53 +274,58 @@ static int parse_cmdline_partitions(sector_t n,
return 0;
}
static void rk_emmc_fix(void)
static void rkpart_bootmode_fixup(void)
{
const char mode_emmc[] = " androidboot.mode=emmc";
const char charger_emmc[] = " androidboot.charger.emmc=1";
const char mode[] = " androidboot.mode=emmc";
const char charger[] = " androidboot.charger.emmc=1";
char *new_command_line;
size_t saved_command_line_len = strlen(saved_command_line);
if (strstr(saved_command_line, "androidboot.mode=charger")) {
new_command_line = kzalloc(saved_command_line_len + strlen(charger_emmc) + 1, GFP_KERNEL);
sprintf(new_command_line, "%s%s", saved_command_line, charger_emmc);
new_command_line = kzalloc(saved_command_line_len + strlen(charger) + 1, GFP_KERNEL);
sprintf(new_command_line, "%s%s", saved_command_line, charger);
} else {
new_command_line = kzalloc(saved_command_line_len + strlen(mode_emmc) + 1, GFP_KERNEL);
sprintf(new_command_line, "%s%s", saved_command_line, mode_emmc);
new_command_line = kzalloc(saved_command_line_len + strlen(mode) + 1, GFP_KERNEL);
sprintf(new_command_line, "%s%s", saved_command_line, mode);
}
saved_command_line = new_command_line;
}
int mtdpart_partition(struct parsed_partitions *state)
int rkpart_partition(struct parsed_partitions *state)
{
int num_parts = 0, i;
sector_t n = get_capacity(state->bdev->bd_disk);
struct mtd_partition *parts = NULL;
struct rk_partition *parts = NULL;
if(n < SECTOR_1G)
if (n < SECTOR_1G)
return 0;
//only used to eMMC-disk
if(1 != state->bdev->bd_disk->emmc_disk)
return 0;
/* ONLY be used by eMMC-disk */
if (1 != state->bdev->bd_disk->emmc_disk)
return 0;
/* Fixme: parameter should be coherence with part table */
cmdline = strstr(saved_command_line, "mtdparts=") + 9;
cmdline_parsed = 0;
num_parts = parse_cmdline_partitions(n, &parts, 0);
if(num_parts < 0)
if (num_parts < 0)
return num_parts;
for(i = 0; i < num_parts; i++){
put_partition(state, i+1, parts[i].from + FROM_OFFSET, parts[i].size);
for (i = 0; i < num_parts; i++) {
put_partition( state,
i+1,
parts[i].from + FROM_OFFSET,
parts[i].size);
strcpy(state->parts[i+1].info.volname, parts[i].name);
printk(KERN_INFO "%10s: 0x%09llx -- 0x%09llx (%llu MB)\n",
printk(KERN_INFO "%10s: 0x%09llx -- 0x%09llx (%llu MB)\n",
parts[i].name,
parts[i].from * 512,
(parts[i].from + parts[i].size) * 512,
parts[i].size / 2048);
}
rk_emmc_fix();
rkpart_bootmode_fixup();
return 1;
}

40
block/partitions/rk.h Executable file
View File

@@ -0,0 +1,40 @@
/*
* block/partitions/rk.h
*/
/* error message prefix */
#define ERRP "rkpart: "
/* debug macro */
#define RKPART_DEBUG 0
#if RKPART_DEBUG
#define dbg(x) do { \
printk("DEBUG-CMDLINE-PART: "); \
printk x; \
} while (0)
#else
#define dbg(x)
#endif
/* At least 1GB disk support*/
#define SECTOR_1G 0x200000
/* Default partition table offet got from loader: 4MB*/
#define FROM_OFFSET 0x2000
/* special size referring to all the remaining space in a partition */
#define SIZE_REMAINING UINT_MAX
#define OFFSET_CONTINUOUS UINT_MAX
struct rk_partition {
char *name;
sector_t from;
sector_t size;
};
struct cmdline_rk_partition {
struct cmdline_rk_partition *next;
char *rk_id;
int num_parts;
struct rk_partition *parts;
};
int rkpart_partition(struct parsed_partitions *state);