aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/onenand')
-rw-r--r--drivers/mtd/onenand/onenand_base.c20
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