diff options
Diffstat (limited to 'drivers/mtd/onenand')
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 553b24d93335..3d6f880cba9c 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
@@ -1051,40 +1051,37 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | column = to & (mtd->writesize - 1); | 1053 | column = to & (mtd->writesize - 1); |
1054 | subpage = column || (len & (mtd->writesize - 1)); | ||
1055 | 1054 | ||
1056 | /* Grab the lock and see if the device is available */ | 1055 | /* Grab the lock and see if the device is available */ |
1057 | onenand_get_device(mtd, FL_WRITING); | 1056 | onenand_get_device(mtd, FL_WRITING); |
1058 | 1057 | ||
1059 | /* Loop until all data write */ | 1058 | /* Loop until all data write */ |
1060 | while (written < len) { | 1059 | while (written < len) { |
1061 | int bytes = mtd->writesize; | 1060 | int thislen = min_t(int, mtd->writesize - column, len - written); |
1062 | int thislen = min_t(int, bytes, len - written); | ||
1063 | u_char *wbuf = (u_char *) buf; | 1061 | u_char *wbuf = (u_char *) buf; |
1064 | 1062 | ||
1065 | cond_resched(); | 1063 | cond_resched(); |
1066 | 1064 | ||
1067 | this->command(mtd, ONENAND_CMD_BUFFERRAM, to, bytes); | 1065 | this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen); |
1068 | 1066 | ||
1069 | /* Partial page write */ | 1067 | /* Partial page write */ |
1068 | subpage = thislen < mtd->writesize; | ||
1070 | if (subpage) { | 1069 | if (subpage) { |
1071 | bytes = min_t(int, bytes - column, (int) len); | ||
1072 | memset(this->page_buf, 0xff, mtd->writesize); | 1070 | memset(this->page_buf, 0xff, mtd->writesize); |
1073 | memcpy(this->page_buf + column, buf, bytes); | 1071 | memcpy(this->page_buf + column, buf, thislen); |
1074 | wbuf = this->page_buf; | 1072 | wbuf = this->page_buf; |
1075 | /* Even though partial write, we need page size */ | ||
1076 | thislen = mtd->writesize; | ||
1077 | } | 1073 | } |
1078 | 1074 | ||
1079 | this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, thislen); | 1075 | this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize); |
1080 | this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); | 1076 | this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); |
1081 | 1077 | ||
1082 | this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize); | 1078 | this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize); |
1083 | 1079 | ||
1080 | ret = this->wait(mtd, FL_WRITING); | ||
1081 | |||
1084 | /* In partial page write we don't update bufferram */ | 1082 | /* In partial page write we don't update bufferram */ |
1085 | onenand_update_bufferram(mtd, to, !subpage); | 1083 | onenand_update_bufferram(mtd, to, !ret && !subpage); |
1086 | 1084 | ||
1087 | ret = this->wait(mtd, FL_WRITING); | ||
1088 | if (ret) { | 1085 | if (ret) { |
1089 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret); | 1086 | DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret); |
1090 | break; | 1087 | break; |
@@ -1098,6 +1095,7 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
1098 | } | 1095 | } |
1099 | 1096 | ||
1100 | written += thislen; | 1097 | written += thislen; |
1098 | |||
1101 | if (written == len) | 1099 | if (written == len) |
1102 | break; | 1100 | break; |
1103 | 1101 | ||