blob: 499ad992ba160e43df5d7b16fdbd96f0cd0f1587 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* arch/arm/mach-msm/nand_partitions.c
2 *
3 * Code to extract partition information from ATAG set up by the
4 * bootloader.
5 *
6 * Copyright (C) 2007 Google, Inc.
Mekala Natarajanc2a29cc2011-10-27 15:23:47 -07007 * Copyright (c) 2008-2009,2011 Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07008 * Author: Brian Swetland <swetland@google.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/platform_device.h>
24
25#include <asm/mach/flash.h>
26#include <linux/io.h>
27
28#include <asm/setup.h>
29
30#include <linux/mtd/nand.h>
31#include <linux/mtd/partitions.h>
32
33#include <mach/msm_iomap.h>
34
35#include <mach/board.h>
Sahitya Tummalae608c512011-09-05 09:41:06 +053036#ifdef CONFIG_MSM_SMD
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070037#include "smd_private.h"
Sahitya Tummalae608c512011-09-05 09:41:06 +053038#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070039
40/* configuration tags specific to msm */
41
42#define ATAG_MSM_PARTITION 0x4d534D70 /* MSMp */
43
44struct msm_ptbl_entry {
45 char name[16];
46 __u32 offset;
47 __u32 size;
48 __u32 flags;
49};
50
Mekala Natarajanc2a29cc2011-10-27 15:23:47 -070051#define MSM_MAX_PARTITIONS 18
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070052
53static struct mtd_partition msm_nand_partitions[MSM_MAX_PARTITIONS];
54static char msm_nand_names[MSM_MAX_PARTITIONS * 16];
55
56extern struct flash_platform_data msm_nand_data;
57
58static int __init parse_tag_msm_partition(const struct tag *tag)
59{
60 struct mtd_partition *ptn = msm_nand_partitions;
61 char *name = msm_nand_names;
62 struct msm_ptbl_entry *entry = (void *) &tag->u;
63 unsigned count, n;
64
65 count = (tag->hdr.size - 2) /
66 (sizeof(struct msm_ptbl_entry) / sizeof(__u32));
67
68 if (count > MSM_MAX_PARTITIONS)
69 count = MSM_MAX_PARTITIONS;
70
71 for (n = 0; n < count; n++) {
72 memcpy(name, entry->name, 15);
73 name[15] = 0;
74
75 ptn->name = name;
76 ptn->offset = entry->offset;
77 ptn->size = entry->size;
78
79 printk(KERN_INFO "Partition (from atag) %s "
80 "-- Offset:%llx Size:%llx\n",
81 ptn->name, ptn->offset, ptn->size);
82
83 name += 16;
84 entry++;
85 ptn++;
86 }
87
88 msm_nand_data.nr_parts = count;
89 msm_nand_data.parts = msm_nand_partitions;
90
91 return 0;
92}
93
94__tagtable(ATAG_MSM_PARTITION, parse_tag_msm_partition);
95
96#define FLASH_PART_MAGIC1 0x55EE73AA
97#define FLASH_PART_MAGIC2 0xE35EBDDB
98#define FLASH_PARTITION_VERSION 0x3
99
100#define LINUX_FS_PARTITION_NAME "0:EFS2APPS"
101
102struct flash_partition_entry {
103 char name[16];
104 u32 offset; /* Offset in blocks from beginning of device */
105 u32 length; /* Length of the partition in blocks */
106 u8 attrib1;
107 u8 attrib2;
108 u8 attrib3;
109 u8 which_flash; /* Numeric ID (first = 0, second = 1) */
110};
111struct flash_partition_table {
112 u32 magic1;
113 u32 magic2;
114 u32 version;
115 u32 numparts;
116 struct flash_partition_entry part_entry[16];
117};
118
Sahitya Tummalae608c512011-09-05 09:41:06 +0530119#ifdef CONFIG_MSM_SMD
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700120static int get_nand_partitions(void)
121{
122 struct flash_partition_table *partition_table;
123 struct flash_partition_entry *part_entry;
124 struct mtd_partition *ptn = msm_nand_partitions;
125 char *name = msm_nand_names;
126 int part;
127
128 if (msm_nand_data.nr_parts)
129 return 0;
130
131 partition_table = (struct flash_partition_table *)
132 smem_alloc(SMEM_AARM_PARTITION_TABLE,
133 sizeof(struct flash_partition_table));
134
135 if (!partition_table) {
136 printk(KERN_WARNING "%s: no flash partition table in shared "
137 "memory\n", __func__);
138 return -ENOENT;
139 }
140
141 if ((partition_table->magic1 != (u32) FLASH_PART_MAGIC1) ||
142 (partition_table->magic2 != (u32) FLASH_PART_MAGIC2) ||
143 (partition_table->version != (u32) FLASH_PARTITION_VERSION)) {
144 printk(KERN_WARNING "%s: version mismatch -- magic1=%#x, "
145 "magic2=%#x, version=%#x\n", __func__,
146 partition_table->magic1,
147 partition_table->magic2,
148 partition_table->version);
149 return -EFAULT;
150 }
151
152 msm_nand_data.nr_parts = 0;
153
154 /* Get the LINUX FS partition info */
155 for (part = 0; part < partition_table->numparts; part++) {
156 part_entry = &partition_table->part_entry[part];
157
158 /* Find a match for the Linux file system partition */
159 if (strcmp(part_entry->name, LINUX_FS_PARTITION_NAME) == 0) {
160 strcpy(name, part_entry->name);
161 ptn->name = name;
162
163 /*TODO: Get block count and size info */
164 ptn->offset = part_entry->offset;
165
166 /* For SMEM, -1 indicates remaining space in flash,
167 * but for MTD it is 0
168 */
169 if (part_entry->length == (u32)-1)
170 ptn->size = 0;
171 else
172 ptn->size = part_entry->length;
173
174 msm_nand_data.nr_parts = 1;
175 msm_nand_data.parts = msm_nand_partitions;
176
177 printk(KERN_INFO "Partition(from smem) %s "
178 "-- Offset:%llx Size:%llx\n",
179 ptn->name, ptn->offset, ptn->size);
180
181 return 0;
182 }
183 }
184
185 printk(KERN_WARNING "%s: no partition table found!", __func__);
186
187 return -ENODEV;
188}
Sahitya Tummalae608c512011-09-05 09:41:06 +0530189#else
190static int get_nand_partitions(void)
191{
192
193 if (msm_nand_data.nr_parts)
194 return 0;
195
196 printk(KERN_WARNING "%s: no partition table found!", __func__);
197
198 return -ENODEV;
199}
200#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700201
202device_initcall(get_nand_partitions);