Lines Matching +full:sleep +full:- +full:map

1 // SPDX-License-Identifier: GPL-2.0-or-later
31 static int get_chip(struct map_info *map, struct flchip *chip, int mode);
32 static int chip_ready(struct map_info *map, struct flchip *chip, int mode);
33 static void put_chip(struct map_info *map, struct flchip *chip);
35 struct mtd_info *lpddr_cmdset(struct map_info *map) in lpddr_cmdset() argument
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()
60 if (map_is_linear(map)) { in lpddr_cmdset()
61 mtd->_point = lpddr_point; in lpddr_cmdset()
62 mtd->_unpoint = lpddr_unpoint; in lpddr_cmdset()
64 mtd->size = 1 << 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()
125 static int wait_for_ready(struct map_info *map, struct flchip *chip, in wait_for_ready() argument
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()
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()
170 /* Someone's suspended the operation: sleep */ 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()
180 /* Suspend has occurred while sleep: reset timeout */ 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()
190 map->name, dsr); in wait_for_ready()
192 ret = -EIO; in wait_for_ready()
194 chip->state = FL_READY; in wait_for_ready()
198 static int get_chip(struct map_info *map, struct flchip *chip, int mode) in get_chip() argument
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()
242 mutex_unlock(&chip->mutex); in get_chip()
243 ret = chip_ready(map, contender, mode); 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()
251 mutex_unlock(&contender->mutex); in get_chip()
254 mutex_lock(&shared->lock); in get_chip()
258 if (chip->state == FL_SYNCING) { in get_chip()
259 put_chip(map, contender); in get_chip()
260 mutex_unlock(&contender->mutex); in get_chip()
263 mutex_unlock(&contender->mutex); in get_chip()
267 Must sleep in such a case. */ 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()
281 shared->writing = chip; in get_chip()
283 shared->erasing = chip; in get_chip()
284 mutex_unlock(&shared->lock); in get_chip()
287 ret = chip_ready(map, chip, mode); in get_chip()
288 if (ret == -EAGAIN) in get_chip()
294 static int chip_ready(struct map_info *map, struct flchip *chip, int mode) in chip_ready() argument
296 struct lpddr_private *lpddr = map->fldrv_priv; in chip_ready()
301 if (FL_SYNCING == mode && FL_READY != chip->oldstate) in chip_ready()
302 goto sleep; in chip_ready()
304 switch (chip->state) { in chip_ready()
310 if (!lpddr->qinfo->SuspEraseSupp || in chip_ready()
312 goto sleep; in chip_ready()
314 map_write(map, CMD(LPDDR_SUSPEND), 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()
318 ret = wait_for_ready(map, chip, 0); in chip_ready()
322 put_chip(map, chip); 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()
337 sleep: 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()
348 static void put_chip(struct map_info *map, struct flchip *chip) in put_chip() argument
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()
362 put_chip(map, loaner); 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()
387 map_write(map, CMD(LPDDR_RESUME), in put_chip()
388 map->pfow_base + PFOW_COMMAND_CODE); in put_chip()
389 map_write(map, CMD(LPDDR_START_EXECUTION), 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()
403 static int do_write_buffer(struct map_info *map, struct flchip *chip, in do_write_buffer() argument
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()
417 ret = get_chip(map, chip, FL_WRITING); 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()
424 words = (len - word_gap + map_bankwidth(map) - 1) / map_bankwidth(map); in do_write_buffer()
426 words--; in do_write_buffer()
428 word_gap = map_bankwidth(map) - word_gap; in do_write_buffer()
429 adr -= word_gap; in do_write_buffer()
430 datum = map_word_ff(map); in do_write_buffer()
434 prog_buf_ofs = map->pfow_base + CMDVAL(map_read(map, in do_write_buffer()
435 map->pfow_base + PFOW_PROGRAM_BUFFER_OFFSET)); in do_write_buffer()
439 int n = map_bankwidth(map) - word_gap; in do_write_buffer()
441 if (n > vec->iov_len - vec_seek) in do_write_buffer()
442 n = vec->iov_len - vec_seek; in do_write_buffer()
446 if (!word_gap && (len < map_bankwidth(map))) in do_write_buffer()
447 datum = map_word_ff(map); in do_write_buffer()
449 datum = map_word_load_partial(map, datum, in do_write_buffer()
450 vec->iov_base + vec_seek, word_gap, n); in do_write_buffer()
452 len -= n; in do_write_buffer()
454 if (!len || word_gap == map_bankwidth(map)) { in do_write_buffer()
455 map_write(map, datum, prog_buf_ofs); in do_write_buffer()
456 prog_buf_ofs += map_bankwidth(map); in do_write_buffer()
461 if (vec_seek == vec->iov_len) { in do_write_buffer()
470 send_pfow_command(map, LPDDR_BUFF_PROGRAM, adr, wbufsize, NULL); in do_write_buffer()
471 chip->state = FL_WRITING; in do_write_buffer()
472 ret = wait_for_ready(map, chip, (1<<lpddr->qinfo->ProgBufferTime)); in do_write_buffer()
475 map->name, ret, adr); in do_write_buffer()
479 out: put_chip(map, chip); in do_write_buffer()
480 mutex_unlock(&chip->mutex); in do_write_buffer()
486 struct map_info *map = mtd->priv; in do_erase_oneblock() local
487 struct lpddr_private *lpddr = map->fldrv_priv; in do_erase_oneblock()
488 int chipnum = adr >> lpddr->chipshift; in do_erase_oneblock()
489 struct flchip *chip = &lpddr->chips[chipnum]; in do_erase_oneblock()
492 mutex_lock(&chip->mutex); in do_erase_oneblock()
493 ret = get_chip(map, chip, FL_ERASING); in do_erase_oneblock()
495 mutex_unlock(&chip->mutex); in do_erase_oneblock()
498 send_pfow_command(map, LPDDR_BLOCK_ERASE, adr, 0, NULL); in do_erase_oneblock()
499 chip->state = FL_ERASING; in do_erase_oneblock()
500 ret = wait_for_ready(map, chip, (1<<lpddr->qinfo->BlockEraseTime)*1000); in do_erase_oneblock()
503 map->name, ret, adr); in do_erase_oneblock()
506 out: put_chip(map, chip); in do_erase_oneblock()
507 mutex_unlock(&chip->mutex); in do_erase_oneblock()
514 struct map_info *map = mtd->priv; in lpddr_read() local
515 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_read()
516 int chipnum = adr >> lpddr->chipshift; in lpddr_read()
517 struct flchip *chip = &lpddr->chips[chipnum]; in lpddr_read()
520 mutex_lock(&chip->mutex); in lpddr_read()
521 ret = get_chip(map, chip, FL_READY); in lpddr_read()
523 mutex_unlock(&chip->mutex); in lpddr_read()
527 map_copy_from(map, buf, adr, len); in lpddr_read()
530 put_chip(map, chip); in lpddr_read()
531 mutex_unlock(&chip->mutex); in lpddr_read()
538 struct map_info *map = mtd->priv; in lpddr_point() local
539 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_point()
540 int chipnum = adr >> lpddr->chipshift; in lpddr_point()
542 struct flchip *chip = &lpddr->chips[chipnum]; in lpddr_point()
545 if (!map->virt) in lpddr_point()
546 return -EINVAL; in lpddr_point()
549 ofs = adr - (chipnum << lpddr->chipshift); in lpddr_point()
550 *mtdbuf = (void *)map->virt + chip->start + ofs; in lpddr_point()
555 if (chipnum >= lpddr->numchips) in lpddr_point()
560 last_end = chip->start; in lpddr_point()
561 else if (chip->start != last_end) in lpddr_point()
564 if ((len + ofs - 1) >> lpddr->chipshift) in lpddr_point()
565 thislen = (1<<lpddr->chipshift) - ofs; in lpddr_point()
569 mutex_lock(&chip->mutex); in lpddr_point()
570 ret = get_chip(map, chip, FL_POINT); in lpddr_point()
571 mutex_unlock(&chip->mutex); in lpddr_point()
575 chip->state = FL_POINT; in lpddr_point()
576 chip->ref_point_counter++; in lpddr_point()
578 len -= thislen; in lpddr_point()
581 last_end += 1 << lpddr->chipshift; in lpddr_point()
583 chip = &lpddr->chips[chipnum]; in lpddr_point()
590 struct map_info *map = mtd->priv; in lpddr_unpoint() local
591 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_unpoint()
592 int chipnum = adr >> lpddr->chipshift, err = 0; in lpddr_unpoint()
596 ofs = adr - (chipnum << lpddr->chipshift); in lpddr_unpoint()
602 chip = &lpddr->chips[chipnum]; in lpddr_unpoint()
603 if (chipnum >= lpddr->numchips) in lpddr_unpoint()
606 if ((len + ofs - 1) >> lpddr->chipshift) in lpddr_unpoint()
607 thislen = (1<<lpddr->chipshift) - ofs; in lpddr_unpoint()
611 mutex_lock(&chip->mutex); in lpddr_unpoint()
612 if (chip->state == FL_POINT) { in lpddr_unpoint()
613 chip->ref_point_counter--; in lpddr_unpoint()
614 if (chip->ref_point_counter == 0) in lpddr_unpoint()
615 chip->state = FL_READY; in lpddr_unpoint()
618 "pointed region\n", map->name); in lpddr_unpoint()
619 err = -EINVAL; in lpddr_unpoint()
622 put_chip(map, chip); in lpddr_unpoint()
623 mutex_unlock(&chip->mutex); in lpddr_unpoint()
625 len -= thislen; in lpddr_unpoint()
648 struct map_info *map = mtd->priv; in lpddr_writev() local
649 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_writev()
653 int wbufsize = 1 << lpddr->qinfo->BufSizeShift; in lpddr_writev()
662 chipnum = to >> lpddr->chipshift; in lpddr_writev()
669 int size = wbufsize - (ofs & (wbufsize-1)); in lpddr_writev()
674 ret = do_write_buffer(map, &lpddr->chips[chipnum], in lpddr_writev()
681 len -= size; in lpddr_writev()
696 struct map_info *map = mtd->priv; in lpddr_erase() local
697 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_erase()
698 int size = 1 << lpddr->qinfo->UniformBlockSizeShift; in lpddr_erase()
700 ofs = instr->addr; in lpddr_erase()
701 len = instr->len; in lpddr_erase()
708 len -= size; in lpddr_erase()
719 struct map_info *map = mtd->priv; in do_xxlock() local
720 struct lpddr_private *lpddr = map->fldrv_priv; in do_xxlock()
721 int chipnum = adr >> lpddr->chipshift; in do_xxlock()
722 struct flchip *chip = &lpddr->chips[chipnum]; in do_xxlock()
724 mutex_lock(&chip->mutex); in do_xxlock()
725 ret = get_chip(map, chip, FL_LOCKING); in do_xxlock()
727 mutex_unlock(&chip->mutex); in do_xxlock()
732 send_pfow_command(map, LPDDR_LOCK_BLOCK, adr, adr + len, NULL); in do_xxlock()
733 chip->state = FL_LOCKING; in do_xxlock()
735 send_pfow_command(map, LPDDR_UNLOCK_BLOCK, adr, adr + len, NULL); in do_xxlock()
736 chip->state = FL_UNLOCKING; in do_xxlock()
740 ret = wait_for_ready(map, chip, 1); in do_xxlock()
743 map->name, ret); in do_xxlock()
746 out: put_chip(map, chip); in do_xxlock()
747 mutex_unlock(&chip->mutex); in do_xxlock()