Lines Matching +full:sleep +full:- +full:map
21 * 02110-1301, USA.
44 static int get_chip(struct map_info *map, struct flchip *chip, int mode);
45 static int chip_ready(struct map_info *map, struct flchip *chip, int mode);
46 static void put_chip(struct map_info *map, struct flchip *chip);
48 struct mtd_info *lpddr_cmdset(struct map_info *map) in lpddr_cmdset() argument
50 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_cmdset()
60 mtd->priv = map; in lpddr_cmdset()
61 mtd->type = MTD_NORFLASH; in lpddr_cmdset()
64 mtd->_read = lpddr_read; in lpddr_cmdset()
65 mtd->type = MTD_NORFLASH; in lpddr_cmdset()
66 mtd->flags = MTD_CAP_NORFLASH; in lpddr_cmdset()
67 mtd->flags &= ~MTD_BIT_WRITEABLE; in lpddr_cmdset()
68 mtd->_erase = lpddr_erase; in lpddr_cmdset()
69 mtd->_write = lpddr_write_buffers; in lpddr_cmdset()
70 mtd->_writev = lpddr_writev; in lpddr_cmdset()
71 mtd->_lock = lpddr_lock; in lpddr_cmdset()
72 mtd->_unlock = lpddr_unlock; in lpddr_cmdset()
73 if (map_is_linear(map)) { in lpddr_cmdset()
74 mtd->_point = lpddr_point; in lpddr_cmdset()
75 mtd->_unpoint = lpddr_unpoint; in lpddr_cmdset()
77 mtd->size = 1 << lpddr->qinfo->DevSizeShift; in lpddr_cmdset()
78 mtd->erasesize = 1 << lpddr->qinfo->UniformBlockSizeShift; in lpddr_cmdset()
79 mtd->writesize = 1 << lpddr->qinfo->BufSizeShift; in lpddr_cmdset()
81 shared = kmalloc_array(lpddr->numchips, sizeof(struct flchip_shared), in lpddr_cmdset()
88 chip = &lpddr->chips[0]; in lpddr_cmdset()
89 numchips = lpddr->numchips / lpddr->qinfo->HWPartsNum; in lpddr_cmdset()
93 for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) { in lpddr_cmdset()
94 *chip = lpddr->chips[i]; in lpddr_cmdset()
95 chip->start += j << lpddr->chipshift; in lpddr_cmdset()
96 chip->oldstate = chip->state = FL_READY; in lpddr_cmdset()
97 chip->priv = &shared[i]; in lpddr_cmdset()
100 init_waitqueue_head(&chip->wq); in lpddr_cmdset()
101 mutex_init(&chip->mutex); in lpddr_cmdset()
110 static int wait_for_ready(struct map_info *map, struct flchip *chip, in wait_for_ready() argument
115 flstate_t chip_state = chip->state; in wait_for_ready()
126 dsr = CMDVAL(map_read(map, map->pfow_base + PFOW_DSR)); in wait_for_ready()
131 map->name, chip_state); in wait_for_ready()
132 ret = -ETIME; in wait_for_ready()
137 mutex_unlock(&chip->mutex); in wait_for_ready()
145 timeo -= sleep_time; in wait_for_ready()
150 timeo--; in wait_for_ready()
152 mutex_lock(&chip->mutex); in wait_for_ready()
154 while (chip->state != chip_state) { in wait_for_ready()
155 /* Someone's suspended the operation: sleep */ in wait_for_ready()
158 add_wait_queue(&chip->wq, &wait); in wait_for_ready()
159 mutex_unlock(&chip->mutex); in wait_for_ready()
161 remove_wait_queue(&chip->wq, &wait); in wait_for_ready()
162 mutex_lock(&chip->mutex); in wait_for_ready()
164 if (chip->erase_suspended || chip->write_suspended) { in wait_for_ready()
165 /* Suspend has occurred while sleep: reset timeout */ in wait_for_ready()
167 chip->erase_suspended = chip->write_suspended = 0; in wait_for_ready()
173 map_write(map, CMD(~(DSR_ERR)), map->pfow_base + PFOW_DSR); in wait_for_ready()
175 map->name, dsr); in wait_for_ready()
177 ret = -EIO; in wait_for_ready()
179 chip->state = FL_READY; in wait_for_ready()
183 static int get_chip(struct map_info *map, struct flchip *chip, int mode) in get_chip() argument
189 if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING) in get_chip()
190 && chip->state != FL_SYNCING) { in get_chip()
199 * - any write operation must own shared->writing. in get_chip()
201 * - any erase operation must own _both_ shared->writing and in get_chip()
202 * shared->erasing. in get_chip()
204 * - contension arbitration is handled in the owner's context. in get_chip()
209 struct flchip_shared *shared = chip->priv; in get_chip()
211 mutex_lock(&shared->lock); in get_chip()
212 contender = shared->writing; in get_chip()
220 * it'll happily send us to sleep. In any case, when in get_chip()
223 ret = mutex_trylock(&contender->mutex); in get_chip()
224 mutex_unlock(&shared->lock); in get_chip()
227 mutex_unlock(&chip->mutex); in get_chip()
228 ret = chip_ready(map, contender, mode); in get_chip()
229 mutex_lock(&chip->mutex); in get_chip()
231 if (ret == -EAGAIN) { in get_chip()
232 mutex_unlock(&contender->mutex); in get_chip()
236 mutex_unlock(&contender->mutex); in get_chip()
239 mutex_lock(&shared->lock); in get_chip()
243 if (chip->state == FL_SYNCING) { in get_chip()
244 put_chip(map, contender); in get_chip()
245 mutex_unlock(&contender->mutex); in get_chip()
248 mutex_unlock(&contender->mutex); in get_chip()
252 Must sleep in such a case. */ in get_chip()
253 if (mode == FL_ERASING && shared->erasing in get_chip()
254 && shared->erasing->oldstate == FL_ERASING) { in get_chip()
255 mutex_unlock(&shared->lock); in get_chip()
257 add_wait_queue(&chip->wq, &wait); in get_chip()
258 mutex_unlock(&chip->mutex); in get_chip()
260 remove_wait_queue(&chip->wq, &wait); in get_chip()
261 mutex_lock(&chip->mutex); in get_chip()
266 shared->writing = chip; in get_chip()
268 shared->erasing = chip; in get_chip()
269 mutex_unlock(&shared->lock); in get_chip()
272 ret = chip_ready(map, chip, mode); in get_chip()
273 if (ret == -EAGAIN) in get_chip()
279 static int chip_ready(struct map_info *map, struct flchip *chip, int mode) in chip_ready() argument
281 struct lpddr_private *lpddr = map->fldrv_priv; in chip_ready()
286 if (FL_SYNCING == mode && FL_READY != chip->oldstate) in chip_ready()
287 goto sleep; in chip_ready()
289 switch (chip->state) { in chip_ready()
295 if (!lpddr->qinfo->SuspEraseSupp || in chip_ready()
297 goto sleep; in chip_ready()
299 map_write(map, CMD(LPDDR_SUSPEND), in chip_ready()
300 map->pfow_base + PFOW_PROGRAM_ERASE_SUSPEND); in chip_ready()
301 chip->oldstate = FL_ERASING; in chip_ready()
302 chip->state = FL_ERASE_SUSPENDING; in chip_ready()
303 ret = wait_for_ready(map, chip, 0); in chip_ready()
307 put_chip(map, chip); in chip_ready()
309 "State may be wrong \n", map->name); in chip_ready()
310 return -EIO; in chip_ready()
312 chip->erase_suspended = 1; in chip_ready()
313 chip->state = FL_READY; in chip_ready()
318 if (mode == FL_READY && chip->oldstate == FL_READY) in chip_ready()
322 sleep: in chip_ready()
324 add_wait_queue(&chip->wq, &wait); in chip_ready()
325 mutex_unlock(&chip->mutex); in chip_ready()
327 remove_wait_queue(&chip->wq, &wait); in chip_ready()
328 mutex_lock(&chip->mutex); in chip_ready()
329 return -EAGAIN; in chip_ready()
333 static void put_chip(struct map_info *map, struct flchip *chip) in put_chip() argument
335 if (chip->priv) { in put_chip()
336 struct flchip_shared *shared = chip->priv; in put_chip()
337 mutex_lock(&shared->lock); in put_chip()
338 if (shared->writing == chip && chip->oldstate == FL_READY) { in put_chip()
340 shared->writing = shared->erasing; in put_chip()
341 if (shared->writing && shared->writing != chip) { in put_chip()
343 struct flchip *loaner = shared->writing; in put_chip()
344 mutex_lock(&loaner->mutex); in put_chip()
345 mutex_unlock(&shared->lock); in put_chip()
346 mutex_unlock(&chip->mutex); in put_chip()
347 put_chip(map, loaner); in put_chip()
348 mutex_lock(&chip->mutex); in put_chip()
349 mutex_unlock(&loaner->mutex); in put_chip()
350 wake_up(&chip->wq); in put_chip()
353 shared->erasing = NULL; in put_chip()
354 shared->writing = NULL; in put_chip()
355 } else if (shared->erasing == chip && shared->writing != chip) { in put_chip()
363 mutex_unlock(&shared->lock); in put_chip()
364 wake_up(&chip->wq); in put_chip()
367 mutex_unlock(&shared->lock); in put_chip()
370 switch (chip->oldstate) { in put_chip()
372 map_write(map, CMD(LPDDR_RESUME), in put_chip()
373 map->pfow_base + PFOW_COMMAND_CODE); in put_chip()
374 map_write(map, CMD(LPDDR_START_EXECUTION), in put_chip()
375 map->pfow_base + PFOW_COMMAND_EXECUTE); in put_chip()
376 chip->oldstate = FL_READY; in put_chip()
377 chip->state = FL_ERASING; in put_chip()
383 map->name, chip->oldstate); in put_chip()
385 wake_up(&chip->wq); in put_chip()
388 static int do_write_buffer(struct map_info *map, struct flchip *chip, in do_write_buffer() argument
392 struct lpddr_private *lpddr = map->fldrv_priv; in do_write_buffer()
399 wbufsize = 1 << lpddr->qinfo->BufSizeShift; in do_write_buffer()
401 mutex_lock(&chip->mutex); in do_write_buffer()
402 ret = get_chip(map, chip, FL_WRITING); in do_write_buffer()
404 mutex_unlock(&chip->mutex); in do_write_buffer()
408 word_gap = (-adr & (map_bankwidth(map)-1)); in do_write_buffer()
409 words = (len - word_gap + map_bankwidth(map) - 1) / map_bankwidth(map); in do_write_buffer()
411 words--; in do_write_buffer()
413 word_gap = map_bankwidth(map) - word_gap; in do_write_buffer()
414 adr -= word_gap; in do_write_buffer()
415 datum = map_word_ff(map); in do_write_buffer()
419 prog_buf_ofs = map->pfow_base + CMDVAL(map_read(map, in do_write_buffer()
420 map->pfow_base + PFOW_PROGRAM_BUFFER_OFFSET)); in do_write_buffer()
424 int n = map_bankwidth(map) - word_gap; in do_write_buffer()
426 if (n > vec->iov_len - vec_seek) in do_write_buffer()
427 n = vec->iov_len - vec_seek; in do_write_buffer()
431 if (!word_gap && (len < map_bankwidth(map))) in do_write_buffer()
432 datum = map_word_ff(map); in do_write_buffer()
434 datum = map_word_load_partial(map, datum, in do_write_buffer()
435 vec->iov_base + vec_seek, word_gap, n); in do_write_buffer()
437 len -= n; in do_write_buffer()
439 if (!len || word_gap == map_bankwidth(map)) { in do_write_buffer()
440 map_write(map, datum, prog_buf_ofs); in do_write_buffer()
441 prog_buf_ofs += map_bankwidth(map); in do_write_buffer()
446 if (vec_seek == vec->iov_len) { in do_write_buffer()
455 send_pfow_command(map, LPDDR_BUFF_PROGRAM, adr, wbufsize, NULL); in do_write_buffer()
456 chip->state = FL_WRITING; in do_write_buffer()
457 ret = wait_for_ready(map, chip, (1<<lpddr->qinfo->ProgBufferTime)); in do_write_buffer()
460 map->name, ret, adr); in do_write_buffer()
464 out: put_chip(map, chip); in do_write_buffer()
465 mutex_unlock(&chip->mutex); in do_write_buffer()
471 struct map_info *map = mtd->priv; in do_erase_oneblock() local
472 struct lpddr_private *lpddr = map->fldrv_priv; in do_erase_oneblock()
473 int chipnum = adr >> lpddr->chipshift; in do_erase_oneblock()
474 struct flchip *chip = &lpddr->chips[chipnum]; in do_erase_oneblock()
477 mutex_lock(&chip->mutex); in do_erase_oneblock()
478 ret = get_chip(map, chip, FL_ERASING); in do_erase_oneblock()
480 mutex_unlock(&chip->mutex); in do_erase_oneblock()
483 send_pfow_command(map, LPDDR_BLOCK_ERASE, adr, 0, NULL); in do_erase_oneblock()
484 chip->state = FL_ERASING; in do_erase_oneblock()
485 ret = wait_for_ready(map, chip, (1<<lpddr->qinfo->BlockEraseTime)*1000); in do_erase_oneblock()
488 map->name, ret, adr); in do_erase_oneblock()
491 out: put_chip(map, chip); in do_erase_oneblock()
492 mutex_unlock(&chip->mutex); in do_erase_oneblock()
499 struct map_info *map = mtd->priv; in lpddr_read() local
500 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_read()
501 int chipnum = adr >> lpddr->chipshift; in lpddr_read()
502 struct flchip *chip = &lpddr->chips[chipnum]; in lpddr_read()
505 mutex_lock(&chip->mutex); in lpddr_read()
506 ret = get_chip(map, chip, FL_READY); in lpddr_read()
508 mutex_unlock(&chip->mutex); in lpddr_read()
512 map_copy_from(map, buf, adr, len); in lpddr_read()
515 put_chip(map, chip); in lpddr_read()
516 mutex_unlock(&chip->mutex); in lpddr_read()
523 struct map_info *map = mtd->priv; in lpddr_point() local
524 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_point()
525 int chipnum = adr >> lpddr->chipshift; in lpddr_point()
527 struct flchip *chip = &lpddr->chips[chipnum]; in lpddr_point()
530 if (!map->virt) in lpddr_point()
531 return -EINVAL; in lpddr_point()
534 ofs = adr - (chipnum << lpddr->chipshift); in lpddr_point()
535 *mtdbuf = (void *)map->virt + chip->start + ofs; in lpddr_point()
540 if (chipnum >= lpddr->numchips) in lpddr_point()
545 last_end = chip->start; in lpddr_point()
546 else if (chip->start != last_end) in lpddr_point()
549 if ((len + ofs - 1) >> lpddr->chipshift) in lpddr_point()
550 thislen = (1<<lpddr->chipshift) - ofs; in lpddr_point()
554 mutex_lock(&chip->mutex); in lpddr_point()
555 ret = get_chip(map, chip, FL_POINT); in lpddr_point()
556 mutex_unlock(&chip->mutex); in lpddr_point()
560 chip->state = FL_POINT; in lpddr_point()
561 chip->ref_point_counter++; in lpddr_point()
563 len -= thislen; in lpddr_point()
566 last_end += 1 << lpddr->chipshift; in lpddr_point()
568 chip = &lpddr->chips[chipnum]; in lpddr_point()
575 struct map_info *map = mtd->priv; in lpddr_unpoint() local
576 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_unpoint()
577 int chipnum = adr >> lpddr->chipshift, err = 0; in lpddr_unpoint()
581 ofs = adr - (chipnum << lpddr->chipshift); in lpddr_unpoint()
587 chip = &lpddr->chips[chipnum]; in lpddr_unpoint()
588 if (chipnum >= lpddr->numchips) in lpddr_unpoint()
591 if ((len + ofs - 1) >> lpddr->chipshift) in lpddr_unpoint()
592 thislen = (1<<lpddr->chipshift) - ofs; in lpddr_unpoint()
596 mutex_lock(&chip->mutex); in lpddr_unpoint()
597 if (chip->state == FL_POINT) { in lpddr_unpoint()
598 chip->ref_point_counter--; in lpddr_unpoint()
599 if (chip->ref_point_counter == 0) in lpddr_unpoint()
600 chip->state = FL_READY; in lpddr_unpoint()
603 "pointed region\n", map->name); in lpddr_unpoint()
604 err = -EINVAL; in lpddr_unpoint()
607 put_chip(map, chip); in lpddr_unpoint()
608 mutex_unlock(&chip->mutex); in lpddr_unpoint()
610 len -= thislen; in lpddr_unpoint()
633 struct map_info *map = mtd->priv; in lpddr_writev() local
634 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_writev()
638 int wbufsize = 1 << lpddr->qinfo->BufSizeShift; in lpddr_writev()
647 chipnum = to >> lpddr->chipshift; in lpddr_writev()
654 int size = wbufsize - (ofs & (wbufsize-1)); in lpddr_writev()
659 ret = do_write_buffer(map, &lpddr->chips[chipnum], in lpddr_writev()
666 len -= size; in lpddr_writev()
681 struct map_info *map = mtd->priv; in lpddr_erase() local
682 struct lpddr_private *lpddr = map->fldrv_priv; in lpddr_erase()
683 int size = 1 << lpddr->qinfo->UniformBlockSizeShift; in lpddr_erase()
685 ofs = instr->addr; in lpddr_erase()
686 len = instr->len; in lpddr_erase()
693 len -= size; in lpddr_erase()
704 struct map_info *map = mtd->priv; in do_xxlock() local
705 struct lpddr_private *lpddr = map->fldrv_priv; in do_xxlock()
706 int chipnum = adr >> lpddr->chipshift; in do_xxlock()
707 struct flchip *chip = &lpddr->chips[chipnum]; in do_xxlock()
709 mutex_lock(&chip->mutex); in do_xxlock()
710 ret = get_chip(map, chip, FL_LOCKING); in do_xxlock()
712 mutex_unlock(&chip->mutex); in do_xxlock()
717 send_pfow_command(map, LPDDR_LOCK_BLOCK, adr, adr + len, NULL); in do_xxlock()
718 chip->state = FL_LOCKING; in do_xxlock()
720 send_pfow_command(map, LPDDR_UNLOCK_BLOCK, adr, adr + len, NULL); in do_xxlock()
721 chip->state = FL_UNLOCKING; in do_xxlock()
725 ret = wait_for_ready(map, chip, 1); in do_xxlock()
728 map->name, ret); in do_xxlock()
731 out: put_chip(map, chip); in do_xxlock()
732 mutex_unlock(&chip->mutex); in do_xxlock()