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 | ||