aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/lpddr/lpddr_cmds.c
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2011-03-09 10:15:44 -0500
committerMichal Marek <mmarek@suse.cz>2011-03-09 10:15:44 -0500
commit2d8ad8719591fa803b0d589ed057fa46f49b7155 (patch)
tree4ae051577dad1161c91dafbf4207bb10a9dc91bb /drivers/mtd/lpddr/lpddr_cmds.c
parent9b4ce7bce5f30712fd926ab4599a803314a07719 (diff)
parentc56eb8fb6dccb83d9fe62fd4dc00c834de9bc470 (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.c100
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
30static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len, 31static 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)
336sleep: 336sleep:
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 }
751out: put_chip(map, chip); 751out: 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
789out: put_chip(map, chip); 789out: put_chip(map, chip);
790 spin_unlock(chip->mutex); 790 mutex_unlock(&chip->mutex);
791 return ret; 791 return ret;
792} 792}
793 793