diff options
| author | Michal Marek <mmarek@suse.cz> | 2011-03-09 10:15:44 -0500 |
|---|---|---|
| committer | Michal Marek <mmarek@suse.cz> | 2011-03-09 10:15:44 -0500 |
| commit | 2d8ad8719591fa803b0d589ed057fa46f49b7155 (patch) | |
| tree | 4ae051577dad1161c91dafbf4207bb10a9dc91bb /drivers/mtd/lpddr/lpddr_cmds.c | |
| parent | 9b4ce7bce5f30712fd926ab4599a803314a07719 (diff) | |
| parent | c56eb8fb6dccb83d9fe62fd4dc00c834de9bc470 (diff) | |
Merge commit 'v2.6.38-rc1' into kbuild/packaging
Diffstat (limited to 'drivers/mtd/lpddr/lpddr_cmds.c')
| -rw-r--r-- | drivers/mtd/lpddr/lpddr_cmds.c | 100 |
1 files changed, 50 insertions, 50 deletions
diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index e22ca49583e7..04fdfcca93f7 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | */ | 26 | */ |
| 27 | #include <linux/mtd/pfow.h> | 27 | #include <linux/mtd/pfow.h> |
| 28 | #include <linux/mtd/qinfo.h> | 28 | #include <linux/mtd/qinfo.h> |
| 29 | #include <linux/slab.h> | ||
| 29 | 30 | ||
| 30 | static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len, | 31 | static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len, |
| 31 | size_t *retlen, u_char *buf); | 32 | size_t *retlen, u_char *buf); |
| @@ -97,7 +98,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) | |||
| 97 | numchips = lpddr->numchips / lpddr->qinfo->HWPartsNum; | 98 | numchips = lpddr->numchips / lpddr->qinfo->HWPartsNum; |
| 98 | for (i = 0; i < numchips; i++) { | 99 | for (i = 0; i < numchips; i++) { |
| 99 | shared[i].writing = shared[i].erasing = NULL; | 100 | shared[i].writing = shared[i].erasing = NULL; |
| 100 | spin_lock_init(&shared[i].lock); | 101 | mutex_init(&shared[i].lock); |
| 101 | for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) { | 102 | for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) { |
| 102 | *chip = lpddr->chips[i]; | 103 | *chip = lpddr->chips[i]; |
| 103 | chip->start += j << lpddr->chipshift; | 104 | chip->start += j << lpddr->chipshift; |
| @@ -106,8 +107,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) | |||
| 106 | /* those should be reset too since | 107 | /* those should be reset too since |
| 107 | they create memory references. */ | 108 | they create memory references. */ |
| 108 | init_waitqueue_head(&chip->wq); | 109 | init_waitqueue_head(&chip->wq); |
| 109 | spin_lock_init(&chip->_spinlock); | 110 | mutex_init(&chip->mutex); |
| 110 | chip->mutex = &chip->_spinlock; | ||
| 111 | chip++; | 111 | chip++; |
| 112 | } | 112 | } |
| 113 | } | 113 | } |
| @@ -143,7 +143,7 @@ static int wait_for_ready(struct map_info *map, struct flchip *chip, | |||
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | /* OK Still waiting. Drop the lock, wait a while and retry. */ | 145 | /* OK Still waiting. Drop the lock, wait a while and retry. */ |
| 146 | spin_unlock(chip->mutex); | 146 | mutex_unlock(&chip->mutex); |
| 147 | if (sleep_time >= 1000000/HZ) { | 147 | if (sleep_time >= 1000000/HZ) { |
| 148 | /* | 148 | /* |
| 149 | * Half of the normal delay still remaining | 149 | * Half of the normal delay still remaining |
| @@ -158,17 +158,17 @@ static int wait_for_ready(struct map_info *map, struct flchip *chip, | |||
| 158 | cond_resched(); | 158 | cond_resched(); |
| 159 | timeo--; | 159 | timeo--; |
| 160 | } | 160 | } |
| 161 | spin_lock(chip->mutex); | 161 | mutex_lock(&chip->mutex); |
| 162 | 162 | ||
| 163 | while (chip->state != chip_state) { | 163 | while (chip->state != chip_state) { |
| 164 | /* Someone's suspended the operation: sleep */ | 164 | /* Someone's suspended the operation: sleep */ |
| 165 | DECLARE_WAITQUEUE(wait, current); | 165 | DECLARE_WAITQUEUE(wait, current); |
| 166 | set_current_state(TASK_UNINTERRUPTIBLE); | 166 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 167 | add_wait_queue(&chip->wq, &wait); | 167 | add_wait_queue(&chip->wq, &wait); |
| 168 | spin_unlock(chip->mutex); | 168 | mutex_unlock(&chip->mutex); |
| 169 | schedule(); | 169 | schedule(); |
| 170 | remove_wait_queue(&chip->wq, &wait); | 170 | remove_wait_queue(&chip->wq, &wait); |
| 171 | spin_lock(chip->mutex); | 171 | mutex_lock(&chip->mutex); |
| 172 | } | 172 | } |
| 173 | if (chip->erase_suspended || chip->write_suspended) { | 173 | if (chip->erase_suspended || chip->write_suspended) { |
| 174 | /* Suspend has occured while sleep: reset timeout */ | 174 | /* Suspend has occured while sleep: reset timeout */ |
| @@ -217,7 +217,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode) | |||
| 217 | */ | 217 | */ |
| 218 | struct flchip_shared *shared = chip->priv; | 218 | struct flchip_shared *shared = chip->priv; |
| 219 | struct flchip *contender; | 219 | struct flchip *contender; |
| 220 | spin_lock(&shared->lock); | 220 | mutex_lock(&shared->lock); |
| 221 | contender = shared->writing; | 221 | contender = shared->writing; |
| 222 | if (contender && contender != chip) { | 222 | if (contender && contender != chip) { |
| 223 | /* | 223 | /* |
| @@ -229,45 +229,45 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode) | |||
| 229 | * it'll happily send us to sleep. In any case, when | 229 | * it'll happily send us to sleep. In any case, when |
| 230 | * get_chip returns success we're clear to go ahead. | 230 | * get_chip returns success we're clear to go ahead. |
| 231 | */ | 231 | */ |
| 232 | ret = spin_trylock(contender->mutex); | 232 | ret = mutex_trylock(&contender->mutex); |
| 233 | spin_unlock(&shared->lock); | 233 | mutex_unlock(&shared->lock); |
| 234 | if (!ret) | 234 | if (!ret) |
| 235 | goto retry; | 235 | goto retry; |
| 236 | spin_unlock(chip->mutex); | 236 | mutex_unlock(&chip->mutex); |
| 237 | ret = chip_ready(map, contender, mode); | 237 | ret = chip_ready(map, contender, mode); |
| 238 | spin_lock(chip->mutex); | 238 | mutex_lock(&chip->mutex); |
| 239 | 239 | ||
| 240 | if (ret == -EAGAIN) { | 240 | if (ret == -EAGAIN) { |
| 241 | spin_unlock(contender->mutex); | 241 | mutex_unlock(&contender->mutex); |
| 242 | goto retry; | 242 | goto retry; |
| 243 | } | 243 | } |
| 244 | if (ret) { | 244 | if (ret) { |
| 245 | spin_unlock(contender->mutex); | 245 | mutex_unlock(&contender->mutex); |
| 246 | return ret; | 246 | return ret; |
| 247 | } | 247 | } |
| 248 | spin_lock(&shared->lock); | 248 | mutex_lock(&shared->lock); |
| 249 | 249 | ||
| 250 | /* We should not own chip if it is already in FL_SYNCING | 250 | /* We should not own chip if it is already in FL_SYNCING |
| 251 | * state. Put contender and retry. */ | 251 | * state. Put contender and retry. */ |
| 252 | if (chip->state == FL_SYNCING) { | 252 | if (chip->state == FL_SYNCING) { |
| 253 | put_chip(map, contender); | 253 | put_chip(map, contender); |
| 254 | spin_unlock(contender->mutex); | 254 | mutex_unlock(&contender->mutex); |
| 255 | goto retry; | 255 | goto retry; |
| 256 | } | 256 | } |
| 257 | spin_unlock(contender->mutex); | 257 | mutex_unlock(&contender->mutex); |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | /* Check if we have suspended erase on this chip. | 260 | /* Check if we have suspended erase on this chip. |
| 261 | Must sleep in such a case. */ | 261 | Must sleep in such a case. */ |
| 262 | if (mode == FL_ERASING && shared->erasing | 262 | if (mode == FL_ERASING && shared->erasing |
| 263 | && shared->erasing->oldstate == FL_ERASING) { | 263 | && shared->erasing->oldstate == FL_ERASING) { |
| 264 | spin_unlock(&shared->lock); | 264 | mutex_unlock(&shared->lock); |
| 265 | set_current_state(TASK_UNINTERRUPTIBLE); | 265 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 266 | add_wait_queue(&chip->wq, &wait); | 266 | add_wait_queue(&chip->wq, &wait); |
| 267 | spin_unlock(chip->mutex); | 267 | mutex_unlock(&chip->mutex); |
| 268 | schedule(); | 268 | schedule(); |
| 269 | remove_wait_queue(&chip->wq, &wait); | 269 | remove_wait_queue(&chip->wq, &wait); |
| 270 | spin_lock(chip->mutex); | 270 | mutex_lock(&chip->mutex); |
| 271 | goto retry; | 271 | goto retry; |
| 272 | } | 272 | } |
| 273 | 273 | ||
| @@ -275,7 +275,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, int mode) | |||
| 275 | shared->writing = chip; | 275 | shared->writing = chip; |
| 276 | if (mode == FL_ERASING) | 276 | if (mode == FL_ERASING) |
| 277 | shared->erasing = chip; | 277 | shared->erasing = chip; |
| 278 | spin_unlock(&shared->lock); | 278 | mutex_unlock(&shared->lock); |
| 279 | } | 279 | } |
| 280 | 280 | ||
| 281 | ret = chip_ready(map, chip, mode); | 281 | ret = chip_ready(map, chip, mode); |
| @@ -336,10 +336,10 @@ static int chip_ready(struct map_info *map, struct flchip *chip, int mode) | |||
| 336 | sleep: | 336 | sleep: |
| 337 | set_current_state(TASK_UNINTERRUPTIBLE); | 337 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 338 | add_wait_queue(&chip->wq, &wait); | 338 | add_wait_queue(&chip->wq, &wait); |
| 339 | spin_unlock(chip->mutex); | 339 | mutex_unlock(&chip->mutex); |
| 340 | schedule(); | 340 | schedule(); |
| 341 | remove_wait_queue(&chip->wq, &wait); | 341 | remove_wait_queue(&chip->wq, &wait); |
| 342 | spin_lock(chip->mutex); | 342 | mutex_lock(&chip->mutex); |
| 343 | return -EAGAIN; | 343 | return -EAGAIN; |
| 344 | } | 344 | } |
| 345 | } | 345 | } |
| @@ -348,19 +348,19 @@ static void put_chip(struct map_info *map, struct flchip *chip) | |||
| 348 | { | 348 | { |
| 349 | if (chip->priv) { | 349 | if (chip->priv) { |
| 350 | struct flchip_shared *shared = chip->priv; | 350 | struct flchip_shared *shared = chip->priv; |
| 351 | spin_lock(&shared->lock); | 351 | mutex_lock(&shared->lock); |
| 352 | if (shared->writing == chip && chip->oldstate == FL_READY) { | 352 | if (shared->writing == chip && chip->oldstate == FL_READY) { |
| 353 | /* We own the ability to write, but we're done */ | 353 | /* We own the ability to write, but we're done */ |
| 354 | shared->writing = shared->erasing; | 354 | shared->writing = shared->erasing; |
| 355 | if (shared->writing && shared->writing != chip) { | 355 | if (shared->writing && shared->writing != chip) { |
| 356 | /* give back the ownership */ | 356 | /* give back the ownership */ |
| 357 | struct flchip *loaner = shared->writing; | 357 | struct flchip *loaner = shared->writing; |
| 358 | spin_lock(loaner->mutex); | 358 | mutex_lock(&loaner->mutex); |
| 359 | spin_unlock(&shared->lock); | 359 | mutex_unlock(&shared->lock); |
| 360 | spin_unlock(chip->mutex); | 360 | mutex_unlock(&chip->mutex); |
| 361 | put_chip(map, loaner); | 361 | put_chip(map, loaner); |
| 362 | spin_lock(chip->mutex); | 362 | mutex_lock(&chip->mutex); |
| 363 | spin_unlock(loaner->mutex); | 363 | mutex_unlock(&loaner->mutex); |
| 364 | wake_up(&chip->wq); | 364 | wake_up(&chip->wq); |
| 365 | return; | 365 | return; |
| 366 | } | 366 | } |
| @@ -374,11 +374,11 @@ static void put_chip(struct map_info *map, struct flchip *chip) | |||
| 374 | * Don't let the switch below mess things up since | 374 | * Don't let the switch below mess things up since |
| 375 | * we don't have ownership to resume anything. | 375 | * we don't have ownership to resume anything. |
| 376 | */ | 376 | */ |
| 377 | spin_unlock(&shared->lock); | 377 | mutex_unlock(&shared->lock); |
| 378 | wake_up(&chip->wq); | 378 | wake_up(&chip->wq); |
| 379 | return; | 379 | return; |
| 380 | } | 380 | } |
| 381 | spin_unlock(&shared->lock); | 381 | mutex_unlock(&shared->lock); |
| 382 | } | 382 | } |
| 383 | 383 | ||
| 384 | switch (chip->oldstate) { | 384 | switch (chip->oldstate) { |
| @@ -413,10 +413,10 @@ int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
| 413 | 413 | ||
| 414 | wbufsize = 1 << lpddr->qinfo->BufSizeShift; | 414 | wbufsize = 1 << lpddr->qinfo->BufSizeShift; |
| 415 | 415 | ||
| 416 | spin_lock(chip->mutex); | 416 | mutex_lock(&chip->mutex); |
| 417 | ret = get_chip(map, chip, FL_WRITING); | 417 | ret = get_chip(map, chip, FL_WRITING); |
| 418 | if (ret) { | 418 | if (ret) { |
| 419 | spin_unlock(chip->mutex); | 419 | mutex_unlock(&chip->mutex); |
| 420 | return ret; | 420 | return ret; |
| 421 | } | 421 | } |
| 422 | /* Figure out the number of words to write */ | 422 | /* Figure out the number of words to write */ |
| @@ -477,7 +477,7 @@ int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
| 477 | } | 477 | } |
| 478 | 478 | ||
| 479 | out: put_chip(map, chip); | 479 | out: put_chip(map, chip); |
| 480 | spin_unlock(chip->mutex); | 480 | mutex_unlock(&chip->mutex); |
| 481 | return ret; | 481 | return ret; |
| 482 | } | 482 | } |
| 483 | 483 | ||
| @@ -489,10 +489,10 @@ int do_erase_oneblock(struct mtd_info *mtd, loff_t adr) | |||
| 489 | struct flchip *chip = &lpddr->chips[chipnum]; | 489 | struct flchip *chip = &lpddr->chips[chipnum]; |
| 490 | int ret; | 490 | int ret; |
| 491 | 491 | ||
| 492 | spin_lock(chip->mutex); | 492 | mutex_lock(&chip->mutex); |
| 493 | ret = get_chip(map, chip, FL_ERASING); | 493 | ret = get_chip(map, chip, FL_ERASING); |
| 494 | if (ret) { | 494 | if (ret) { |
| 495 | spin_unlock(chip->mutex); | 495 | mutex_unlock(&chip->mutex); |
| 496 | return ret; | 496 | return ret; |
| 497 | } | 497 | } |
| 498 | send_pfow_command(map, LPDDR_BLOCK_ERASE, adr, 0, NULL); | 498 | send_pfow_command(map, LPDDR_BLOCK_ERASE, adr, 0, NULL); |
| @@ -504,7 +504,7 @@ int do_erase_oneblock(struct mtd_info *mtd, loff_t adr) | |||
| 504 | goto out; | 504 | goto out; |
| 505 | } | 505 | } |
| 506 | out: put_chip(map, chip); | 506 | out: put_chip(map, chip); |
| 507 | spin_unlock(chip->mutex); | 507 | mutex_unlock(&chip->mutex); |
| 508 | return ret; | 508 | return ret; |
| 509 | } | 509 | } |
| 510 | 510 | ||
| @@ -517,10 +517,10 @@ static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len, | |||
| 517 | struct flchip *chip = &lpddr->chips[chipnum]; | 517 | struct flchip *chip = &lpddr->chips[chipnum]; |
| 518 | int ret = 0; | 518 | int ret = 0; |
| 519 | 519 | ||
| 520 | spin_lock(chip->mutex); | 520 | mutex_lock(&chip->mutex); |
| 521 | ret = get_chip(map, chip, FL_READY); | 521 | ret = get_chip(map, chip, FL_READY); |
| 522 | if (ret) { | 522 | if (ret) { |
| 523 | spin_unlock(chip->mutex); | 523 | mutex_unlock(&chip->mutex); |
| 524 | return ret; | 524 | return ret; |
| 525 | } | 525 | } |
| 526 | 526 | ||
| @@ -528,7 +528,7 @@ static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len, | |||
| 528 | *retlen = len; | 528 | *retlen = len; |
| 529 | 529 | ||
| 530 | put_chip(map, chip); | 530 | put_chip(map, chip); |
| 531 | spin_unlock(chip->mutex); | 531 | mutex_unlock(&chip->mutex); |
| 532 | return ret; | 532 | return ret; |
| 533 | } | 533 | } |
| 534 | 534 | ||
| @@ -568,9 +568,9 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, | |||
| 568 | else | 568 | else |
| 569 | thislen = len; | 569 | thislen = len; |
| 570 | /* get the chip */ | 570 | /* get the chip */ |
| 571 | spin_lock(chip->mutex); | 571 | mutex_lock(&chip->mutex); |
| 572 | ret = get_chip(map, chip, FL_POINT); | 572 | ret = get_chip(map, chip, FL_POINT); |
| 573 | spin_unlock(chip->mutex); | 573 | mutex_unlock(&chip->mutex); |
| 574 | if (ret) | 574 | if (ret) |
| 575 | break; | 575 | break; |
| 576 | 576 | ||
| @@ -610,7 +610,7 @@ static void lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) | |||
| 610 | else | 610 | else |
| 611 | thislen = len; | 611 | thislen = len; |
| 612 | 612 | ||
| 613 | spin_lock(chip->mutex); | 613 | mutex_lock(&chip->mutex); |
| 614 | if (chip->state == FL_POINT) { | 614 | if (chip->state == FL_POINT) { |
| 615 | chip->ref_point_counter--; | 615 | chip->ref_point_counter--; |
| 616 | if (chip->ref_point_counter == 0) | 616 | if (chip->ref_point_counter == 0) |
| @@ -620,7 +620,7 @@ static void lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) | |||
| 620 | "pointed region\n", map->name); | 620 | "pointed region\n", map->name); |
| 621 | 621 | ||
| 622 | put_chip(map, chip); | 622 | put_chip(map, chip); |
| 623 | spin_unlock(chip->mutex); | 623 | mutex_unlock(&chip->mutex); |
| 624 | 624 | ||
| 625 | len -= thislen; | 625 | len -= thislen; |
| 626 | ofs = 0; | 626 | ofs = 0; |
| @@ -726,10 +726,10 @@ int do_xxlock(struct mtd_info *mtd, loff_t adr, uint32_t len, int thunk) | |||
| 726 | int chipnum = adr >> lpddr->chipshift; | 726 | int chipnum = adr >> lpddr->chipshift; |
| 727 | struct flchip *chip = &lpddr->chips[chipnum]; | 727 | struct flchip *chip = &lpddr->chips[chipnum]; |
| 728 | 728 | ||
| 729 | spin_lock(chip->mutex); | 729 | mutex_lock(&chip->mutex); |
| 730 | ret = get_chip(map, chip, FL_LOCKING); | 730 | ret = get_chip(map, chip, FL_LOCKING); |
| 731 | if (ret) { | 731 | if (ret) { |
| 732 | spin_unlock(chip->mutex); | 732 | mutex_unlock(&chip->mutex); |
| 733 | return ret; | 733 | return ret; |
| 734 | } | 734 | } |
| 735 | 735 | ||
| @@ -749,7 +749,7 @@ int do_xxlock(struct mtd_info *mtd, loff_t adr, uint32_t len, int thunk) | |||
| 749 | goto out; | 749 | goto out; |
| 750 | } | 750 | } |
| 751 | out: put_chip(map, chip); | 751 | out: put_chip(map, chip); |
| 752 | spin_unlock(chip->mutex); | 752 | mutex_unlock(&chip->mutex); |
| 753 | return ret; | 753 | return ret; |
| 754 | } | 754 | } |
| 755 | 755 | ||
| @@ -770,10 +770,10 @@ int word_program(struct map_info *map, loff_t adr, uint32_t curval) | |||
| 770 | int chipnum = adr >> lpddr->chipshift; | 770 | int chipnum = adr >> lpddr->chipshift; |
| 771 | struct flchip *chip = &lpddr->chips[chipnum]; | 771 | struct flchip *chip = &lpddr->chips[chipnum]; |
| 772 | 772 | ||
| 773 | spin_lock(chip->mutex); | 773 | mutex_lock(&chip->mutex); |
| 774 | ret = get_chip(map, chip, FL_WRITING); | 774 | ret = get_chip(map, chip, FL_WRITING); |
| 775 | if (ret) { | 775 | if (ret) { |
| 776 | spin_unlock(chip->mutex); | 776 | mutex_unlock(&chip->mutex); |
| 777 | return ret; | 777 | return ret; |
| 778 | } | 778 | } |
| 779 | 779 | ||
| @@ -787,7 +787,7 @@ int word_program(struct map_info *map, loff_t adr, uint32_t curval) | |||
| 787 | } | 787 | } |
| 788 | 788 | ||
| 789 | out: put_chip(map, chip); | 789 | out: put_chip(map, chip); |
| 790 | spin_unlock(chip->mutex); | 790 | mutex_unlock(&chip->mutex); |
| 791 | return ret; | 791 | return ret; |
| 792 | } | 792 | } |
| 793 | 793 | ||
