Lines Matching +full:nand +full:- +full:ecc +full:- +full:algo
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright © 2004-2008 Simtec Electronics
7 * Samsung S3C2410/S3C2440/S3C2412 NAND driver
10 #define pr_fmt(fmt) "nand-s3c2410: " fmt
36 #include <linux/platform_data/mtd-nand-s3c2410.h>
73 /* new oob placement block for use with hardware ecc generation
79 return -ERANGE; in s3c2410_ooblayout_ecc()
81 oobregion->offset = 0; in s3c2410_ooblayout_ecc()
82 oobregion->length = 3; in s3c2410_ooblayout_ecc()
91 return -ERANGE; in s3c2410_ooblayout_free()
93 oobregion->offset = 8; in s3c2410_ooblayout_free()
94 oobregion->length = 8; in s3c2410_ooblayout_free()
100 .ecc = s3c2410_ooblayout_ecc,
109 * struct s3c2410_nand_mtd - driver MTD structure
111 * @chip: The NAND chip information.
112 * @set: The platform information supplied for this set of NAND chips.
133 /* overview of the s3c2410 nand state */
136 * struct s3c2410_nand_info - NAND controller state.
142 * @sel_reg: Pointer to the register controlling the NAND selection.
143 * @sel_bit: The bit in @sel_reg to select the NAND chip.
200 return s3c2410_nand_mtd_toours(mtd)->info; in s3c2410_nand_mtd_toinfo()
210 return dev_get_platdata(&dev->dev); in to_nand_plat()
223 * s3c2410_nand_clk_set_state - Enable, disable or suspend NAND clock.
233 if (info->clk_state == CLOCK_ENABLE) { in s3c2410_nand_clk_set_state()
235 clk_disable_unprepare(info->clk); in s3c2410_nand_clk_set_state()
238 clk_prepare_enable(info->clk); in s3c2410_nand_clk_set_state()
241 info->clk_state = new_state; in s3c2410_nand_clk_set_state()
249 * s3c_nand_calc_rate - calculate timing data.
267 return -1; in s3c_nand_calc_rate()
281 * s3c2410_nand_setrate - setup controller timing information.
290 struct s3c2410_platform_nand *plat = info->platform; in s3c2410_nand_setrate()
291 int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4; in s3c2410_nand_setrate()
293 unsigned long clkrate = clk_get_rate(info->clk); in s3c2410_nand_setrate()
299 info->clk_rate = clkrate; in s3c2410_nand_setrate()
303 tacls = s3c_nand_calc_rate(plat->tacls, clkrate, tacls_max); in s3c2410_nand_setrate()
304 twrph0 = s3c_nand_calc_rate(plat->twrph0, clkrate, 8); in s3c2410_nand_setrate()
305 twrph1 = s3c_nand_calc_rate(plat->twrph1, clkrate, 8); in s3c2410_nand_setrate()
314 dev_err(info->device, "cannot get suitable timings\n"); in s3c2410_nand_setrate()
315 return -EINVAL; in s3c2410_nand_setrate()
318 dev_info(info->device, "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", in s3c2410_nand_setrate()
322 switch (info->cpu_type) { in s3c2410_nand_setrate()
328 set |= S3C2410_NFCONF_TACLS(tacls - 1); in s3c2410_nand_setrate()
329 set |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); in s3c2410_nand_setrate()
330 set |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); in s3c2410_nand_setrate()
335 mask = (S3C2440_NFCONF_TACLS(tacls_max - 1) | in s3c2410_nand_setrate()
339 set = S3C2440_NFCONF_TACLS(tacls - 1); in s3c2410_nand_setrate()
340 set |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); in s3c2410_nand_setrate()
341 set |= S3C2440_NFCONF_TWRPH1(twrph1 - 1); in s3c2410_nand_setrate()
350 cfg = readl(info->regs + S3C2410_NFCONF); in s3c2410_nand_setrate()
353 writel(cfg, info->regs + S3C2410_NFCONF); in s3c2410_nand_setrate()
357 dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg); in s3c2410_nand_setrate()
363 * s3c2410_nand_inithw - basic hardware initialisation
377 switch (info->cpu_type) { in s3c2410_nand_inithw()
384 /* enable the controller and de-assert nFCE */ in s3c2410_nand_inithw()
386 writel(S3C2440_NFCONT_ENABLE, info->regs + S3C2440_NFCONT); in s3c2410_nand_inithw()
393 * s3c2410_nand_select_chip - select the given nand chip
394 * @this: NAND chip object.
399 * chip can be de-selected.
412 info = nmtd->info; in s3c2410_nand_select_chip()
414 if (chip != -1) in s3c2410_nand_select_chip()
417 cur = readl(info->sel_reg); in s3c2410_nand_select_chip()
419 if (chip == -1) { in s3c2410_nand_select_chip()
420 cur |= info->sel_bit; in s3c2410_nand_select_chip()
422 if (nmtd->set != NULL && chip > nmtd->set->nr_chips) { in s3c2410_nand_select_chip()
423 dev_err(info->device, "invalid chip %d\n", chip); in s3c2410_nand_select_chip()
427 if (info->platform != NULL) { in s3c2410_nand_select_chip()
428 if (info->platform->select_chip != NULL) in s3c2410_nand_select_chip()
429 (info->platform->select_chip) (nmtd->set, chip); in s3c2410_nand_select_chip()
432 cur &= ~info->sel_bit; in s3c2410_nand_select_chip()
435 writel(cur, info->sel_reg); in s3c2410_nand_select_chip()
437 if (chip == -1) in s3c2410_nand_select_chip()
456 writeb(cmd, info->regs + S3C2410_NFCMD); in s3c2410_nand_hwcontrol()
458 writeb(cmd, info->regs + S3C2410_NFADDR); in s3c2410_nand_hwcontrol()
473 writeb(cmd, info->regs + S3C2440_NFCMD); in s3c2440_nand_hwcontrol()
475 writeb(cmd, info->regs + S3C2440_NFADDR); in s3c2440_nand_hwcontrol()
480 * returns 0 if the nand is busy, 1 if it is ready
487 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; in s3c2410_nand_devready()
494 return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; in s3c2440_nand_devready()
501 return readb(info->regs + S3C2412_NFSTAT) & S3C2412_NFSTAT_READY; in s3c2412_nand_devready()
504 /* ECC handling functions */
525 return 0; /* ECC is ok */ in s3c2410_nand_correct_data()
527 /* sometimes people do not think about using the ECC, so check in s3c2410_nand_correct_data()
528 * to see if we have an 0xff,0xff,0xff read ECC and then ignore in s3c2410_nand_correct_data()
529 * the error, on the assumption that this is an un-eccd page. in s3c2410_nand_correct_data()
532 && info->platform->ignore_unset_ecc) in s3c2410_nand_correct_data()
535 /* Can we correct this ECC (ie, one row and column change). in s3c2410_nand_correct_data()
559 dev_dbg(info->device, "correcting error bit %d, byte %d\n", in s3c2410_nand_correct_data()
566 /* if there is only one bit difference in the ECC, then in s3c2410_nand_correct_data()
568 * means the error is most probably in the ECC itself */ in s3c2410_nand_correct_data()
574 if ((diff0 & (diff0 - 1)) == 0) in s3c2410_nand_correct_data()
577 return -1; in s3c2410_nand_correct_data()
580 /* ECC functions
582 * These allow the s3c2410 and s3c2440 to use the controller's ECC
583 * generator block to ECC the data as it passes through]
592 ctrl = readl(info->regs + S3C2410_NFCONF); in s3c2410_nand_enable_hwecc()
594 writel(ctrl, info->regs + S3C2410_NFCONF); in s3c2410_nand_enable_hwecc()
603 ctrl = readl(info->regs + S3C2440_NFCONT); in s3c2412_nand_enable_hwecc()
605 info->regs + S3C2440_NFCONT); in s3c2412_nand_enable_hwecc()
614 ctrl = readl(info->regs + S3C2440_NFCONT); in s3c2440_nand_enable_hwecc()
615 writel(ctrl | S3C2440_NFCONT_INITECC, info->regs + S3C2440_NFCONT); in s3c2440_nand_enable_hwecc()
624 ecc_code[0] = readb(info->regs + S3C2410_NFECC + 0); in s3c2410_nand_calculate_ecc()
625 ecc_code[1] = readb(info->regs + S3C2410_NFECC + 1); in s3c2410_nand_calculate_ecc()
626 ecc_code[2] = readb(info->regs + S3C2410_NFECC + 2); in s3c2410_nand_calculate_ecc()
628 pr_debug("%s: returning ecc %*phN\n", __func__, 3, ecc_code); in s3c2410_nand_calculate_ecc()
638 unsigned long ecc = readl(info->regs + S3C2412_NFMECC0); in s3c2412_nand_calculate_ecc() local
640 ecc_code[0] = ecc; in s3c2412_nand_calculate_ecc()
641 ecc_code[1] = ecc >> 8; in s3c2412_nand_calculate_ecc()
642 ecc_code[2] = ecc >> 16; in s3c2412_nand_calculate_ecc()
644 pr_debug("%s: returning ecc %*phN\n", __func__, 3, ecc_code); in s3c2412_nand_calculate_ecc()
654 unsigned long ecc = readl(info->regs + S3C2440_NFMECC0); in s3c2440_nand_calculate_ecc() local
656 ecc_code[0] = ecc; in s3c2440_nand_calculate_ecc()
657 ecc_code[1] = ecc >> 8; in s3c2440_nand_calculate_ecc()
658 ecc_code[2] = ecc >> 16; in s3c2440_nand_calculate_ecc()
660 pr_debug("%s: returning ecc %06lx\n", __func__, ecc & 0xffffff); in s3c2440_nand_calculate_ecc()
665 /* over-ride the standard functions for a little more speed. We can
671 readsb(this->legacy.IO_ADDR_R, buf, len); in s3c2410_nand_read_buf()
679 readsl(info->regs + S3C2440_NFDATA, buf, len >> 2); in s3c2440_nand_read_buf()
685 for (; len & 3; len--) in s3c2440_nand_read_buf()
686 *buf++ = readb(info->regs + S3C2440_NFDATA); in s3c2440_nand_read_buf()
693 writesb(this->legacy.IO_ADDR_W, buf, len); in s3c2410_nand_write_buf()
702 writesl(info->regs + S3C2440_NFDATA, buf, len >> 2); in s3c2440_nand_write_buf()
708 for (; len & 3; len--, buf++) in s3c2440_nand_write_buf()
709 writeb(*buf, info->regs + S3C2440_NFDATA); in s3c2440_nand_write_buf()
724 newclk = clk_get_rate(info->clk); in s3c2410_nand_cpufreq_transition()
726 if ((val == CPUFREQ_POSTCHANGE && newclk < info->clk_rate) || in s3c2410_nand_cpufreq_transition()
727 (val == CPUFREQ_PRECHANGE && newclk > info->clk_rate)) { in s3c2410_nand_cpufreq_transition()
736 info->freq_transition.notifier_call = s3c2410_nand_cpufreq_transition; in s3c2410_nand_cpufreq_register()
738 return cpufreq_register_notifier(&info->freq_transition, in s3c2410_nand_cpufreq_register()
745 cpufreq_unregister_notifier(&info->freq_transition, in s3c2410_nand_cpufreq_deregister()
776 if (info->mtds != NULL) { in s3c24xx_nand_remove()
777 struct s3c2410_nand_mtd *ptr = info->mtds; in s3c24xx_nand_remove()
780 for (mtdno = 0; mtdno < info->mtd_count; mtdno++, ptr++) { in s3c24xx_nand_remove()
782 nand_release(&ptr->chip); in s3c24xx_nand_remove()
788 if (!IS_ERR(info->clk)) in s3c24xx_nand_remove()
799 struct mtd_info *mtdinfo = nand_to_mtd(&mtd->chip); in s3c2410_nand_add_partition()
801 mtdinfo->name = set->name; in s3c2410_nand_add_partition()
803 return mtd_device_register(mtdinfo, set->partitions, in s3c2410_nand_add_partition()
804 set->nr_partitions); in s3c2410_nand_add_partition()
807 return -ENODEV; in s3c2410_nand_add_partition()
815 struct s3c2410_platform_nand *pdata = info->platform; in s3c2410_nand_setup_data_interface()
821 return -ENOTSUPP; in s3c2410_nand_setup_data_interface()
823 tacls = timings->tCLS_min - timings->tWP_min; in s3c2410_nand_setup_data_interface()
827 pdata->tacls = DIV_ROUND_UP(tacls, 1000); in s3c2410_nand_setup_data_interface()
828 pdata->twrph0 = DIV_ROUND_UP(timings->tWP_min, 1000); in s3c2410_nand_setup_data_interface()
829 pdata->twrph1 = DIV_ROUND_UP(timings->tCLH_min, 1000); in s3c2410_nand_setup_data_interface()
835 * s3c2410_nand_init_chip - initialise a single instance of an chip
836 * @info: The base NAND controller the chip is on.
848 struct device_node *np = info->device->of_node; in s3c2410_nand_init_chip()
849 struct nand_chip *chip = &nmtd->chip; in s3c2410_nand_init_chip()
850 void __iomem *regs = info->regs; in s3c2410_nand_init_chip()
852 nand_set_flash_node(chip, set->of_node); in s3c2410_nand_init_chip()
854 chip->legacy.write_buf = s3c2410_nand_write_buf; in s3c2410_nand_init_chip()
855 chip->legacy.read_buf = s3c2410_nand_read_buf; in s3c2410_nand_init_chip()
856 chip->legacy.select_chip = s3c2410_nand_select_chip; in s3c2410_nand_init_chip()
857 chip->legacy.chip_delay = 50; in s3c2410_nand_init_chip()
859 chip->options = set->options; in s3c2410_nand_init_chip()
860 chip->controller = &info->controller; in s3c2410_nand_init_chip()
864 * auto-detect timings only when booting with a device tree. in s3c2410_nand_init_chip()
867 chip->options |= NAND_KEEP_TIMINGS; in s3c2410_nand_init_chip()
869 switch (info->cpu_type) { in s3c2410_nand_init_chip()
871 chip->legacy.IO_ADDR_W = regs + S3C2410_NFDATA; in s3c2410_nand_init_chip()
872 info->sel_reg = regs + S3C2410_NFCONF; in s3c2410_nand_init_chip()
873 info->sel_bit = S3C2410_NFCONF_nFCE; in s3c2410_nand_init_chip()
874 chip->legacy.cmd_ctrl = s3c2410_nand_hwcontrol; in s3c2410_nand_init_chip()
875 chip->legacy.dev_ready = s3c2410_nand_devready; in s3c2410_nand_init_chip()
879 chip->legacy.IO_ADDR_W = regs + S3C2440_NFDATA; in s3c2410_nand_init_chip()
880 info->sel_reg = regs + S3C2440_NFCONT; in s3c2410_nand_init_chip()
881 info->sel_bit = S3C2440_NFCONT_nFCE; in s3c2410_nand_init_chip()
882 chip->legacy.cmd_ctrl = s3c2440_nand_hwcontrol; in s3c2410_nand_init_chip()
883 chip->legacy.dev_ready = s3c2440_nand_devready; in s3c2410_nand_init_chip()
884 chip->legacy.read_buf = s3c2440_nand_read_buf; in s3c2410_nand_init_chip()
885 chip->legacy.write_buf = s3c2440_nand_write_buf; in s3c2410_nand_init_chip()
889 chip->legacy.IO_ADDR_W = regs + S3C2440_NFDATA; in s3c2410_nand_init_chip()
890 info->sel_reg = regs + S3C2440_NFCONT; in s3c2410_nand_init_chip()
891 info->sel_bit = S3C2412_NFCONT_nFCE0; in s3c2410_nand_init_chip()
892 chip->legacy.cmd_ctrl = s3c2440_nand_hwcontrol; in s3c2410_nand_init_chip()
893 chip->legacy.dev_ready = s3c2412_nand_devready; in s3c2410_nand_init_chip()
896 dev_info(info->device, "System booted from NAND\n"); in s3c2410_nand_init_chip()
901 chip->legacy.IO_ADDR_R = chip->legacy.IO_ADDR_W; in s3c2410_nand_init_chip()
903 nmtd->info = info; in s3c2410_nand_init_chip()
904 nmtd->set = set; in s3c2410_nand_init_chip()
906 chip->ecc.mode = info->platform->ecc_mode; in s3c2410_nand_init_chip()
909 * If you use u-boot BBT creation code, specifying this flag will in s3c2410_nand_init_chip()
910 * let the kernel fish out the BBT from the NAND. in s3c2410_nand_init_chip()
912 if (set->flash_bbt) in s3c2410_nand_init_chip()
913 chip->bbt_options |= NAND_BBT_USE_FLASH; in s3c2410_nand_init_chip()
917 * s3c2410_nand_attach_chip - Init the ECC engine after NAND scan
918 * @chip: The NAND chip
920 * This hook is called by the core after the identification of the NAND chip,
921 * once the relevant per-chip information is up to date.. This call ensure that
924 * The internal state is currently limited to the ECC state information.
931 switch (chip->ecc.mode) { in s3c2410_nand_attach_chip()
934 dev_info(info->device, "ECC disabled\n"); in s3c2410_nand_attach_chip()
939 * This driver expects Hamming based ECC when ecc_mode is set in s3c2410_nand_attach_chip()
940 * to NAND_ECC_SOFT. Force ecc.algo to NAND_ECC_HAMMING to in s3c2410_nand_attach_chip()
944 chip->ecc.algo = NAND_ECC_HAMMING; in s3c2410_nand_attach_chip()
945 dev_info(info->device, "soft ECC\n"); in s3c2410_nand_attach_chip()
949 chip->ecc.calculate = s3c2410_nand_calculate_ecc; in s3c2410_nand_attach_chip()
950 chip->ecc.correct = s3c2410_nand_correct_data; in s3c2410_nand_attach_chip()
951 chip->ecc.strength = 1; in s3c2410_nand_attach_chip()
953 switch (info->cpu_type) { in s3c2410_nand_attach_chip()
955 chip->ecc.hwctl = s3c2410_nand_enable_hwecc; in s3c2410_nand_attach_chip()
956 chip->ecc.calculate = s3c2410_nand_calculate_ecc; in s3c2410_nand_attach_chip()
960 chip->ecc.hwctl = s3c2412_nand_enable_hwecc; in s3c2410_nand_attach_chip()
961 chip->ecc.calculate = s3c2412_nand_calculate_ecc; in s3c2410_nand_attach_chip()
965 chip->ecc.hwctl = s3c2440_nand_enable_hwecc; in s3c2410_nand_attach_chip()
966 chip->ecc.calculate = s3c2440_nand_calculate_ecc; in s3c2410_nand_attach_chip()
970 dev_dbg(info->device, "chip %p => page shift %d\n", in s3c2410_nand_attach_chip()
971 chip, chip->page_shift); in s3c2410_nand_attach_chip()
974 * the large or small page nand device */ in s3c2410_nand_attach_chip()
975 if (chip->page_shift > 10) { in s3c2410_nand_attach_chip()
976 chip->ecc.size = 256; in s3c2410_nand_attach_chip()
977 chip->ecc.bytes = 3; in s3c2410_nand_attach_chip()
979 chip->ecc.size = 512; in s3c2410_nand_attach_chip()
980 chip->ecc.bytes = 3; in s3c2410_nand_attach_chip()
985 dev_info(info->device, "hardware ECC\n"); in s3c2410_nand_attach_chip()
989 dev_err(info->device, "invalid ECC mode!\n"); in s3c2410_nand_attach_chip()
990 return -EINVAL; in s3c2410_nand_attach_chip()
993 if (chip->bbt_options & NAND_BBT_USE_FLASH) in s3c2410_nand_attach_chip()
994 chip->options |= NAND_SKIP_BBTSCAN; in s3c2410_nand_attach_chip()
1006 .compatible = "samsung,s3c2410-nand",
1010 .compatible = "samsung,s3c2412-nand",
1013 .compatible = "samsung,s3c2440-nand",
1025 struct device_node *np = pdev->dev.of_node, *child; in s3c24xx_nand_probe_dt()
1028 devtype_data = of_device_get_match_data(&pdev->dev); in s3c24xx_nand_probe_dt()
1030 return -ENODEV; in s3c24xx_nand_probe_dt()
1032 info->cpu_type = devtype_data->type; in s3c24xx_nand_probe_dt()
1034 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); in s3c24xx_nand_probe_dt()
1036 return -ENOMEM; in s3c24xx_nand_probe_dt()
1038 pdev->dev.platform_data = pdata; in s3c24xx_nand_probe_dt()
1040 pdata->nr_sets = of_get_child_count(np); in s3c24xx_nand_probe_dt()
1041 if (!pdata->nr_sets) in s3c24xx_nand_probe_dt()
1044 sets = devm_kcalloc(&pdev->dev, pdata->nr_sets, sizeof(*sets), in s3c24xx_nand_probe_dt()
1047 return -ENOMEM; in s3c24xx_nand_probe_dt()
1049 pdata->sets = sets; in s3c24xx_nand_probe_dt()
1052 sets->name = (char *)child->name; in s3c24xx_nand_probe_dt()
1053 sets->of_node = child; in s3c24xx_nand_probe_dt()
1054 sets->nr_chips = 1; in s3c24xx_nand_probe_dt()
1068 info->cpu_type = platform_get_device_id(pdev)->driver_data; in s3c24xx_nand_probe_pdata()
1078 * nand layer to look for devices
1092 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); in s3c24xx_nand_probe()
1094 err = -ENOMEM; in s3c24xx_nand_probe()
1100 nand_controller_init(&info->controller); in s3c24xx_nand_probe()
1101 info->controller.ops = &s3c24xx_nand_controller_ops; in s3c24xx_nand_probe()
1105 info->clk = devm_clk_get(&pdev->dev, "nand"); in s3c24xx_nand_probe()
1106 if (IS_ERR(info->clk)) { in s3c24xx_nand_probe()
1107 dev_err(&pdev->dev, "failed to get clock\n"); in s3c24xx_nand_probe()
1108 err = -ENOENT; in s3c24xx_nand_probe()
1114 if (pdev->dev.of_node) in s3c24xx_nand_probe()
1127 res = pdev->resource; in s3c24xx_nand_probe()
1130 info->device = &pdev->dev; in s3c24xx_nand_probe()
1131 info->platform = plat; in s3c24xx_nand_probe()
1133 info->regs = devm_ioremap_resource(&pdev->dev, res); in s3c24xx_nand_probe()
1134 if (IS_ERR(info->regs)) { in s3c24xx_nand_probe()
1135 err = PTR_ERR(info->regs); in s3c24xx_nand_probe()
1139 dev_dbg(&pdev->dev, "mapped registers at %p\n", info->regs); in s3c24xx_nand_probe()
1141 if (!plat->sets || plat->nr_sets < 1) { in s3c24xx_nand_probe()
1142 err = -EINVAL; in s3c24xx_nand_probe()
1146 sets = plat->sets; in s3c24xx_nand_probe()
1147 nr_sets = plat->nr_sets; in s3c24xx_nand_probe()
1149 info->mtd_count = nr_sets; in s3c24xx_nand_probe()
1153 size = nr_sets * sizeof(*info->mtds); in s3c24xx_nand_probe()
1154 info->mtds = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); in s3c24xx_nand_probe()
1155 if (info->mtds == NULL) { in s3c24xx_nand_probe()
1156 err = -ENOMEM; in s3c24xx_nand_probe()
1162 nmtd = info->mtds; in s3c24xx_nand_probe()
1165 struct mtd_info *mtd = nand_to_mtd(&nmtd->chip); in s3c24xx_nand_probe()
1170 mtd->dev.parent = &pdev->dev; in s3c24xx_nand_probe()
1173 err = nand_scan(&nmtd->chip, sets ? sets->nr_chips : 1); in s3c24xx_nand_probe()
1187 dev_err(&pdev->dev, "failed to init cpufreq support\n"); in s3c24xx_nand_probe()
1192 dev_info(&pdev->dev, "clock idle support enabled\n"); in s3c24xx_nand_probe()
1202 err = -EINVAL; in s3c24xx_nand_probe()
1214 info->save_sel = readl(info->sel_reg); in s3c24xx_nand_suspend()
1221 writel(info->save_sel | info->sel_bit, info->sel_reg); in s3c24xx_nand_suspend()
1240 sel = readl(info->sel_reg); in s3c24xx_nand_resume()
1241 sel &= ~info->sel_bit; in s3c24xx_nand_resume()
1242 sel |= info->save_sel & info->sel_bit; in s3c24xx_nand_resume()
1243 writel(sel, info->sel_reg); in s3c24xx_nand_resume()
1260 .name = "s3c2410-nand",
1263 .name = "s3c2440-nand",
1266 .name = "s3c2412-nand",
1269 .name = "s3c6400-nand",
1284 .name = "s3c24xx-nand",
1293 MODULE_DESCRIPTION("S3C24XX MTD NAND driver");