aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c146
-rw-r--r--drivers/mtd/nand/Kconfig2
-rw-r--r--drivers/mtd/nand/diskonchip.c4
-rw-r--r--drivers/mtd/nand/nand_base.c6
-rw-r--r--drivers/mtd/nand/nand_ecc.c2
-rw-r--r--drivers/mtd/nand/nandsim.c2
-rw-r--r--drivers/mtd/nand/s3c2410.c14
-rw-r--r--drivers/mtd/onenand/onenand_sim.c50
8 files changed, 124 insertions, 102 deletions
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 3aa3dca56ae6..a9eb1c516247 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -85,6 +85,7 @@ static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len,
85static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, 85static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
86 size_t len); 86 size_t len);
87 87
88static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
88static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode); 89static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
89static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr); 90static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr);
90#include "fwh_lock.h" 91#include "fwh_lock.h"
@@ -641,73 +642,13 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd,
641/* 642/*
642 * *********** CHIP ACCESS FUNCTIONS *********** 643 * *********** CHIP ACCESS FUNCTIONS ***********
643 */ 644 */
644 645static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
645static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
646{ 646{
647 DECLARE_WAITQUEUE(wait, current); 647 DECLARE_WAITQUEUE(wait, current);
648 struct cfi_private *cfi = map->fldrv_priv; 648 struct cfi_private *cfi = map->fldrv_priv;
649 map_word status, status_OK = CMD(0x80), status_PWS = CMD(0x01); 649 map_word status, status_OK = CMD(0x80), status_PWS = CMD(0x01);
650 unsigned long timeo;
651 struct cfi_pri_intelext *cfip = cfi->cmdset_priv; 650 struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
652 651 unsigned long timeo = jiffies + HZ;
653 resettime:
654 timeo = jiffies + HZ;
655 retry:
656 if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) {
657 /*
658 * OK. We have possibility for contension on the write/erase
659 * operations which are global to the real chip and not per
660 * partition. So let's fight it over in the partition which
661 * currently has authority on the operation.
662 *
663 * The rules are as follows:
664 *
665 * - any write operation must own shared->writing.
666 *
667 * - any erase operation must own _both_ shared->writing and
668 * shared->erasing.
669 *
670 * - contension arbitration is handled in the owner's context.
671 *
672 * The 'shared' struct can be read and/or written only when
673 * its lock is taken.
674 */
675 struct flchip_shared *shared = chip->priv;
676 struct flchip *contender;
677 spin_lock(&shared->lock);
678 contender = shared->writing;
679 if (contender && contender != chip) {
680 /*
681 * The engine to perform desired operation on this
682 * partition is already in use by someone else.
683 * Let's fight over it in the context of the chip
684 * currently using it. If it is possible to suspend,
685 * that other partition will do just that, otherwise
686 * it'll happily send us to sleep. In any case, when
687 * get_chip returns success we're clear to go ahead.
688 */
689 int ret = spin_trylock(contender->mutex);
690 spin_unlock(&shared->lock);
691 if (!ret)
692 goto retry;
693 spin_unlock(chip->mutex);
694 ret = get_chip(map, contender, contender->start, mode);
695 spin_lock(chip->mutex);
696 if (ret) {
697 spin_unlock(contender->mutex);
698 return ret;
699 }
700 timeo = jiffies + HZ;
701 spin_lock(&shared->lock);
702 spin_unlock(contender->mutex);
703 }
704
705 /* We now own it */
706 shared->writing = chip;
707 if (mode == FL_ERASING)
708 shared->erasing = chip;
709 spin_unlock(&shared->lock);
710 }
711 652
712 switch (chip->state) { 653 switch (chip->state) {
713 654
@@ -722,16 +663,11 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
722 if (chip->priv && map_word_andequal(map, status, status_PWS, status_PWS)) 663 if (chip->priv && map_word_andequal(map, status, status_PWS, status_PWS))
723 break; 664 break;
724 665
725 if (time_after(jiffies, timeo)) {
726 printk(KERN_ERR "%s: Waiting for chip to be ready timed out. Status %lx\n",
727 map->name, status.x[0]);
728 return -EIO;
729 }
730 spin_unlock(chip->mutex); 666 spin_unlock(chip->mutex);
731 cfi_udelay(1); 667 cfi_udelay(1);
732 spin_lock(chip->mutex); 668 spin_lock(chip->mutex);
733 /* Someone else might have been playing with it. */ 669 /* Someone else might have been playing with it. */
734 goto retry; 670 return -EAGAIN;
735 } 671 }
736 672
737 case FL_READY: 673 case FL_READY:
@@ -809,10 +745,82 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
809 schedule(); 745 schedule();
810 remove_wait_queue(&chip->wq, &wait); 746 remove_wait_queue(&chip->wq, &wait);
811 spin_lock(chip->mutex); 747 spin_lock(chip->mutex);
812 goto resettime; 748 return -EAGAIN;
813 } 749 }
814} 750}
815 751
752static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
753{
754 int ret;
755
756 retry:
757 if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING
758 || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) {
759 /*
760 * OK. We have possibility for contention on the write/erase
761 * operations which are global to the real chip and not per
762 * partition. So let's fight it over in the partition which
763 * currently has authority on the operation.
764 *
765 * The rules are as follows:
766 *
767 * - any write operation must own shared->writing.
768 *
769 * - any erase operation must own _both_ shared->writing and
770 * shared->erasing.
771 *
772 * - contention arbitration is handled in the owner's context.
773 *
774 * The 'shared' struct can be read and/or written only when
775 * its lock is taken.
776 */
777 struct flchip_shared *shared = chip->priv;
778 struct flchip *contender;
779 spin_lock(&shared->lock);
780 contender = shared->writing;
781 if (contender && contender != chip) {
782 /*
783 * The engine to perform desired operation on this
784 * partition is already in use by someone else.
785 * Let's fight over it in the context of the chip
786 * currently using it. If it is possible to suspend,
787 * that other partition will do just that, otherwise
788 * it'll happily send us to sleep. In any case, when
789 * get_chip returns success we're clear to go ahead.
790 */
791 ret = spin_trylock(contender->mutex);
792 spin_unlock(&shared->lock);
793 if (!ret)
794 goto retry;
795 spin_unlock(chip->mutex);
796 ret = chip_ready(map, contender, contender->start, mode);
797 spin_lock(chip->mutex);
798
799 if (ret == -EAGAIN) {
800 spin_unlock(contender->mutex);
801 goto retry;
802 }
803 if (ret) {
804 spin_unlock(contender->mutex);
805 return ret;
806 }
807 spin_lock(&shared->lock);
808 spin_unlock(contender->mutex);
809 }
810
811 /* We now own it */
812 shared->writing = chip;
813 if (mode == FL_ERASING)
814 shared->erasing = chip;
815 spin_unlock(&shared->lock);
816 }
817 ret = chip_ready(map, chip, adr, mode);
818 if (ret == -EAGAIN)
819 goto retry;
820
821 return ret;
822}
823
816static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr) 824static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr)
817{ 825{
818 struct cfi_private *cfi = map->fldrv_priv; 826 struct cfi_private *cfi = map->fldrv_priv;
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 8f9c3baeb38e..246d4512f64b 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -300,7 +300,7 @@ config MTD_NAND_PLATFORM
300 via platform_data. 300 via platform_data.
301 301
302config MTD_ALAUDA 302config MTD_ALAUDA
303 tristate "MTD driver for Olympus MAUSB-10 and Fijufilm DPC-R1" 303 tristate "MTD driver for Olympus MAUSB-10 and Fujifilm DPC-R1"
304 depends on MTD_NAND && USB 304 depends on MTD_NAND && USB
305 help 305 help
306 These two (and possibly other) Alauda-based cardreaders for 306 These two (and possibly other) Alauda-based cardreaders for
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index ab9f5c5db38d..0e72153b3297 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -220,7 +220,7 @@ static int doc_ecc_decode(struct rs_control *rs, uint8_t *data, uint8_t *ecc)
220 } 220 }
221 } 221 }
222 /* If the parity is wrong, no rescue possible */ 222 /* If the parity is wrong, no rescue possible */
223 return parity ? -1 : nerr; 223 return parity ? -EBADMSG : nerr;
224} 224}
225 225
226static void DoC_Delay(struct doc_priv *doc, unsigned short cycles) 226static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
@@ -1034,7 +1034,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat,
1034 WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); 1034 WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
1035 else 1035 else
1036 WriteDOC(DOC_ECC_DIS, docptr, ECCConf); 1036 WriteDOC(DOC_ECC_DIS, docptr, ECCConf);
1037 if (no_ecc_failures && (ret == -1)) { 1037 if (no_ecc_failures && (ret == -EBADMSG)) {
1038 printk(KERN_ERR "suppressing ECC failure\n"); 1038 printk(KERN_ERR "suppressing ECC failure\n");
1039 ret = 0; 1039 ret = 0;
1040 } 1040 }
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index b4e0e7723894..e29c1da7f56e 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -789,7 +789,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
789 int stat; 789 int stat;
790 790
791 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); 791 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
792 if (stat == -1) 792 if (stat < 0)
793 mtd->ecc_stats.failed++; 793 mtd->ecc_stats.failed++;
794 else 794 else
795 mtd->ecc_stats.corrected += stat; 795 mtd->ecc_stats.corrected += stat;
@@ -833,7 +833,7 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
833 int stat; 833 int stat;
834 834
835 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); 835 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
836 if (stat == -1) 836 if (stat < 0)
837 mtd->ecc_stats.failed++; 837 mtd->ecc_stats.failed++;
838 else 838 else
839 mtd->ecc_stats.corrected += stat; 839 mtd->ecc_stats.corrected += stat;
@@ -874,7 +874,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
874 chip->read_buf(mtd, oob, eccbytes); 874 chip->read_buf(mtd, oob, eccbytes);
875 stat = chip->ecc.correct(mtd, p, oob, NULL); 875 stat = chip->ecc.correct(mtd, p, oob, NULL);
876 876
877 if (stat == -1) 877 if (stat < 0)
878 mtd->ecc_stats.failed++; 878 mtd->ecc_stats.failed++;
879 else 879 else
880 mtd->ecc_stats.corrected += stat; 880 mtd->ecc_stats.corrected += stat;
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index fde593e5e634..9003a135e050 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -189,7 +189,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat,
189 if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1) 189 if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1)
190 return 1; 190 return 1;
191 191
192 return -1; 192 return -EBADMSG;
193} 193}
194EXPORT_SYMBOL(nand_correct_data); 194EXPORT_SYMBOL(nand_correct_data);
195 195
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index a7574807dc46..10490b48d9f7 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -511,7 +511,7 @@ static int init_nandsim(struct mtd_info *mtd)
511 } 511 }
512 512
513 if (ns->options & OPT_SMALLPAGE) { 513 if (ns->options & OPT_SMALLPAGE) {
514 if (ns->geom.totsz < (64 << 20)) { 514 if (ns->geom.totsz < (32 << 20)) {
515 ns->geom.pgaddrbytes = 3; 515 ns->geom.pgaddrbytes = 3;
516 ns->geom.secaddrbytes = 2; 516 ns->geom.secaddrbytes = 2;
517 } else { 517 } else {
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index 21b921dd6aab..66f76e9618dd 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -488,12 +488,24 @@ static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
488 readsb(this->IO_ADDR_R, buf, len); 488 readsb(this->IO_ADDR_R, buf, len);
489} 489}
490 490
491static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
492{
493 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
494 readsl(info->regs + S3C2440_NFDATA, buf, len / 4);
495}
496
491static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) 497static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
492{ 498{
493 struct nand_chip *this = mtd->priv; 499 struct nand_chip *this = mtd->priv;
494 writesb(this->IO_ADDR_W, buf, len); 500 writesb(this->IO_ADDR_W, buf, len);
495} 501}
496 502
503static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
504{
505 struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
506 writesl(info->regs + S3C2440_NFDATA, buf, len / 4);
507}
508
497/* device management functions */ 509/* device management functions */
498 510
499static int s3c2410_nand_remove(struct platform_device *pdev) 511static int s3c2410_nand_remove(struct platform_device *pdev)
@@ -604,6 +616,8 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
604 info->sel_bit = S3C2440_NFCONT_nFCE; 616 info->sel_bit = S3C2440_NFCONT_nFCE;
605 chip->cmd_ctrl = s3c2440_nand_hwcontrol; 617 chip->cmd_ctrl = s3c2440_nand_hwcontrol;
606 chip->dev_ready = s3c2440_nand_devready; 618 chip->dev_ready = s3c2440_nand_devready;
619 chip->read_buf = s3c2440_nand_read_buf;
620 chip->write_buf = s3c2440_nand_write_buf;
607 break; 621 break;
608 622
609 case TYPE_S3C2412: 623 case TYPE_S3C2412:
diff --git a/drivers/mtd/onenand/onenand_sim.c b/drivers/mtd/onenand/onenand_sim.c
index 0d89ad5776fa..d64200b7c94b 100644
--- a/drivers/mtd/onenand/onenand_sim.c
+++ b/drivers/mtd/onenand/onenand_sim.c
@@ -88,11 +88,11 @@ do { \
88 88
89/** 89/**
90 * onenand_lock_handle - Handle Lock scheme 90 * onenand_lock_handle - Handle Lock scheme
91 * @param this OneNAND device structure 91 * @this: OneNAND device structure
92 * @param cmd The command to be sent 92 * @cmd: The command to be sent
93 * 93 *
94 * Send lock command to OneNAND device. 94 * Send lock command to OneNAND device.
95 * The lock scheme is depends on chip type. 95 * The lock scheme depends on chip type.
96 */ 96 */
97static void onenand_lock_handle(struct onenand_chip *this, int cmd) 97static void onenand_lock_handle(struct onenand_chip *this, int cmd)
98{ 98{
@@ -131,8 +131,8 @@ static void onenand_lock_handle(struct onenand_chip *this, int cmd)
131 131
132/** 132/**
133 * onenand_bootram_handle - Handle BootRAM area 133 * onenand_bootram_handle - Handle BootRAM area
134 * @param this OneNAND device structure 134 * @this: OneNAND device structure
135 * @param cmd The command to be sent 135 * @cmd: The command to be sent
136 * 136 *
137 * Emulate BootRAM area. It is possible to do basic operation using BootRAM. 137 * Emulate BootRAM area. It is possible to do basic operation using BootRAM.
138 */ 138 */
@@ -153,10 +153,10 @@ static void onenand_bootram_handle(struct onenand_chip *this, int cmd)
153 153
154/** 154/**
155 * onenand_update_interrupt - Set interrupt register 155 * onenand_update_interrupt - Set interrupt register
156 * @param this OneNAND device structure 156 * @this: OneNAND device structure
157 * @param cmd The command to be sent 157 * @cmd: The command to be sent
158 * 158 *
159 * Update interrupt register. The status is depends on command. 159 * Update interrupt register. The status depends on command.
160 */ 160 */
161static void onenand_update_interrupt(struct onenand_chip *this, int cmd) 161static void onenand_update_interrupt(struct onenand_chip *this, int cmd)
162{ 162{
@@ -189,11 +189,12 @@ static void onenand_update_interrupt(struct onenand_chip *this, int cmd)
189} 189}
190 190
191/** 191/**
192 * onenand_check_overwrite - Check over-write if happend 192 * onenand_check_overwrite - Check if over-write happened
193 * @param dest The destination pointer 193 * @dest: The destination pointer
194 * @param src The source pointer 194 * @src: The source pointer
195 * @param count The length to be check 195 * @count: The length to be check
196 * @return 0 on same, otherwise 1 196 *
197 * Returns: 0 on same, otherwise 1
197 * 198 *
198 * Compare the source with destination 199 * Compare the source with destination
199 */ 200 */
@@ -213,10 +214,10 @@ static int onenand_check_overwrite(void *dest, void *src, size_t count)
213 214
214/** 215/**
215 * onenand_data_handle - Handle OneNAND Core and DataRAM 216 * onenand_data_handle - Handle OneNAND Core and DataRAM
216 * @param this OneNAND device structure 217 * @this: OneNAND device structure
217 * @param cmd The command to be sent 218 * @cmd: The command to be sent
218 * @param dataram Which dataram used 219 * @dataram: Which dataram used
219 * @param offset The offset to OneNAND Core 220 * @offset: The offset to OneNAND Core
220 * 221 *
221 * Copy data from OneNAND Core to DataRAM (read) 222 * Copy data from OneNAND Core to DataRAM (read)
222 * Copy data from DataRAM to OneNAND Core (write) 223 * Copy data from DataRAM to OneNAND Core (write)
@@ -295,8 +296,8 @@ static void onenand_data_handle(struct onenand_chip *this, int cmd,
295 296
296/** 297/**
297 * onenand_command_handle - Handle command 298 * onenand_command_handle - Handle command
298 * @param this OneNAND device structure 299 * @this: OneNAND device structure
299 * @param cmd The command to be sent 300 * @cmd: The command to be sent
300 * 301 *
301 * Emulate OneNAND command. 302 * Emulate OneNAND command.
302 */ 303 */
@@ -350,8 +351,8 @@ static void onenand_command_handle(struct onenand_chip *this, int cmd)
350 351
351/** 352/**
352 * onenand_writew - [OneNAND Interface] Emulate write operation 353 * onenand_writew - [OneNAND Interface] Emulate write operation
353 * @param value value to write 354 * @value: value to write
354 * @param addr address to write 355 * @addr: address to write
355 * 356 *
356 * Write OneNAND register with value 357 * Write OneNAND register with value
357 */ 358 */
@@ -373,7 +374,7 @@ static void onenand_writew(unsigned short value, void __iomem * addr)
373 374
374/** 375/**
375 * flash_init - Initialize OneNAND simulator 376 * flash_init - Initialize OneNAND simulator
376 * @param flash OneNAND simulaotr data strucutres 377 * @flash: OneNAND simulator data strucutres
377 * 378 *
378 * Initialize OneNAND simulator. 379 * Initialize OneNAND simulator.
379 */ 380 */
@@ -416,7 +417,7 @@ static int __init flash_init(struct onenand_flash *flash)
416 417
417/** 418/**
418 * flash_exit - Clean up OneNAND simulator 419 * flash_exit - Clean up OneNAND simulator
419 * @param flash OneNAND simulaotr data strucutres 420 * @flash: OneNAND simulator data structures
420 * 421 *
421 * Clean up OneNAND simulator. 422 * Clean up OneNAND simulator.
422 */ 423 */
@@ -424,7 +425,6 @@ static void flash_exit(struct onenand_flash *flash)
424{ 425{
425 vfree(ONENAND_CORE(flash)); 426 vfree(ONENAND_CORE(flash));
426 kfree(flash->base); 427 kfree(flash->base);
427 kfree(flash);
428} 428}
429 429
430static int __init onenand_sim_init(void) 430static int __init onenand_sim_init(void)
@@ -449,7 +449,7 @@ static int __init onenand_sim_init(void)
449 info->onenand.write_word = onenand_writew; 449 info->onenand.write_word = onenand_writew;
450 450
451 if (flash_init(&info->flash)) { 451 if (flash_init(&info->flash)) {
452 printk(KERN_ERR "Unable to allocat flash.\n"); 452 printk(KERN_ERR "Unable to allocate flash.\n");
453 kfree(ffchars); 453 kfree(ffchars);
454 kfree(info); 454 kfree(info);
455 return -ENOMEM; 455 return -ENOMEM;