Lines Matching +full:wait +full:- +full:retry +full:- +full:us
1 // SPDX-License-Identifier: GPL-2.0-or-later
37 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_cmdset()
47 mtd->priv = map; in lpddr_cmdset()
48 mtd->type = MTD_NORFLASH; in lpddr_cmdset()
51 mtd->_read = lpddr_read; in lpddr_cmdset()
52 mtd->type = MTD_NORFLASH; in lpddr_cmdset()
53 mtd->flags = MTD_CAP_NORFLASH; in lpddr_cmdset()
54 mtd->flags &= ~MTD_BIT_WRITEABLE; in lpddr_cmdset()
55 mtd->_erase = lpddr_erase; in lpddr_cmdset()
56 mtd->_write = lpddr_write_buffers; in lpddr_cmdset()
57 mtd->_writev = lpddr_writev; in lpddr_cmdset()
58 mtd->_lock = lpddr_lock; in lpddr_cmdset()
59 mtd->_unlock = lpddr_unlock; in lpddr_cmdset()
61 mtd->_point = lpddr_point; in lpddr_cmdset()
62 mtd->_unpoint = lpddr_unpoint; in lpddr_cmdset()
64 mtd->size = 1ULL << lpddr->qinfo->DevSizeShift; in lpddr_cmdset()
65 mtd->erasesize = 1 << lpddr->qinfo->UniformBlockSizeShift; in lpddr_cmdset()
66 mtd->writesize = 1 << lpddr->qinfo->BufSizeShift; in lpddr_cmdset()
68 shared = kmalloc_array(lpddr->numchips, sizeof(struct flchip_shared), in lpddr_cmdset()
75 chip = &lpddr->chips[0]; in lpddr_cmdset()
76 numchips = lpddr->numchips / lpddr->qinfo->HWPartsNum; in lpddr_cmdset()
80 for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) { in lpddr_cmdset()
81 *chip = lpddr->chips[i]; in lpddr_cmdset()
82 chip->start += j << lpddr->chipshift; in lpddr_cmdset()
83 chip->oldstate = chip->state = FL_READY; in lpddr_cmdset()
84 chip->priv = &shared[i]; in lpddr_cmdset()
87 init_waitqueue_head(&chip->wq); in lpddr_cmdset()
88 mutex_init(&chip->mutex); in lpddr_cmdset()
130 flstate_t chip_state = chip->state; in wait_for_ready()
141 dsr = CMDVAL(map_read(map, map->pfow_base + PFOW_DSR)); in wait_for_ready()
146 map->name, chip_state); in wait_for_ready()
147 ret = -ETIME; in wait_for_ready()
151 /* OK Still waiting. Drop the lock, wait a while and retry. */ in wait_for_ready()
152 mutex_unlock(&chip->mutex); in wait_for_ready()
160 timeo -= sleep_time; in wait_for_ready()
165 timeo--; in wait_for_ready()
167 mutex_lock(&chip->mutex); in wait_for_ready()
169 while (chip->state != chip_state) { in wait_for_ready()
171 DECLARE_WAITQUEUE(wait, current); in wait_for_ready()
173 add_wait_queue(&chip->wq, &wait); in wait_for_ready()
174 mutex_unlock(&chip->mutex); in wait_for_ready()
176 remove_wait_queue(&chip->wq, &wait); in wait_for_ready()
177 mutex_lock(&chip->mutex); in wait_for_ready()
179 if (chip->erase_suspended || chip->write_suspended) { in wait_for_ready()
182 chip->erase_suspended = chip->write_suspended = 0; in wait_for_ready()
188 map_write(map, CMD(~(DSR_ERR)), map->pfow_base + PFOW_DSR); in wait_for_ready()
189 printk(KERN_WARNING"%s: Bad status on wait: 0x%x \n", in wait_for_ready()
190 map->name, dsr); in wait_for_ready()
192 ret = -EIO; in wait_for_ready()
194 chip->state = FL_READY; in wait_for_ready()
201 DECLARE_WAITQUEUE(wait, current); in get_chip()
203 retry: in get_chip()
204 if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING) in get_chip()
205 && chip->state != FL_SYNCING) { in get_chip()
214 * - any write operation must own shared->writing. in get_chip()
216 * - any erase operation must own _both_ shared->writing and in get_chip()
217 * shared->erasing. in get_chip()
219 * - contension arbitration is handled in the owner's context. in get_chip()
224 struct flchip_shared *shared = chip->priv; in get_chip()
226 mutex_lock(&shared->lock); in get_chip()
227 contender = shared->writing; in get_chip()
235 * it'll happily send us to sleep. In any case, when in get_chip()
238 ret = mutex_trylock(&contender->mutex); in get_chip()
239 mutex_unlock(&shared->lock); in get_chip()
241 goto retry; in get_chip()
242 mutex_unlock(&chip->mutex); in get_chip()
244 mutex_lock(&chip->mutex); in get_chip()
246 if (ret == -EAGAIN) { in get_chip()
247 mutex_unlock(&contender->mutex); in get_chip()
248 goto retry; in get_chip()
251 mutex_unlock(&contender->mutex); in get_chip()
254 mutex_lock(&shared->lock); in get_chip()
257 * state. Put contender and retry. */ in get_chip()
258 if (chip->state == FL_SYNCING) { in get_chip()
260 mutex_unlock(&contender->mutex); in get_chip()
261 goto retry; in get_chip()
263 mutex_unlock(&contender->mutex); in get_chip()
268 if (mode == FL_ERASING && shared->erasing in get_chip()
269 && shared->erasing->oldstate == FL_ERASING) { in get_chip()
270 mutex_unlock(&shared->lock); in get_chip()
272 add_wait_queue(&chip->wq, &wait); in get_chip()
273 mutex_unlock(&chip->mutex); in get_chip()
275 remove_wait_queue(&chip->wq, &wait); in get_chip()
276 mutex_lock(&chip->mutex); in get_chip()
277 goto retry; in get_chip()
281 shared->writing = chip; in get_chip()
283 shared->erasing = chip; in get_chip()
284 mutex_unlock(&shared->lock); in get_chip()
288 if (ret == -EAGAIN) in get_chip()
289 goto retry; in get_chip()
296 struct lpddr_private *lpddr = map->fldrv_priv; in chip_ready()
298 DECLARE_WAITQUEUE(wait, current); in chip_ready()
301 if (FL_SYNCING == mode && FL_READY != chip->oldstate) in chip_ready()
304 switch (chip->state) { in chip_ready()
310 if (!lpddr->qinfo->SuspEraseSupp || in chip_ready()
315 map->pfow_base + PFOW_PROGRAM_ERASE_SUSPEND); in chip_ready()
316 chip->oldstate = FL_ERASING; in chip_ready()
317 chip->state = FL_ERASE_SUSPENDING; in chip_ready()
324 "State may be wrong \n", map->name); in chip_ready()
325 return -EIO; in chip_ready()
327 chip->erase_suspended = 1; in chip_ready()
328 chip->state = FL_READY; in chip_ready()
333 if (mode == FL_READY && chip->oldstate == FL_READY) in chip_ready()
339 add_wait_queue(&chip->wq, &wait); in chip_ready()
340 mutex_unlock(&chip->mutex); in chip_ready()
342 remove_wait_queue(&chip->wq, &wait); in chip_ready()
343 mutex_lock(&chip->mutex); in chip_ready()
344 return -EAGAIN; in chip_ready()
350 if (chip->priv) { in put_chip()
351 struct flchip_shared *shared = chip->priv; in put_chip()
352 mutex_lock(&shared->lock); in put_chip()
353 if (shared->writing == chip && chip->oldstate == FL_READY) { in put_chip()
355 shared->writing = shared->erasing; in put_chip()
356 if (shared->writing && shared->writing != chip) { in put_chip()
358 struct flchip *loaner = shared->writing; in put_chip()
359 mutex_lock(&loaner->mutex); in put_chip()
360 mutex_unlock(&shared->lock); in put_chip()
361 mutex_unlock(&chip->mutex); in put_chip()
363 mutex_lock(&chip->mutex); in put_chip()
364 mutex_unlock(&loaner->mutex); in put_chip()
365 wake_up(&chip->wq); in put_chip()
368 shared->erasing = NULL; in put_chip()
369 shared->writing = NULL; in put_chip()
370 } else if (shared->erasing == chip && shared->writing != chip) { in put_chip()
378 mutex_unlock(&shared->lock); in put_chip()
379 wake_up(&chip->wq); in put_chip()
382 mutex_unlock(&shared->lock); in put_chip()
385 switch (chip->oldstate) { in put_chip()
388 map->pfow_base + PFOW_COMMAND_CODE); in put_chip()
390 map->pfow_base + PFOW_COMMAND_EXECUTE); in put_chip()
391 chip->oldstate = FL_READY; in put_chip()
392 chip->state = FL_ERASING; in put_chip()
398 map->name, chip->oldstate); in put_chip()
400 wake_up(&chip->wq); in put_chip()
407 struct lpddr_private *lpddr = map->fldrv_priv; in do_write_buffer()
414 wbufsize = 1 << lpddr->qinfo->BufSizeShift; in do_write_buffer()
416 mutex_lock(&chip->mutex); in do_write_buffer()
419 mutex_unlock(&chip->mutex); in do_write_buffer()
423 word_gap = (-adr & (map_bankwidth(map)-1)); in do_write_buffer()
425 word_gap = map_bankwidth(map) - word_gap; in do_write_buffer()
426 adr -= word_gap; in do_write_buffer()
431 prog_buf_ofs = map->pfow_base + CMDVAL(map_read(map, in do_write_buffer()
432 map->pfow_base + PFOW_PROGRAM_BUFFER_OFFSET)); in do_write_buffer()
436 int n = map_bankwidth(map) - word_gap; in do_write_buffer()
438 if (n > vec->iov_len - vec_seek) in do_write_buffer()
439 n = vec->iov_len - vec_seek; in do_write_buffer()
447 vec->iov_base + vec_seek, word_gap, n); in do_write_buffer()
449 len -= n; in do_write_buffer()
458 if (vec_seek == vec->iov_len) { in do_write_buffer()
468 chip->state = FL_WRITING; in do_write_buffer()
469 ret = wait_for_ready(map, chip, (1<<lpddr->qinfo->ProgBufferTime)); in do_write_buffer()
472 map->name, ret, adr); in do_write_buffer()
477 mutex_unlock(&chip->mutex); in do_write_buffer()
483 struct map_info *map = mtd->priv; in do_erase_oneblock()
484 struct lpddr_private *lpddr = map->fldrv_priv; in do_erase_oneblock()
485 int chipnum = adr >> lpddr->chipshift; in do_erase_oneblock()
486 struct flchip *chip = &lpddr->chips[chipnum]; in do_erase_oneblock()
489 mutex_lock(&chip->mutex); in do_erase_oneblock()
492 mutex_unlock(&chip->mutex); in do_erase_oneblock()
496 chip->state = FL_ERASING; in do_erase_oneblock()
497 ret = wait_for_ready(map, chip, (1<<lpddr->qinfo->BlockEraseTime)*1000); in do_erase_oneblock()
500 map->name, ret, adr); in do_erase_oneblock()
504 mutex_unlock(&chip->mutex); in do_erase_oneblock()
511 struct map_info *map = mtd->priv; in lpddr_read()
512 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_read()
513 int chipnum = adr >> lpddr->chipshift; in lpddr_read()
514 struct flchip *chip = &lpddr->chips[chipnum]; in lpddr_read()
517 mutex_lock(&chip->mutex); in lpddr_read()
520 mutex_unlock(&chip->mutex); in lpddr_read()
528 mutex_unlock(&chip->mutex); in lpddr_read()
535 struct map_info *map = mtd->priv; in lpddr_point()
536 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_point()
537 int chipnum = adr >> lpddr->chipshift; in lpddr_point()
539 struct flchip *chip = &lpddr->chips[chipnum]; in lpddr_point()
542 if (!map->virt) in lpddr_point()
543 return -EINVAL; in lpddr_point()
546 ofs = adr - (chipnum << lpddr->chipshift); in lpddr_point()
547 *mtdbuf = (void *)map->virt + chip->start + ofs; in lpddr_point()
552 if (chipnum >= lpddr->numchips) in lpddr_point()
557 last_end = chip->start; in lpddr_point()
558 else if (chip->start != last_end) in lpddr_point()
561 if ((len + ofs - 1) >> lpddr->chipshift) in lpddr_point()
562 thislen = (1<<lpddr->chipshift) - ofs; in lpddr_point()
566 mutex_lock(&chip->mutex); in lpddr_point()
568 mutex_unlock(&chip->mutex); in lpddr_point()
572 chip->state = FL_POINT; in lpddr_point()
573 chip->ref_point_counter++; in lpddr_point()
575 len -= thislen; in lpddr_point()
578 last_end += 1 << lpddr->chipshift; in lpddr_point()
580 chip = &lpddr->chips[chipnum]; in lpddr_point()
587 struct map_info *map = mtd->priv; in lpddr_unpoint()
588 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_unpoint()
589 int chipnum = adr >> lpddr->chipshift, err = 0; in lpddr_unpoint()
593 ofs = adr - (chipnum << lpddr->chipshift); in lpddr_unpoint()
599 chip = &lpddr->chips[chipnum]; in lpddr_unpoint()
600 if (chipnum >= lpddr->numchips) in lpddr_unpoint()
603 if ((len + ofs - 1) >> lpddr->chipshift) in lpddr_unpoint()
604 thislen = (1<<lpddr->chipshift) - ofs; in lpddr_unpoint()
608 mutex_lock(&chip->mutex); in lpddr_unpoint()
609 if (chip->state == FL_POINT) { in lpddr_unpoint()
610 chip->ref_point_counter--; in lpddr_unpoint()
611 if (chip->ref_point_counter == 0) in lpddr_unpoint()
612 chip->state = FL_READY; in lpddr_unpoint()
615 "pointed region\n", map->name); in lpddr_unpoint()
616 err = -EINVAL; in lpddr_unpoint()
620 mutex_unlock(&chip->mutex); in lpddr_unpoint()
622 len -= thislen; in lpddr_unpoint()
645 struct map_info *map = mtd->priv; in lpddr_writev()
646 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_writev()
650 int wbufsize = 1 << lpddr->qinfo->BufSizeShift; in lpddr_writev()
659 chipnum = to >> lpddr->chipshift; in lpddr_writev()
666 int size = wbufsize - (ofs & (wbufsize-1)); in lpddr_writev()
671 ret = do_write_buffer(map, &lpddr->chips[chipnum], in lpddr_writev()
678 len -= size; in lpddr_writev()
693 struct map_info *map = mtd->priv; in lpddr_erase()
694 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_erase()
695 int size = 1 << lpddr->qinfo->UniformBlockSizeShift; in lpddr_erase()
697 ofs = instr->addr; in lpddr_erase()
698 len = instr->len; in lpddr_erase()
705 len -= size; in lpddr_erase()
716 struct map_info *map = mtd->priv; in do_xxlock()
717 struct lpddr_private *lpddr = map->fldrv_priv; in do_xxlock()
718 int chipnum = adr >> lpddr->chipshift; in do_xxlock()
719 struct flchip *chip = &lpddr->chips[chipnum]; in do_xxlock()
721 mutex_lock(&chip->mutex); in do_xxlock()
724 mutex_unlock(&chip->mutex); in do_xxlock()
730 chip->state = FL_LOCKING; in do_xxlock()
733 chip->state = FL_UNLOCKING; in do_xxlock()
740 map->name, ret); in do_xxlock()
744 mutex_unlock(&chip->mutex); in do_xxlock()