diff options
author | Kyungmin Park <kyungmin.park@samsung.com> | 2006-11-15 21:29:39 -0500 |
---|---|---|
committer | Kyungmin Park <kyungmin.park@samsung.com> | 2006-11-15 21:29:39 -0500 |
commit | 08f782b60a633cbd926ef5e49de303a752390719 (patch) | |
tree | 927c3269661438faf438e7c3096edd9fa02086dd /drivers/mtd | |
parent | 2c22120fbd017d78ad2b6825ba573db3ef539bca (diff) |
[MTD] OneNAND: lock support
Now you can use mtd lock inferface on OneNAND
The idea is from Nemakal, Vijaya, thanks
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 63 |
1 files changed, 48 insertions, 15 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index aea13a388868..bef4f26ad2ed 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
@@ -1301,32 +1301,38 @@ static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs) | |||
1301 | } | 1301 | } |
1302 | 1302 | ||
1303 | /** | 1303 | /** |
1304 | * onenand_unlock - [MTD Interface] Unlock block(s) | 1304 | * onenand_do_lock_cmd - [OneNAND Interface] Lock or unlock block(s) |
1305 | * @param mtd MTD device structure | 1305 | * @param mtd MTD device structure |
1306 | * @param ofs offset relative to mtd start | 1306 | * @param ofs offset relative to mtd start |
1307 | * @param len number of bytes to unlock | 1307 | * @param len number of bytes to lock or unlock |
1308 | * | 1308 | * |
1309 | * Unlock one or more blocks | 1309 | * Lock or unlock one or more blocks |
1310 | */ | 1310 | */ |
1311 | static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | 1311 | static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int cmd) |
1312 | { | 1312 | { |
1313 | struct onenand_chip *this = mtd->priv; | 1313 | struct onenand_chip *this = mtd->priv; |
1314 | int start, end, block, value, status; | 1314 | int start, end, block, value, status; |
1315 | int wp_status_mask; | ||
1315 | 1316 | ||
1316 | start = ofs >> this->erase_shift; | 1317 | start = ofs >> this->erase_shift; |
1317 | end = len >> this->erase_shift; | 1318 | end = len >> this->erase_shift; |
1318 | 1319 | ||
1320 | if (cmd == ONENAND_CMD_LOCK) | ||
1321 | wp_status_mask = ONENAND_WP_LS; | ||
1322 | else | ||
1323 | wp_status_mask = ONENAND_WP_US; | ||
1324 | |||
1319 | /* Continuous lock scheme */ | 1325 | /* Continuous lock scheme */ |
1320 | if (this->options & ONENAND_HAS_CONT_LOCK) { | 1326 | if (this->options & ONENAND_HAS_CONT_LOCK) { |
1321 | /* Set start block address */ | 1327 | /* Set start block address */ |
1322 | this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS); | 1328 | this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS); |
1323 | /* Set end block address */ | 1329 | /* Set end block address */ |
1324 | this->write_word(start + end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS); | 1330 | this->write_word(start + end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS); |
1325 | /* Write unlock command */ | 1331 | /* Write lock command */ |
1326 | this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0); | 1332 | this->command(mtd, cmd, 0, 0); |
1327 | 1333 | ||
1328 | /* There's no return value */ | 1334 | /* There's no return value */ |
1329 | this->wait(mtd, FL_UNLOCKING); | 1335 | this->wait(mtd, FL_LOCKING); |
1330 | 1336 | ||
1331 | /* Sanity check */ | 1337 | /* Sanity check */ |
1332 | while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS) | 1338 | while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS) |
@@ -1335,7 +1341,7 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1335 | 1341 | ||
1336 | /* Check lock status */ | 1342 | /* Check lock status */ |
1337 | status = this->read_word(this->base + ONENAND_REG_WP_STATUS); | 1343 | status = this->read_word(this->base + ONENAND_REG_WP_STATUS); |
1338 | if (!(status & ONENAND_WP_US)) | 1344 | if (!(status & wp_status_mask)) |
1339 | printk(KERN_ERR "wp status = 0x%x\n", status); | 1345 | printk(KERN_ERR "wp status = 0x%x\n", status); |
1340 | 1346 | ||
1341 | return 0; | 1347 | return 0; |
@@ -1351,11 +1357,11 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1351 | this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); | 1357 | this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); |
1352 | /* Set start block address */ | 1358 | /* Set start block address */ |
1353 | this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS); | 1359 | this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS); |
1354 | /* Write unlock command */ | 1360 | /* Write lock command */ |
1355 | this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0); | 1361 | this->command(mtd, cmd, 0, 0); |
1356 | 1362 | ||
1357 | /* There's no return value */ | 1363 | /* There's no return value */ |
1358 | this->wait(mtd, FL_UNLOCKING); | 1364 | this->wait(mtd, FL_LOCKING); |
1359 | 1365 | ||
1360 | /* Sanity check */ | 1366 | /* Sanity check */ |
1361 | while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS) | 1367 | while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS) |
@@ -1364,7 +1370,7 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1364 | 1370 | ||
1365 | /* Check lock status */ | 1371 | /* Check lock status */ |
1366 | status = this->read_word(this->base + ONENAND_REG_WP_STATUS); | 1372 | status = this->read_word(this->base + ONENAND_REG_WP_STATUS); |
1367 | if (!(status & ONENAND_WP_US)) | 1373 | if (!(status & wp_status_mask)) |
1368 | printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status); | 1374 | printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status); |
1369 | } | 1375 | } |
1370 | 1376 | ||
@@ -1372,6 +1378,33 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | |||
1372 | } | 1378 | } |
1373 | 1379 | ||
1374 | /** | 1380 | /** |
1381 | * onenand_lock - [MTD Interface] Lock block(s) | ||
1382 | * @param mtd MTD device structure | ||
1383 | * @param ofs offset relative to mtd start | ||
1384 | * @param len number of bytes to unlock | ||
1385 | * | ||
1386 | * Lock one or more blocks | ||
1387 | */ | ||
1388 | static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len) | ||
1389 | { | ||
1390 | return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK); | ||
1391 | } | ||
1392 | |||
1393 | |||
1394 | /** | ||
1395 | * onenand_unlock - [MTD Interface] Unlock block(s) | ||
1396 | * @param mtd MTD device structure | ||
1397 | * @param ofs offset relative to mtd start | ||
1398 | * @param len number of bytes to unlock | ||
1399 | * | ||
1400 | * Unlock one or more blocks | ||
1401 | */ | ||
1402 | static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | ||
1403 | { | ||
1404 | return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK); | ||
1405 | } | ||
1406 | |||
1407 | /** | ||
1375 | * onenand_check_lock_status - [OneNAND Interface] Check lock status | 1408 | * onenand_check_lock_status - [OneNAND Interface] Check lock status |
1376 | * @param this onenand chip data structure | 1409 | * @param this onenand chip data structure |
1377 | * | 1410 | * |
@@ -1415,7 +1448,7 @@ static int onenand_unlock_all(struct mtd_info *mtd) | |||
1415 | this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0); | 1448 | this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0); |
1416 | 1449 | ||
1417 | /* There's no return value */ | 1450 | /* There's no return value */ |
1418 | this->wait(mtd, FL_UNLOCKING); | 1451 | this->wait(mtd, FL_LOCKING); |
1419 | 1452 | ||
1420 | /* Sanity check */ | 1453 | /* Sanity check */ |
1421 | while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS) | 1454 | while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS) |
@@ -1439,7 +1472,7 @@ static int onenand_unlock_all(struct mtd_info *mtd) | |||
1439 | return 0; | 1472 | return 0; |
1440 | } | 1473 | } |
1441 | 1474 | ||
1442 | mtd->unlock(mtd, 0x0, this->chipsize); | 1475 | onenand_unlock(mtd, 0x0, this->chipsize); |
1443 | 1476 | ||
1444 | return 0; | 1477 | return 0; |
1445 | } | 1478 | } |
@@ -2027,7 +2060,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) | |||
2027 | mtd->lock_user_prot_reg = onenand_lock_user_prot_reg; | 2060 | mtd->lock_user_prot_reg = onenand_lock_user_prot_reg; |
2028 | #endif | 2061 | #endif |
2029 | mtd->sync = onenand_sync; | 2062 | mtd->sync = onenand_sync; |
2030 | mtd->lock = NULL; | 2063 | mtd->lock = onenand_lock; |
2031 | mtd->unlock = onenand_unlock; | 2064 | mtd->unlock = onenand_unlock; |
2032 | mtd->suspend = onenand_suspend; | 2065 | mtd->suspend = onenand_suspend; |
2033 | mtd->resume = onenand_resume; | 2066 | mtd->resume = onenand_resume; |