0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/mtd/pfow.h>
0015 #include <linux/mtd/qinfo.h>
0016 #include <linux/slab.h>
0017 #include <linux/module.h>
0018
0019 static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len,
0020 size_t *retlen, u_char *buf);
0021 static int lpddr_write_buffers(struct mtd_info *mtd, loff_t to,
0022 size_t len, size_t *retlen, const u_char *buf);
0023 static int lpddr_writev(struct mtd_info *mtd, const struct kvec *vecs,
0024 unsigned long count, loff_t to, size_t *retlen);
0025 static int lpddr_erase(struct mtd_info *mtd, struct erase_info *instr);
0026 static int lpddr_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
0027 static int lpddr_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
0028 static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,
0029 size_t *retlen, void **mtdbuf, resource_size_t *phys);
0030 static int lpddr_unpoint(struct mtd_info *mtd, loff_t adr, size_t len);
0031 static int get_chip(struct map_info *map, struct flchip *chip, int mode);
0032 static int chip_ready(struct map_info *map, struct flchip *chip, int mode);
0033 static void put_chip(struct map_info *map, struct flchip *chip);
0034
0035 struct mtd_info *lpddr_cmdset(struct map_info *map)
0036 {
0037 struct lpddr_private *lpddr = map->fldrv_priv;
0038 struct flchip_shared *shared;
0039 struct flchip *chip;
0040 struct mtd_info *mtd;
0041 int numchips;
0042 int i, j;
0043
0044 mtd = kzalloc(sizeof(*mtd), GFP_KERNEL);
0045 if (!mtd)
0046 return NULL;
0047 mtd->priv = map;
0048 mtd->type = MTD_NORFLASH;
0049
0050
0051 mtd->_read = lpddr_read;
0052 mtd->type = MTD_NORFLASH;
0053 mtd->flags = MTD_CAP_NORFLASH;
0054 mtd->flags &= ~MTD_BIT_WRITEABLE;
0055 mtd->_erase = lpddr_erase;
0056 mtd->_write = lpddr_write_buffers;
0057 mtd->_writev = lpddr_writev;
0058 mtd->_lock = lpddr_lock;
0059 mtd->_unlock = lpddr_unlock;
0060 if (map_is_linear(map)) {
0061 mtd->_point = lpddr_point;
0062 mtd->_unpoint = lpddr_unpoint;
0063 }
0064 mtd->size = 1 << lpddr->qinfo->DevSizeShift;
0065 mtd->erasesize = 1 << lpddr->qinfo->UniformBlockSizeShift;
0066 mtd->writesize = 1 << lpddr->qinfo->BufSizeShift;
0067
0068 shared = kmalloc_array(lpddr->numchips, sizeof(struct flchip_shared),
0069 GFP_KERNEL);
0070 if (!shared) {
0071 kfree(mtd);
0072 return NULL;
0073 }
0074
0075 chip = &lpddr->chips[0];
0076 numchips = lpddr->numchips / lpddr->qinfo->HWPartsNum;
0077 for (i = 0; i < numchips; i++) {
0078 shared[i].writing = shared[i].erasing = NULL;
0079 mutex_init(&shared[i].lock);
0080 for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) {
0081 *chip = lpddr->chips[i];
0082 chip->start += j << lpddr->chipshift;
0083 chip->oldstate = chip->state = FL_READY;
0084 chip->priv = &shared[i];
0085
0086
0087 init_waitqueue_head(&chip->wq);
0088 mutex_init(&chip->mutex);
0089 chip++;
0090 }
0091 }
0092
0093 return mtd;
0094 }
0095 EXPORT_SYMBOL(lpddr_cmdset);
0096
0097 static void print_drs_error(unsigned int dsr)
0098 {
0099 int prog_status = (dsr & DSR_RPS) >> 8;
0100
0101 if (!(dsr & DSR_AVAILABLE))
0102 pr_notice("DSR.15: (0) Device not Available\n");
0103 if ((prog_status & 0x03) == 0x03)
0104 pr_notice("DSR.9,8: (11) Attempt to program invalid half with 41h command\n");
0105 else if (prog_status & 0x02)
0106 pr_notice("DSR.9,8: (10) Object Mode Program attempt in region with Control Mode data\n");
0107 else if (prog_status & 0x01)
0108 pr_notice("DSR.9,8: (01) Program attempt in region with Object Mode data\n");
0109 if (!(dsr & DSR_READY_STATUS))
0110 pr_notice("DSR.7: (0) Device is Busy\n");
0111 if (dsr & DSR_ESS)
0112 pr_notice("DSR.6: (1) Erase Suspended\n");
0113 if (dsr & DSR_ERASE_STATUS)
0114 pr_notice("DSR.5: (1) Erase/Blank check error\n");
0115 if (dsr & DSR_PROGRAM_STATUS)
0116 pr_notice("DSR.4: (1) Program Error\n");
0117 if (dsr & DSR_VPPS)
0118 pr_notice("DSR.3: (1) Vpp low detect, operation aborted\n");
0119 if (dsr & DSR_PSS)
0120 pr_notice("DSR.2: (1) Program suspended\n");
0121 if (dsr & DSR_DPS)
0122 pr_notice("DSR.1: (1) Aborted Erase/Program attempt on locked block\n");
0123 }
0124
0125 static int wait_for_ready(struct map_info *map, struct flchip *chip,
0126 unsigned int chip_op_time)
0127 {
0128 unsigned int timeo, reset_timeo, sleep_time;
0129 unsigned int dsr;
0130 flstate_t chip_state = chip->state;
0131 int ret = 0;
0132
0133
0134 timeo = chip_op_time * 8;
0135 if (!timeo)
0136 timeo = 500000;
0137 reset_timeo = timeo;
0138 sleep_time = chip_op_time / 2;
0139
0140 for (;;) {
0141 dsr = CMDVAL(map_read(map, map->pfow_base + PFOW_DSR));
0142 if (dsr & DSR_READY_STATUS)
0143 break;
0144 if (!timeo) {
0145 printk(KERN_ERR "%s: Flash timeout error state %d \n",
0146 map->name, chip_state);
0147 ret = -ETIME;
0148 break;
0149 }
0150
0151
0152 mutex_unlock(&chip->mutex);
0153 if (sleep_time >= 1000000/HZ) {
0154
0155
0156
0157
0158
0159 msleep(sleep_time/1000);
0160 timeo -= sleep_time;
0161 sleep_time = 1000000/HZ;
0162 } else {
0163 udelay(1);
0164 cond_resched();
0165 timeo--;
0166 }
0167 mutex_lock(&chip->mutex);
0168
0169 while (chip->state != chip_state) {
0170
0171 DECLARE_WAITQUEUE(wait, current);
0172 set_current_state(TASK_UNINTERRUPTIBLE);
0173 add_wait_queue(&chip->wq, &wait);
0174 mutex_unlock(&chip->mutex);
0175 schedule();
0176 remove_wait_queue(&chip->wq, &wait);
0177 mutex_lock(&chip->mutex);
0178 }
0179 if (chip->erase_suspended || chip->write_suspended) {
0180
0181 timeo = reset_timeo;
0182 chip->erase_suspended = chip->write_suspended = 0;
0183 }
0184 }
0185
0186 if (dsr & DSR_ERR) {
0187
0188 map_write(map, CMD(~(DSR_ERR)), map->pfow_base + PFOW_DSR);
0189 printk(KERN_WARNING"%s: Bad status on wait: 0x%x \n",
0190 map->name, dsr);
0191 print_drs_error(dsr);
0192 ret = -EIO;
0193 }
0194 chip->state = FL_READY;
0195 return ret;
0196 }
0197
0198 static int get_chip(struct map_info *map, struct flchip *chip, int mode)
0199 {
0200 int ret;
0201 DECLARE_WAITQUEUE(wait, current);
0202
0203 retry:
0204 if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING)
0205 && chip->state != FL_SYNCING) {
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224 struct flchip_shared *shared = chip->priv;
0225 struct flchip *contender;
0226 mutex_lock(&shared->lock);
0227 contender = shared->writing;
0228 if (contender && contender != chip) {
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238 ret = mutex_trylock(&contender->mutex);
0239 mutex_unlock(&shared->lock);
0240 if (!ret)
0241 goto retry;
0242 mutex_unlock(&chip->mutex);
0243 ret = chip_ready(map, contender, mode);
0244 mutex_lock(&chip->mutex);
0245
0246 if (ret == -EAGAIN) {
0247 mutex_unlock(&contender->mutex);
0248 goto retry;
0249 }
0250 if (ret) {
0251 mutex_unlock(&contender->mutex);
0252 return ret;
0253 }
0254 mutex_lock(&shared->lock);
0255
0256
0257
0258 if (chip->state == FL_SYNCING) {
0259 put_chip(map, contender);
0260 mutex_unlock(&contender->mutex);
0261 goto retry;
0262 }
0263 mutex_unlock(&contender->mutex);
0264 }
0265
0266
0267
0268 if (mode == FL_ERASING && shared->erasing
0269 && shared->erasing->oldstate == FL_ERASING) {
0270 mutex_unlock(&shared->lock);
0271 set_current_state(TASK_UNINTERRUPTIBLE);
0272 add_wait_queue(&chip->wq, &wait);
0273 mutex_unlock(&chip->mutex);
0274 schedule();
0275 remove_wait_queue(&chip->wq, &wait);
0276 mutex_lock(&chip->mutex);
0277 goto retry;
0278 }
0279
0280
0281 shared->writing = chip;
0282 if (mode == FL_ERASING)
0283 shared->erasing = chip;
0284 mutex_unlock(&shared->lock);
0285 }
0286
0287 ret = chip_ready(map, chip, mode);
0288 if (ret == -EAGAIN)
0289 goto retry;
0290
0291 return ret;
0292 }
0293
0294 static int chip_ready(struct map_info *map, struct flchip *chip, int mode)
0295 {
0296 struct lpddr_private *lpddr = map->fldrv_priv;
0297 int ret = 0;
0298 DECLARE_WAITQUEUE(wait, current);
0299
0300
0301 if (FL_SYNCING == mode && FL_READY != chip->oldstate)
0302 goto sleep;
0303
0304 switch (chip->state) {
0305 case FL_READY:
0306 case FL_JEDEC_QUERY:
0307 return 0;
0308
0309 case FL_ERASING:
0310 if (!lpddr->qinfo->SuspEraseSupp ||
0311 !(mode == FL_READY || mode == FL_POINT))
0312 goto sleep;
0313
0314 map_write(map, CMD(LPDDR_SUSPEND),
0315 map->pfow_base + PFOW_PROGRAM_ERASE_SUSPEND);
0316 chip->oldstate = FL_ERASING;
0317 chip->state = FL_ERASE_SUSPENDING;
0318 ret = wait_for_ready(map, chip, 0);
0319 if (ret) {
0320
0321
0322 put_chip(map, chip);
0323 printk(KERN_ERR "%s: suspend operation failed."
0324 "State may be wrong \n", map->name);
0325 return -EIO;
0326 }
0327 chip->erase_suspended = 1;
0328 chip->state = FL_READY;
0329 return 0;
0330
0331 case FL_POINT:
0332
0333 if (mode == FL_READY && chip->oldstate == FL_READY)
0334 return 0;
0335 fallthrough;
0336 default:
0337 sleep:
0338 set_current_state(TASK_UNINTERRUPTIBLE);
0339 add_wait_queue(&chip->wq, &wait);
0340 mutex_unlock(&chip->mutex);
0341 schedule();
0342 remove_wait_queue(&chip->wq, &wait);
0343 mutex_lock(&chip->mutex);
0344 return -EAGAIN;
0345 }
0346 }
0347
0348 static void put_chip(struct map_info *map, struct flchip *chip)
0349 {
0350 if (chip->priv) {
0351 struct flchip_shared *shared = chip->priv;
0352 mutex_lock(&shared->lock);
0353 if (shared->writing == chip && chip->oldstate == FL_READY) {
0354
0355 shared->writing = shared->erasing;
0356 if (shared->writing && shared->writing != chip) {
0357
0358 struct flchip *loaner = shared->writing;
0359 mutex_lock(&loaner->mutex);
0360 mutex_unlock(&shared->lock);
0361 mutex_unlock(&chip->mutex);
0362 put_chip(map, loaner);
0363 mutex_lock(&chip->mutex);
0364 mutex_unlock(&loaner->mutex);
0365 wake_up(&chip->wq);
0366 return;
0367 }
0368 shared->erasing = NULL;
0369 shared->writing = NULL;
0370 } else if (shared->erasing == chip && shared->writing != chip) {
0371
0372
0373
0374
0375
0376
0377
0378 mutex_unlock(&shared->lock);
0379 wake_up(&chip->wq);
0380 return;
0381 }
0382 mutex_unlock(&shared->lock);
0383 }
0384
0385 switch (chip->oldstate) {
0386 case FL_ERASING:
0387 map_write(map, CMD(LPDDR_RESUME),
0388 map->pfow_base + PFOW_COMMAND_CODE);
0389 map_write(map, CMD(LPDDR_START_EXECUTION),
0390 map->pfow_base + PFOW_COMMAND_EXECUTE);
0391 chip->oldstate = FL_READY;
0392 chip->state = FL_ERASING;
0393 break;
0394 case FL_READY:
0395 break;
0396 default:
0397 printk(KERN_ERR "%s: put_chip() called with oldstate %d!\n",
0398 map->name, chip->oldstate);
0399 }
0400 wake_up(&chip->wq);
0401 }
0402
0403 static int do_write_buffer(struct map_info *map, struct flchip *chip,
0404 unsigned long adr, const struct kvec **pvec,
0405 unsigned long *pvec_seek, int len)
0406 {
0407 struct lpddr_private *lpddr = map->fldrv_priv;
0408 map_word datum;
0409 int ret, wbufsize, word_gap, words;
0410 const struct kvec *vec;
0411 unsigned long vec_seek;
0412 unsigned long prog_buf_ofs;
0413
0414 wbufsize = 1 << lpddr->qinfo->BufSizeShift;
0415
0416 mutex_lock(&chip->mutex);
0417 ret = get_chip(map, chip, FL_WRITING);
0418 if (ret) {
0419 mutex_unlock(&chip->mutex);
0420 return ret;
0421 }
0422
0423 word_gap = (-adr & (map_bankwidth(map)-1));
0424 words = (len - word_gap + map_bankwidth(map) - 1) / map_bankwidth(map);
0425 if (!word_gap) {
0426 words--;
0427 } else {
0428 word_gap = map_bankwidth(map) - word_gap;
0429 adr -= word_gap;
0430 datum = map_word_ff(map);
0431 }
0432
0433
0434 prog_buf_ofs = map->pfow_base + CMDVAL(map_read(map,
0435 map->pfow_base + PFOW_PROGRAM_BUFFER_OFFSET));
0436 vec = *pvec;
0437 vec_seek = *pvec_seek;
0438 do {
0439 int n = map_bankwidth(map) - word_gap;
0440
0441 if (n > vec->iov_len - vec_seek)
0442 n = vec->iov_len - vec_seek;
0443 if (n > len)
0444 n = len;
0445
0446 if (!word_gap && (len < map_bankwidth(map)))
0447 datum = map_word_ff(map);
0448
0449 datum = map_word_load_partial(map, datum,
0450 vec->iov_base + vec_seek, word_gap, n);
0451
0452 len -= n;
0453 word_gap += n;
0454 if (!len || word_gap == map_bankwidth(map)) {
0455 map_write(map, datum, prog_buf_ofs);
0456 prog_buf_ofs += map_bankwidth(map);
0457 word_gap = 0;
0458 }
0459
0460 vec_seek += n;
0461 if (vec_seek == vec->iov_len) {
0462 vec++;
0463 vec_seek = 0;
0464 }
0465 } while (len);
0466 *pvec = vec;
0467 *pvec_seek = vec_seek;
0468
0469
0470 send_pfow_command(map, LPDDR_BUFF_PROGRAM, adr, wbufsize, NULL);
0471 chip->state = FL_WRITING;
0472 ret = wait_for_ready(map, chip, (1<<lpddr->qinfo->ProgBufferTime));
0473 if (ret) {
0474 printk(KERN_WARNING"%s Buffer program error: %d at %lx; \n",
0475 map->name, ret, adr);
0476 goto out;
0477 }
0478
0479 out: put_chip(map, chip);
0480 mutex_unlock(&chip->mutex);
0481 return ret;
0482 }
0483
0484 static int do_erase_oneblock(struct mtd_info *mtd, loff_t adr)
0485 {
0486 struct map_info *map = mtd->priv;
0487 struct lpddr_private *lpddr = map->fldrv_priv;
0488 int chipnum = adr >> lpddr->chipshift;
0489 struct flchip *chip = &lpddr->chips[chipnum];
0490 int ret;
0491
0492 mutex_lock(&chip->mutex);
0493 ret = get_chip(map, chip, FL_ERASING);
0494 if (ret) {
0495 mutex_unlock(&chip->mutex);
0496 return ret;
0497 }
0498 send_pfow_command(map, LPDDR_BLOCK_ERASE, adr, 0, NULL);
0499 chip->state = FL_ERASING;
0500 ret = wait_for_ready(map, chip, (1<<lpddr->qinfo->BlockEraseTime)*1000);
0501 if (ret) {
0502 printk(KERN_WARNING"%s Erase block error %d at : %llx\n",
0503 map->name, ret, adr);
0504 goto out;
0505 }
0506 out: put_chip(map, chip);
0507 mutex_unlock(&chip->mutex);
0508 return ret;
0509 }
0510
0511 static int lpddr_read(struct mtd_info *mtd, loff_t adr, size_t len,
0512 size_t *retlen, u_char *buf)
0513 {
0514 struct map_info *map = mtd->priv;
0515 struct lpddr_private *lpddr = map->fldrv_priv;
0516 int chipnum = adr >> lpddr->chipshift;
0517 struct flchip *chip = &lpddr->chips[chipnum];
0518 int ret = 0;
0519
0520 mutex_lock(&chip->mutex);
0521 ret = get_chip(map, chip, FL_READY);
0522 if (ret) {
0523 mutex_unlock(&chip->mutex);
0524 return ret;
0525 }
0526
0527 map_copy_from(map, buf, adr, len);
0528 *retlen = len;
0529
0530 put_chip(map, chip);
0531 mutex_unlock(&chip->mutex);
0532 return ret;
0533 }
0534
0535 static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,
0536 size_t *retlen, void **mtdbuf, resource_size_t *phys)
0537 {
0538 struct map_info *map = mtd->priv;
0539 struct lpddr_private *lpddr = map->fldrv_priv;
0540 int chipnum = adr >> lpddr->chipshift;
0541 unsigned long ofs, last_end = 0;
0542 struct flchip *chip = &lpddr->chips[chipnum];
0543 int ret = 0;
0544
0545 if (!map->virt)
0546 return -EINVAL;
0547
0548
0549 ofs = adr - (chipnum << lpddr->chipshift);
0550 *mtdbuf = (void *)map->virt + chip->start + ofs;
0551
0552 while (len) {
0553 unsigned long thislen;
0554
0555 if (chipnum >= lpddr->numchips)
0556 break;
0557
0558
0559 if (!last_end)
0560 last_end = chip->start;
0561 else if (chip->start != last_end)
0562 break;
0563
0564 if ((len + ofs - 1) >> lpddr->chipshift)
0565 thislen = (1<<lpddr->chipshift) - ofs;
0566 else
0567 thislen = len;
0568
0569 mutex_lock(&chip->mutex);
0570 ret = get_chip(map, chip, FL_POINT);
0571 mutex_unlock(&chip->mutex);
0572 if (ret)
0573 break;
0574
0575 chip->state = FL_POINT;
0576 chip->ref_point_counter++;
0577 *retlen += thislen;
0578 len -= thislen;
0579
0580 ofs = 0;
0581 last_end += 1 << lpddr->chipshift;
0582 chipnum++;
0583 chip = &lpddr->chips[chipnum];
0584 }
0585 return 0;
0586 }
0587
0588 static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)
0589 {
0590 struct map_info *map = mtd->priv;
0591 struct lpddr_private *lpddr = map->fldrv_priv;
0592 int chipnum = adr >> lpddr->chipshift, err = 0;
0593 unsigned long ofs;
0594
0595
0596 ofs = adr - (chipnum << lpddr->chipshift);
0597
0598 while (len) {
0599 unsigned long thislen;
0600 struct flchip *chip;
0601
0602 chip = &lpddr->chips[chipnum];
0603 if (chipnum >= lpddr->numchips)
0604 break;
0605
0606 if ((len + ofs - 1) >> lpddr->chipshift)
0607 thislen = (1<<lpddr->chipshift) - ofs;
0608 else
0609 thislen = len;
0610
0611 mutex_lock(&chip->mutex);
0612 if (chip->state == FL_POINT) {
0613 chip->ref_point_counter--;
0614 if (chip->ref_point_counter == 0)
0615 chip->state = FL_READY;
0616 } else {
0617 printk(KERN_WARNING "%s: Warning: unpoint called on non"
0618 "pointed region\n", map->name);
0619 err = -EINVAL;
0620 }
0621
0622 put_chip(map, chip);
0623 mutex_unlock(&chip->mutex);
0624
0625 len -= thislen;
0626 ofs = 0;
0627 chipnum++;
0628 }
0629
0630 return err;
0631 }
0632
0633 static int lpddr_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
0634 size_t *retlen, const u_char *buf)
0635 {
0636 struct kvec vec;
0637
0638 vec.iov_base = (void *) buf;
0639 vec.iov_len = len;
0640
0641 return lpddr_writev(mtd, &vec, 1, to, retlen);
0642 }
0643
0644
0645 static int lpddr_writev(struct mtd_info *mtd, const struct kvec *vecs,
0646 unsigned long count, loff_t to, size_t *retlen)
0647 {
0648 struct map_info *map = mtd->priv;
0649 struct lpddr_private *lpddr = map->fldrv_priv;
0650 int ret = 0;
0651 int chipnum;
0652 unsigned long ofs, vec_seek, i;
0653 int wbufsize = 1 << lpddr->qinfo->BufSizeShift;
0654 size_t len = 0;
0655
0656 for (i = 0; i < count; i++)
0657 len += vecs[i].iov_len;
0658
0659 if (!len)
0660 return 0;
0661
0662 chipnum = to >> lpddr->chipshift;
0663
0664 ofs = to;
0665 vec_seek = 0;
0666
0667 do {
0668
0669 int size = wbufsize - (ofs & (wbufsize-1));
0670
0671 if (size > len)
0672 size = len;
0673
0674 ret = do_write_buffer(map, &lpddr->chips[chipnum],
0675 ofs, &vecs, &vec_seek, size);
0676 if (ret)
0677 return ret;
0678
0679 ofs += size;
0680 (*retlen) += size;
0681 len -= size;
0682
0683
0684
0685 cond_resched();
0686
0687 } while (len);
0688
0689 return 0;
0690 }
0691
0692 static int lpddr_erase(struct mtd_info *mtd, struct erase_info *instr)
0693 {
0694 unsigned long ofs, len;
0695 int ret;
0696 struct map_info *map = mtd->priv;
0697 struct lpddr_private *lpddr = map->fldrv_priv;
0698 int size = 1 << lpddr->qinfo->UniformBlockSizeShift;
0699
0700 ofs = instr->addr;
0701 len = instr->len;
0702
0703 while (len > 0) {
0704 ret = do_erase_oneblock(mtd, ofs);
0705 if (ret)
0706 return ret;
0707 ofs += size;
0708 len -= size;
0709 }
0710
0711 return 0;
0712 }
0713
0714 #define DO_XXLOCK_LOCK 1
0715 #define DO_XXLOCK_UNLOCK 2
0716 static int do_xxlock(struct mtd_info *mtd, loff_t adr, uint32_t len, int thunk)
0717 {
0718 int ret = 0;
0719 struct map_info *map = mtd->priv;
0720 struct lpddr_private *lpddr = map->fldrv_priv;
0721 int chipnum = adr >> lpddr->chipshift;
0722 struct flchip *chip = &lpddr->chips[chipnum];
0723
0724 mutex_lock(&chip->mutex);
0725 ret = get_chip(map, chip, FL_LOCKING);
0726 if (ret) {
0727 mutex_unlock(&chip->mutex);
0728 return ret;
0729 }
0730
0731 if (thunk == DO_XXLOCK_LOCK) {
0732 send_pfow_command(map, LPDDR_LOCK_BLOCK, adr, adr + len, NULL);
0733 chip->state = FL_LOCKING;
0734 } else if (thunk == DO_XXLOCK_UNLOCK) {
0735 send_pfow_command(map, LPDDR_UNLOCK_BLOCK, adr, adr + len, NULL);
0736 chip->state = FL_UNLOCKING;
0737 } else
0738 BUG();
0739
0740 ret = wait_for_ready(map, chip, 1);
0741 if (ret) {
0742 printk(KERN_ERR "%s: block unlock error status %d \n",
0743 map->name, ret);
0744 goto out;
0745 }
0746 out: put_chip(map, chip);
0747 mutex_unlock(&chip->mutex);
0748 return ret;
0749 }
0750
0751 static int lpddr_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
0752 {
0753 return do_xxlock(mtd, ofs, len, DO_XXLOCK_LOCK);
0754 }
0755
0756 static int lpddr_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
0757 {
0758 return do_xxlock(mtd, ofs, len, DO_XXLOCK_UNLOCK);
0759 }
0760
0761 MODULE_LICENSE("GPL");
0762 MODULE_AUTHOR("Alexey Korolev <akorolev@infradead.org>");
0763 MODULE_DESCRIPTION("MTD driver for LPDDR flash chips");