diff options
| -rw-r--r-- | drivers/mtd/onenand/onenand_base.c | 292 | ||||
| -rw-r--r-- | include/linux/mtd/onenand.h | 4 |
2 files changed, 264 insertions, 32 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 6e250f3a4a16..7bd6ad3ff30a 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c | |||
| @@ -1,17 +1,19 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/drivers/mtd/onenand/onenand_base.c | 2 | * linux/drivers/mtd/onenand/onenand_base.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005-2007 Samsung Electronics | 4 | * Copyright © 2005-2009 Samsung Electronics |
| 5 | * Copyright © 2007 Nokia Corporation | ||
| 6 | * | ||
| 5 | * Kyungmin Park <kyungmin.park@samsung.com> | 7 | * Kyungmin Park <kyungmin.park@samsung.com> |
| 6 | * | 8 | * |
| 7 | * Credits: | 9 | * Credits: |
| 8 | * Adrian Hunter <ext-adrian.hunter@nokia.com>: | 10 | * Adrian Hunter <ext-adrian.hunter@nokia.com>: |
| 9 | * auto-placement support, read-while load support, various fixes | 11 | * auto-placement support, read-while load support, various fixes |
| 10 | * Copyright (C) Nokia Corporation, 2007 | ||
| 11 | * | 12 | * |
| 12 | * Vishak G <vishak.g at samsung.com>, Rohit Hagargundgi <h.rohit at samsung.com> | 13 | * Vishak G <vishak.g at samsung.com>, Rohit Hagargundgi <h.rohit at samsung.com> |
| 13 | * Flex-OneNAND support | 14 | * Flex-OneNAND support |
| 14 | * Copyright (C) Samsung Electronics, 2008 | 15 | * Amul Kumar Saha <amul.saha at samsung.com> |
| 16 | * OTP support | ||
| 15 | * | 17 | * |
| 16 | * This program is free software; you can redistribute it and/or modify | 18 | * This program is free software; you can redistribute it and/or modify |
| 17 | * it under the terms of the GNU General Public License version 2 as | 19 | * it under the terms of the GNU General Public License version 2 as |
| @@ -43,6 +45,18 @@ MODULE_PARM_DESC(flex_bdry, "SLC Boundary information for Flex-OneNAND" | |||
| 43 | " : 0->Set boundary in unlocked status" | 45 | " : 0->Set boundary in unlocked status" |
| 44 | " : 1->Set boundary in locked status"); | 46 | " : 1->Set boundary in locked status"); |
| 45 | 47 | ||
| 48 | /* Default OneNAND/Flex-OneNAND OTP options*/ | ||
| 49 | static int otp; | ||
| 50 | |||
| 51 | module_param(otp, int, 0400); | ||
| 52 | MODULE_PARM_DESC(otp, "Corresponding behaviour of OneNAND in OTP" | ||
| 53 | "Syntax : otp=LOCK_TYPE" | ||
| 54 | "LOCK_TYPE : Keys issued, for specific OTP Lock type" | ||
| 55 | " : 0 -> Default (No Blocks Locked)" | ||
| 56 | " : 1 -> OTP Block lock" | ||
| 57 | " : 2 -> 1st Block lock" | ||
| 58 | " : 3 -> BOTH OTP Block and 1st Block lock"); | ||
| 59 | |||
| 46 | /** | 60 | /** |
| 47 | * onenand_oob_128 - oob info for Flex-Onenand with 4KB page | 61 | * onenand_oob_128 - oob info for Flex-Onenand with 4KB page |
| 48 | * For now, we expose only 64 out of 80 ecc bytes | 62 | * For now, we expose only 64 out of 80 ecc bytes |
| @@ -2591,6 +2605,208 @@ static void onenand_unlock_all(struct mtd_info *mtd) | |||
| 2591 | 2605 | ||
| 2592 | #ifdef CONFIG_MTD_ONENAND_OTP | 2606 | #ifdef CONFIG_MTD_ONENAND_OTP |
| 2593 | 2607 | ||
| 2608 | /** | ||
| 2609 | * onenand_otp_command - Send OTP specific command to OneNAND device | ||
| 2610 | * @param mtd MTD device structure | ||
| 2611 | * @param cmd the command to be sent | ||
| 2612 | * @param addr offset to read from or write to | ||
| 2613 | * @param len number of bytes to read or write | ||
| 2614 | */ | ||
| 2615 | static int onenand_otp_command(struct mtd_info *mtd, int cmd, loff_t addr, | ||
| 2616 | size_t len) | ||
| 2617 | { | ||
| 2618 | struct onenand_chip *this = mtd->priv; | ||
| 2619 | int value, block, page; | ||
| 2620 | |||
| 2621 | /* Address translation */ | ||
| 2622 | switch (cmd) { | ||
| 2623 | case ONENAND_CMD_OTP_ACCESS: | ||
| 2624 | block = (int) (addr >> this->erase_shift); | ||
| 2625 | page = -1; | ||
| 2626 | break; | ||
| 2627 | |||
| 2628 | default: | ||
| 2629 | block = (int) (addr >> this->erase_shift); | ||
| 2630 | page = (int) (addr >> this->page_shift); | ||
| 2631 | |||
| 2632 | if (ONENAND_IS_2PLANE(this)) { | ||
| 2633 | /* Make the even block number */ | ||
| 2634 | block &= ~1; | ||
| 2635 | /* Is it the odd plane? */ | ||
| 2636 | if (addr & this->writesize) | ||
| 2637 | block++; | ||
| 2638 | page >>= 1; | ||
| 2639 | } | ||
| 2640 | page &= this->page_mask; | ||
| 2641 | break; | ||
| 2642 | } | ||
| 2643 | |||
| 2644 | if (block != -1) { | ||
| 2645 | /* Write 'DFS, FBA' of Flash */ | ||
| 2646 | value = onenand_block_address(this, block); | ||
| 2647 | this->write_word(value, this->base + | ||
| 2648 | ONENAND_REG_START_ADDRESS1); | ||
| 2649 | } | ||
| 2650 | |||
| 2651 | if (page != -1) { | ||
| 2652 | /* Now we use page size operation */ | ||
| 2653 | int sectors = 4, count = 4; | ||
| 2654 | int dataram; | ||
| 2655 | |||
| 2656 | switch (cmd) { | ||
| 2657 | default: | ||
| 2658 | if (ONENAND_IS_2PLANE(this) && cmd == ONENAND_CMD_PROG) | ||
| 2659 | cmd = ONENAND_CMD_2X_PROG; | ||
| 2660 | dataram = ONENAND_CURRENT_BUFFERRAM(this); | ||
| 2661 | break; | ||
| 2662 | } | ||
| 2663 | |||
| 2664 | /* Write 'FPA, FSA' of Flash */ | ||
| 2665 | value = onenand_page_address(page, sectors); | ||
| 2666 | this->write_word(value, this->base + | ||
| 2667 | ONENAND_REG_START_ADDRESS8); | ||
| 2668 | |||
| 2669 | /* Write 'BSA, BSC' of DataRAM */ | ||
| 2670 | value = onenand_buffer_address(dataram, sectors, count); | ||
| 2671 | this->write_word(value, this->base + ONENAND_REG_START_BUFFER); | ||
| 2672 | } | ||
| 2673 | |||
| 2674 | /* Interrupt clear */ | ||
| 2675 | this->write_word(ONENAND_INT_CLEAR, this->base + ONENAND_REG_INTERRUPT); | ||
| 2676 | |||
| 2677 | /* Write command */ | ||
| 2678 | this->write_word(cmd, this->base + ONENAND_REG_COMMAND); | ||
| 2679 | |||
| 2680 | return 0; | ||
| 2681 | } | ||
| 2682 | |||
| 2683 | /** | ||
| 2684 | * onenand_otp_write_oob_nolock - [Internal] OneNAND write out-of-band, specific to OTP | ||
| 2685 | * @param mtd MTD device structure | ||
| 2686 | * @param to offset to write to | ||
| 2687 | * @param len number of bytes to write | ||
| 2688 | * @param retlen pointer to variable to store the number of written bytes | ||
| 2689 | * @param buf the data to write | ||
| 2690 | * | ||
| 2691 | * OneNAND write out-of-band only for OTP | ||
| 2692 | */ | ||
| 2693 | static int onenand_otp_write_oob_nolock(struct mtd_info *mtd, loff_t to, | ||
| 2694 | struct mtd_oob_ops *ops) | ||
| 2695 | { | ||
| 2696 | struct onenand_chip *this = mtd->priv; | ||
| 2697 | int column, ret = 0, oobsize; | ||
| 2698 | int written = 0; | ||
| 2699 | u_char *oobbuf; | ||
| 2700 | size_t len = ops->ooblen; | ||
| 2701 | const u_char *buf = ops->oobbuf; | ||
| 2702 | int block, value, status; | ||
| 2703 | |||
| 2704 | to += ops->ooboffs; | ||
| 2705 | |||
| 2706 | /* Initialize retlen, in case of early exit */ | ||
| 2707 | ops->oobretlen = 0; | ||
| 2708 | |||
| 2709 | oobsize = mtd->oobsize; | ||
| 2710 | |||
| 2711 | column = to & (mtd->oobsize - 1); | ||
| 2712 | |||
| 2713 | oobbuf = this->oob_buf; | ||
| 2714 | |||
| 2715 | /* Loop until all data write */ | ||
| 2716 | while (written < len) { | ||
| 2717 | int thislen = min_t(int, oobsize, len - written); | ||
| 2718 | |||
| 2719 | cond_resched(); | ||
| 2720 | |||
| 2721 | block = (int) (to >> this->erase_shift); | ||
| 2722 | /* | ||
| 2723 | * Write 'DFS, FBA' of Flash | ||
| 2724 | * Add: F100h DQ=DFS, FBA | ||
| 2725 | */ | ||
| 2726 | |||
| 2727 | value = onenand_block_address(this, block); | ||
| 2728 | this->write_word(value, this->base + | ||
| 2729 | ONENAND_REG_START_ADDRESS1); | ||
| 2730 | |||
| 2731 | /* | ||
| 2732 | * Select DataRAM for DDP | ||
| 2733 | * Add: F101h DQ=DBS | ||
| 2734 | */ | ||
| 2735 | |||
| 2736 | value = onenand_bufferram_address(this, block); | ||
| 2737 | this->write_word(value, this->base + | ||
| 2738 | ONENAND_REG_START_ADDRESS2); | ||
| 2739 | ONENAND_SET_NEXT_BUFFERRAM(this); | ||
| 2740 | |||
| 2741 | /* | ||
| 2742 | * Enter OTP access mode | ||
| 2743 | */ | ||
| 2744 | this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); | ||
| 2745 | this->wait(mtd, FL_OTPING); | ||
| 2746 | |||
| 2747 | /* We send data to spare ram with oobsize | ||
| 2748 | * to prevent byte access */ | ||
| 2749 | memcpy(oobbuf + column, buf, thislen); | ||
| 2750 | |||
| 2751 | /* | ||
| 2752 | * Write Data into DataRAM | ||
| 2753 | * Add: 8th Word | ||
| 2754 | * in sector0/spare/page0 | ||
| 2755 | * DQ=XXFCh | ||
| 2756 | */ | ||
| 2757 | this->write_bufferram(mtd, ONENAND_SPARERAM, | ||
| 2758 | oobbuf, 0, mtd->oobsize); | ||
| 2759 | |||
| 2760 | onenand_otp_command(mtd, ONENAND_CMD_PROGOOB, to, mtd->oobsize); | ||
| 2761 | onenand_update_bufferram(mtd, to, 0); | ||
| 2762 | if (ONENAND_IS_2PLANE(this)) { | ||
| 2763 | ONENAND_SET_BUFFERRAM1(this); | ||
| 2764 | onenand_update_bufferram(mtd, to + this->writesize, 0); | ||
| 2765 | } | ||
| 2766 | |||
| 2767 | ret = this->wait(mtd, FL_WRITING); | ||
| 2768 | if (ret) { | ||
| 2769 | printk(KERN_ERR "%s: write failed %d\n", __func__, ret); | ||
| 2770 | break; | ||
| 2771 | } | ||
| 2772 | |||
| 2773 | /* Exit OTP access mode */ | ||
| 2774 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); | ||
| 2775 | this->wait(mtd, FL_RESETING); | ||
| 2776 | |||
| 2777 | status = this->read_word(this->base + ONENAND_REG_CTRL_STATUS); | ||
| 2778 | status &= 0x60; | ||
| 2779 | |||
| 2780 | if (status == 0x60) { | ||
| 2781 | printk(KERN_DEBUG "\nBLOCK\tSTATUS\n"); | ||
| 2782 | printk(KERN_DEBUG "1st Block\tLOCKED\n"); | ||
| 2783 | printk(KERN_DEBUG "OTP Block\tLOCKED\n"); | ||
| 2784 | } else if (status == 0x20) { | ||
| 2785 | printk(KERN_DEBUG "\nBLOCK\tSTATUS\n"); | ||
| 2786 | printk(KERN_DEBUG "1st Block\tLOCKED\n"); | ||
| 2787 | printk(KERN_DEBUG "OTP Block\tUN-LOCKED\n"); | ||
| 2788 | } else if (status == 0x40) { | ||
| 2789 | printk(KERN_DEBUG "\nBLOCK\tSTATUS\n"); | ||
| 2790 | printk(KERN_DEBUG "1st Block\tUN-LOCKED\n"); | ||
| 2791 | printk(KERN_DEBUG "OTP Block\tLOCKED\n"); | ||
| 2792 | } else { | ||
| 2793 | printk(KERN_DEBUG "Reboot to check\n"); | ||
| 2794 | } | ||
| 2795 | |||
| 2796 | written += thislen; | ||
| 2797 | if (written == len) | ||
| 2798 | break; | ||
| 2799 | |||
| 2800 | to += mtd->writesize; | ||
| 2801 | buf += thislen; | ||
| 2802 | column = 0; | ||
| 2803 | } | ||
| 2804 | |||
| 2805 | ops->oobretlen = written; | ||
| 2806 | |||
| 2807 | return ret; | ||
| 2808 | } | ||
| 2809 | |||
| 2594 | /* Internal OTP operation */ | 2810 | /* Internal OTP operation */ |
| 2595 | typedef int (*otp_op_t)(struct mtd_info *mtd, loff_t form, size_t len, | 2811 | typedef int (*otp_op_t)(struct mtd_info *mtd, loff_t form, size_t len, |
| 2596 | size_t *retlen, u_char *buf); | 2812 | size_t *retlen, u_char *buf); |
| @@ -2693,11 +2909,11 @@ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 2693 | struct mtd_oob_ops ops; | 2909 | struct mtd_oob_ops ops; |
| 2694 | int ret; | 2910 | int ret; |
| 2695 | 2911 | ||
| 2696 | /* Enter OTP access mode */ | ||
| 2697 | this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); | ||
| 2698 | this->wait(mtd, FL_OTPING); | ||
| 2699 | |||
| 2700 | if (FLEXONENAND(this)) { | 2912 | if (FLEXONENAND(this)) { |
| 2913 | |||
| 2914 | /* Enter OTP access mode */ | ||
| 2915 | this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); | ||
| 2916 | this->wait(mtd, FL_OTPING); | ||
| 2701 | /* | 2917 | /* |
| 2702 | * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of | 2918 | * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of |
| 2703 | * main area of page 49. | 2919 | * main area of page 49. |
| @@ -2708,19 +2924,19 @@ static int do_otp_lock(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 2708 | ops.oobbuf = NULL; | 2924 | ops.oobbuf = NULL; |
| 2709 | ret = onenand_write_ops_nolock(mtd, mtd->writesize * 49, &ops); | 2925 | ret = onenand_write_ops_nolock(mtd, mtd->writesize * 49, &ops); |
| 2710 | *retlen = ops.retlen; | 2926 | *retlen = ops.retlen; |
| 2927 | |||
| 2928 | /* Exit OTP access mode */ | ||
| 2929 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); | ||
| 2930 | this->wait(mtd, FL_RESETING); | ||
| 2711 | } else { | 2931 | } else { |
| 2712 | ops.mode = MTD_OOB_PLACE; | 2932 | ops.mode = MTD_OOB_PLACE; |
| 2713 | ops.ooblen = len; | 2933 | ops.ooblen = len; |
| 2714 | ops.oobbuf = buf; | 2934 | ops.oobbuf = buf; |
| 2715 | ops.ooboffs = 0; | 2935 | ops.ooboffs = 0; |
| 2716 | ret = onenand_write_oob_nolock(mtd, from, &ops); | 2936 | ret = onenand_otp_write_oob_nolock(mtd, from, &ops); |
| 2717 | *retlen = ops.oobretlen; | 2937 | *retlen = ops.oobretlen; |
| 2718 | } | 2938 | } |
| 2719 | 2939 | ||
| 2720 | /* Exit OTP access mode */ | ||
| 2721 | this->command(mtd, ONENAND_CMD_RESET, 0, 0); | ||
| 2722 | this->wait(mtd, FL_RESETING); | ||
| 2723 | |||
| 2724 | return ret; | 2940 | return ret; |
| 2725 | } | 2941 | } |
| 2726 | 2942 | ||
| @@ -2751,16 +2967,21 @@ static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 2751 | if (density < ONENAND_DEVICE_DENSITY_512Mb) | 2967 | if (density < ONENAND_DEVICE_DENSITY_512Mb) |
| 2752 | otp_pages = 20; | 2968 | otp_pages = 20; |
| 2753 | else | 2969 | else |
| 2754 | otp_pages = 10; | 2970 | otp_pages = 50; |
| 2755 | 2971 | ||
| 2756 | if (mode == MTD_OTP_FACTORY) { | 2972 | if (mode == MTD_OTP_FACTORY) { |
| 2757 | from += mtd->writesize * otp_pages; | 2973 | from += mtd->writesize * otp_pages; |
| 2758 | otp_pages = 64 - otp_pages; | 2974 | otp_pages = ONENAND_PAGES_PER_BLOCK - otp_pages; |
| 2759 | } | 2975 | } |
| 2760 | 2976 | ||
| 2761 | /* Check User/Factory boundary */ | 2977 | /* Check User/Factory boundary */ |
| 2762 | if (((mtd->writesize * otp_pages) - (from + len)) < 0) | 2978 | if (mode == MTD_OTP_USER) { |
| 2763 | return 0; | 2979 | if (((mtd->writesize * otp_pages) - (from + len)) < 0) |
| 2980 | return 0; | ||
| 2981 | } else { | ||
| 2982 | if (((mtd->writesize * otp_pages) - len) < 0) | ||
| 2983 | return 0; | ||
| 2984 | } | ||
| 2764 | 2985 | ||
| 2765 | onenand_get_device(mtd, FL_OTPING); | 2986 | onenand_get_device(mtd, FL_OTPING); |
| 2766 | while (len > 0 && otp_pages > 0) { | 2987 | while (len > 0 && otp_pages > 0) { |
| @@ -2783,13 +3004,12 @@ static int onenand_otp_walk(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 2783 | *retlen += sizeof(struct otp_info); | 3004 | *retlen += sizeof(struct otp_info); |
| 2784 | } else { | 3005 | } else { |
| 2785 | size_t tmp_retlen; | 3006 | size_t tmp_retlen; |
| 2786 | int size = len; | ||
| 2787 | 3007 | ||
| 2788 | ret = action(mtd, from, len, &tmp_retlen, buf); | 3008 | ret = action(mtd, from, len, &tmp_retlen, buf); |
| 2789 | 3009 | ||
| 2790 | buf += size; | 3010 | buf += tmp_retlen; |
| 2791 | len -= size; | 3011 | len -= tmp_retlen; |
| 2792 | *retlen += size; | 3012 | *retlen += tmp_retlen; |
| 2793 | 3013 | ||
| 2794 | if (ret) | 3014 | if (ret) |
| 2795 | break; | 3015 | break; |
| @@ -2902,21 +3122,11 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, | |||
| 2902 | u_char *buf = FLEXONENAND(this) ? this->page_buf : this->oob_buf; | 3122 | u_char *buf = FLEXONENAND(this) ? this->page_buf : this->oob_buf; |
| 2903 | size_t retlen; | 3123 | size_t retlen; |
| 2904 | int ret; | 3124 | int ret; |
| 3125 | unsigned int otp_lock_offset = ONENAND_OTP_LOCK_OFFSET; | ||
| 2905 | 3126 | ||
| 2906 | memset(buf, 0xff, FLEXONENAND(this) ? this->writesize | 3127 | memset(buf, 0xff, FLEXONENAND(this) ? this->writesize |
| 2907 | : mtd->oobsize); | 3128 | : mtd->oobsize); |
| 2908 | /* | 3129 | /* |
| 2909 | * Note: OTP lock operation | ||
| 2910 | * OTP block : 0xXXFC | ||
| 2911 | * 1st block : 0xXXF3 (If chip support) | ||
| 2912 | * Both : 0xXXF0 (If chip support) | ||
| 2913 | */ | ||
| 2914 | if (FLEXONENAND(this)) | ||
| 2915 | buf[FLEXONENAND_OTP_LOCK_OFFSET] = 0xFC; | ||
| 2916 | else | ||
| 2917 | buf[ONENAND_OTP_LOCK_OFFSET] = 0xFC; | ||
| 2918 | |||
| 2919 | /* | ||
| 2920 | * Write lock mark to 8th word of sector0 of page0 of the spare0. | 3130 | * Write lock mark to 8th word of sector0 of page0 of the spare0. |
| 2921 | * We write 16 bytes spare area instead of 2 bytes. | 3131 | * We write 16 bytes spare area instead of 2 bytes. |
| 2922 | * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of | 3132 | * For Flex-OneNAND, we write lock mark to 1st word of sector 4 of |
| @@ -2926,10 +3136,30 @@ static int onenand_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, | |||
| 2926 | from = 0; | 3136 | from = 0; |
| 2927 | len = FLEXONENAND(this) ? mtd->writesize : 16; | 3137 | len = FLEXONENAND(this) ? mtd->writesize : 16; |
| 2928 | 3138 | ||
| 3139 | /* | ||
| 3140 | * Note: OTP lock operation | ||
| 3141 | * OTP block : 0xXXFC XX 1111 1100 | ||
| 3142 | * 1st block : 0xXXF3 (If chip support) XX 1111 0011 | ||
| 3143 | * Both : 0xXXF0 (If chip support) XX 1111 0000 | ||
| 3144 | */ | ||
| 3145 | if (FLEXONENAND(this)) | ||
| 3146 | otp_lock_offset = FLEXONENAND_OTP_LOCK_OFFSET; | ||
| 3147 | |||
| 3148 | /* ONENAND_OTP_AREA | ONENAND_OTP_BLOCK0 | ONENAND_OTP_AREA_BLOCK0 */ | ||
| 3149 | if (otp == 1) | ||
| 3150 | buf[otp_lock_offset] = 0xFC; | ||
| 3151 | else if (otp == 2) | ||
| 3152 | buf[otp_lock_offset] = 0xF3; | ||
| 3153 | else if (otp == 3) | ||
| 3154 | buf[otp_lock_offset] = 0xF0; | ||
| 3155 | else if (otp != 0) | ||
| 3156 | printk(KERN_DEBUG "[OneNAND] Invalid option selected for OTP\n"); | ||
| 3157 | |||
| 2929 | ret = onenand_otp_walk(mtd, from, len, &retlen, buf, do_otp_lock, MTD_OTP_USER); | 3158 | ret = onenand_otp_walk(mtd, from, len, &retlen, buf, do_otp_lock, MTD_OTP_USER); |
| 2930 | 3159 | ||
| 2931 | return ret ? : retlen; | 3160 | return ret ? : retlen; |
| 2932 | } | 3161 | } |
| 3162 | |||
| 2933 | #endif /* CONFIG_MTD_ONENAND_OTP */ | 3163 | #endif /* CONFIG_MTD_ONENAND_OTP */ |
| 2934 | 3164 | ||
| 2935 | /** | 3165 | /** |
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index f57e29e17bb0..5509eb06b326 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/include/linux/mtd/onenand.h | 2 | * linux/include/linux/mtd/onenand.h |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005-2007 Samsung Electronics | 4 | * Copyright © 2005-2009 Samsung Electronics |
| 5 | * Kyungmin Park <kyungmin.park@samsung.com> | 5 | * Kyungmin Park <kyungmin.park@samsung.com> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| @@ -137,6 +137,8 @@ struct onenand_chip { | |||
| 137 | /* | 137 | /* |
| 138 | * Helper macros | 138 | * Helper macros |
| 139 | */ | 139 | */ |
| 140 | #define ONENAND_PAGES_PER_BLOCK (1<<6) | ||
| 141 | |||
| 140 | #define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index) | 142 | #define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index) |
| 141 | #define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1) | 143 | #define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1) |
| 142 | #define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1) | 144 | #define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1) |
