summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorAndrew Gabbasov <andrew_gabbasov@mentor.com>2013-05-14 12:27:52 -0500
committerStefan Roese <sr@denx.de>2013-05-23 09:47:59 +0200
commitaedadf10f0eac3084105511062520b0b361dd9bf (patch)
tree3401bdcd36c707b0969d068cca3d0a990eee31f7 /drivers
parent8bcb6f43e98ffc76e998349e0ec32a0e359160d4 (diff)
downloadu-boot-imx-aedadf10f0eac3084105511062520b0b361dd9bf.zip
u-boot-imx-aedadf10f0eac3084105511062520b0b361dd9bf.tar.gz
u-boot-imx-aedadf10f0eac3084105511062520b0b361dd9bf.tar.bz2
cfi_flash: Fix unaligned accesses to cfi_qry structure
Packed structure cfi_qry contains unaligned 16- and 32-bits members, accessing which causes problems when cfi_flash driver is compiled with -munaligned-access option: flash initialization hangs, probably due to data error. Since the structure is supposed to replicate the actual data layout in CFI Flash chips, the alignment issue can't be fixed in the structure. So, unaligned fields need using of explicit unaligned access macros. Signed-off-by: Andrew Gabbasov <andrew_gabbasov@mentor.com> Reviewed-By: Albert ARIBAUD <albert.u.boot@aribaud.net> Signed-off-by: Stefan Roese <sr@denx.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/cfi_flash.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 22d8440..f6759a8 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -38,6 +38,7 @@
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <environment.h>
#include <mtd/cfi_flash.h>
#include <watchdog.h>
@@ -1640,9 +1641,10 @@ static void cfi_reverse_geometry(struct cfi_qry *qry)
u32 tmp;
for (i = 0, j = qry->num_erase_regions - 1; i < j; i++, j--) {
- tmp = qry->erase_region_info[i];
- qry->erase_region_info[i] = qry->erase_region_info[j];
- qry->erase_region_info[j] = tmp;
+ tmp = get_unaligned(&(qry->erase_region_info[i]));
+ put_unaligned(get_unaligned(&(qry->erase_region_info[j])),
+ &(qry->erase_region_info[i]));
+ put_unaligned(tmp, &(qry->erase_region_info[j]));
}
}
@@ -2073,8 +2075,8 @@ ulong flash_get_size (phys_addr_t base, int banknum)
info->start[0] = (ulong)map_physmem(base, info->portwidth, MAP_NOCACHE);
if (flash_detect_cfi (info, &qry)) {
- info->vendor = le16_to_cpu(qry.p_id);
- info->ext_addr = le16_to_cpu(qry.p_adr);
+ info->vendor = le16_to_cpu(get_unaligned(&(qry.p_id)));
+ info->ext_addr = le16_to_cpu(get_unaligned(&(qry.p_adr)));
num_erase_regions = qry.num_erase_regions;
if (info->ext_addr) {
@@ -2163,7 +2165,8 @@ ulong flash_get_size (phys_addr_t base, int banknum)
break;
}
- tmp = le32_to_cpu(qry.erase_region_info[i]);
+ tmp = le32_to_cpu(get_unaligned(
+ &(qry.erase_region_info[i])));
debug("erase region %u: 0x%08lx\n", i, tmp);
erase_region_count = (tmp & 0xffff) + 1;