Skip to content

Commit

Permalink
[MTD] OneNAND: lock support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Kyungmin Park committed Nov 16, 2006
1 parent 2c22120 commit 08f782b
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 16 deletions.
63 changes: 48 additions & 15 deletions drivers/mtd/onenand/onenand_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1301,32 +1301,38 @@ static int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
}

/**
* onenand_unlock - [MTD Interface] Unlock block(s)
* onenand_do_lock_cmd - [OneNAND Interface] Lock or unlock block(s)
* @param mtd MTD device structure
* @param ofs offset relative to mtd start
* @param len number of bytes to unlock
* @param len number of bytes to lock or unlock
*
* Unlock one or more blocks
* Lock or unlock one or more blocks
*/
static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int cmd)
{
struct onenand_chip *this = mtd->priv;
int start, end, block, value, status;
int wp_status_mask;

start = ofs >> this->erase_shift;
end = len >> this->erase_shift;

if (cmd == ONENAND_CMD_LOCK)
wp_status_mask = ONENAND_WP_LS;
else
wp_status_mask = ONENAND_WP_US;

/* Continuous lock scheme */
if (this->options & ONENAND_HAS_CONT_LOCK) {
/* Set start block address */
this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
/* Set end block address */
this->write_word(start + end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);
/* Write unlock command */
this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
/* Write lock command */
this->command(mtd, cmd, 0, 0);

/* There's no return value */
this->wait(mtd, FL_UNLOCKING);
this->wait(mtd, FL_LOCKING);

/* Sanity check */
while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
Expand All @@ -1335,7 +1341,7 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)

/* Check lock status */
status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
if (!(status & ONENAND_WP_US))
if (!(status & wp_status_mask))
printk(KERN_ERR "wp status = 0x%x\n", status);

return 0;
Expand All @@ -1351,11 +1357,11 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);
/* Set start block address */
this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);
/* Write unlock command */
this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);
/* Write lock command */
this->command(mtd, cmd, 0, 0);

/* There's no return value */
this->wait(mtd, FL_UNLOCKING);
this->wait(mtd, FL_LOCKING);

/* Sanity check */
while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
Expand All @@ -1364,13 +1370,40 @@ static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)

/* Check lock status */
status = this->read_word(this->base + ONENAND_REG_WP_STATUS);
if (!(status & ONENAND_WP_US))
if (!(status & wp_status_mask))
printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);
}

return 0;
}

/**
* onenand_lock - [MTD Interface] Lock block(s)
* @param mtd MTD device structure
* @param ofs offset relative to mtd start
* @param len number of bytes to unlock
*
* Lock one or more blocks
*/
static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
{
return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK);
}


/**
* onenand_unlock - [MTD Interface] Unlock block(s)
* @param mtd MTD device structure
* @param ofs offset relative to mtd start
* @param len number of bytes to unlock
*
* Unlock one or more blocks
*/
static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
{
return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
}

/**
* onenand_check_lock_status - [OneNAND Interface] Check lock status
* @param this onenand chip data structure
Expand Down Expand Up @@ -1415,7 +1448,7 @@ static int onenand_unlock_all(struct mtd_info *mtd)
this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);

/* There's no return value */
this->wait(mtd, FL_UNLOCKING);
this->wait(mtd, FL_LOCKING);

/* Sanity check */
while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)
Expand All @@ -1439,7 +1472,7 @@ static int onenand_unlock_all(struct mtd_info *mtd)
return 0;
}

mtd->unlock(mtd, 0x0, this->chipsize);
onenand_unlock(mtd, 0x0, this->chipsize);

return 0;
}
Expand Down Expand Up @@ -2027,7 +2060,7 @@ int onenand_scan(struct mtd_info *mtd, int maxchips)
mtd->lock_user_prot_reg = onenand_lock_user_prot_reg;
#endif
mtd->sync = onenand_sync;
mtd->lock = NULL;
mtd->lock = onenand_lock;
mtd->unlock = onenand_unlock;
mtd->suspend = onenand_suspend;
mtd->resume = onenand_resume;
Expand Down
1 change: 0 additions & 1 deletion include/linux/mtd/onenand.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ typedef enum {
FL_WRITING,
FL_ERASING,
FL_SYNCING,
FL_UNLOCKING,
FL_LOCKING,
FL_RESETING,
FL_OTPING,
Expand Down

0 comments on commit 08f782b

Please sign in to comment.