Lines Matching +full:nand +full:- +full:ecc +full:- +full:placement
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 WARN_ON(mtd_device_unregister(nand_to_mtd(&ptr->chip))); in s3c24xx_nand_remove()
783 nand_cleanup(&ptr->chip); in s3c24xx_nand_remove()
789 if (!IS_ERR(info->clk)) in s3c24xx_nand_remove()
800 struct mtd_info *mtdinfo = nand_to_mtd(&mtd->chip); in s3c2410_nand_add_partition()
802 mtdinfo->name = set->name; in s3c2410_nand_add_partition()
804 return mtd_device_register(mtdinfo, set->partitions, in s3c2410_nand_add_partition()
805 set->nr_partitions); in s3c2410_nand_add_partition()
808 return -ENODEV; in s3c2410_nand_add_partition()
816 struct s3c2410_platform_nand *pdata = info->platform; in s3c2410_nand_setup_interface()
822 return -ENOTSUPP; in s3c2410_nand_setup_interface()
824 tacls = timings->tCLS_min - timings->tWP_min; in s3c2410_nand_setup_interface()
828 pdata->tacls = DIV_ROUND_UP(tacls, 1000); in s3c2410_nand_setup_interface()
829 pdata->twrph0 = DIV_ROUND_UP(timings->tWP_min, 1000); in s3c2410_nand_setup_interface()
830 pdata->twrph1 = DIV_ROUND_UP(timings->tCLH_min, 1000); in s3c2410_nand_setup_interface()
836 * s3c2410_nand_init_chip - initialise a single instance of an chip
837 * @info: The base NAND controller the chip is on.
849 struct device_node *np = info->device->of_node; in s3c2410_nand_init_chip()
850 struct nand_chip *chip = &nmtd->chip; in s3c2410_nand_init_chip()
851 void __iomem *regs = info->regs; in s3c2410_nand_init_chip()
853 nand_set_flash_node(chip, set->of_node); in s3c2410_nand_init_chip()
855 chip->legacy.write_buf = s3c2410_nand_write_buf; in s3c2410_nand_init_chip()
856 chip->legacy.read_buf = s3c2410_nand_read_buf; in s3c2410_nand_init_chip()
857 chip->legacy.select_chip = s3c2410_nand_select_chip; in s3c2410_nand_init_chip()
858 chip->legacy.chip_delay = 50; in s3c2410_nand_init_chip()
860 chip->options = set->options; in s3c2410_nand_init_chip()
861 chip->controller = &info->controller; in s3c2410_nand_init_chip()
865 * auto-detect timings only when booting with a device tree. in s3c2410_nand_init_chip()
868 chip->options |= NAND_KEEP_TIMINGS; in s3c2410_nand_init_chip()
870 switch (info->cpu_type) { in s3c2410_nand_init_chip()
872 chip->legacy.IO_ADDR_W = regs + S3C2410_NFDATA; in s3c2410_nand_init_chip()
873 info->sel_reg = regs + S3C2410_NFCONF; in s3c2410_nand_init_chip()
874 info->sel_bit = S3C2410_NFCONF_nFCE; in s3c2410_nand_init_chip()
875 chip->legacy.cmd_ctrl = s3c2410_nand_hwcontrol; in s3c2410_nand_init_chip()
876 chip->legacy.dev_ready = s3c2410_nand_devready; in s3c2410_nand_init_chip()
880 chip->legacy.IO_ADDR_W = regs + S3C2440_NFDATA; in s3c2410_nand_init_chip()
881 info->sel_reg = regs + S3C2440_NFCONT; in s3c2410_nand_init_chip()
882 info->sel_bit = S3C2440_NFCONT_nFCE; in s3c2410_nand_init_chip()
883 chip->legacy.cmd_ctrl = s3c2440_nand_hwcontrol; in s3c2410_nand_init_chip()
884 chip->legacy.dev_ready = s3c2440_nand_devready; in s3c2410_nand_init_chip()
885 chip->legacy.read_buf = s3c2440_nand_read_buf; in s3c2410_nand_init_chip()
886 chip->legacy.write_buf = s3c2440_nand_write_buf; in s3c2410_nand_init_chip()
890 chip->legacy.IO_ADDR_W = regs + S3C2440_NFDATA; in s3c2410_nand_init_chip()
891 info->sel_reg = regs + S3C2440_NFCONT; in s3c2410_nand_init_chip()
892 info->sel_bit = S3C2412_NFCONT_nFCE0; in s3c2410_nand_init_chip()
893 chip->legacy.cmd_ctrl = s3c2440_nand_hwcontrol; in s3c2410_nand_init_chip()
894 chip->legacy.dev_ready = s3c2412_nand_devready; in s3c2410_nand_init_chip()
897 dev_info(info->device, "System booted from NAND\n"); in s3c2410_nand_init_chip()
902 chip->legacy.IO_ADDR_R = chip->legacy.IO_ADDR_W; in s3c2410_nand_init_chip()
904 nmtd->info = info; in s3c2410_nand_init_chip()
905 nmtd->set = set; in s3c2410_nand_init_chip()
907 chip->ecc.engine_type = info->platform->engine_type; in s3c2410_nand_init_chip()
910 * If you use u-boot BBT creation code, specifying this flag will in s3c2410_nand_init_chip()
911 * let the kernel fish out the BBT from the NAND. in s3c2410_nand_init_chip()
913 if (set->flash_bbt) in s3c2410_nand_init_chip()
914 chip->bbt_options |= NAND_BBT_USE_FLASH; in s3c2410_nand_init_chip()
918 * s3c2410_nand_attach_chip - Init the ECC engine after NAND scan
919 * @chip: The NAND chip
921 * This hook is called by the core after the identification of the NAND chip,
922 * once the relevant per-chip information is up to date.. This call ensure that
925 * The internal state is currently limited to the ECC state information.
932 switch (chip->ecc.engine_type) { in s3c2410_nand_attach_chip()
935 dev_info(info->device, "ECC disabled\n"); in s3c2410_nand_attach_chip()
940 * This driver expects Hamming based ECC when engine_type is set in s3c2410_nand_attach_chip()
941 * to NAND_ECC_ENGINE_TYPE_SOFT. Force ecc.algo to in s3c2410_nand_attach_chip()
945 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; in s3c2410_nand_attach_chip()
946 dev_info(info->device, "soft ECC\n"); in s3c2410_nand_attach_chip()
950 chip->ecc.calculate = s3c2410_nand_calculate_ecc; in s3c2410_nand_attach_chip()
951 chip->ecc.correct = s3c2410_nand_correct_data; in s3c2410_nand_attach_chip()
952 chip->ecc.strength = 1; in s3c2410_nand_attach_chip()
954 switch (info->cpu_type) { in s3c2410_nand_attach_chip()
956 chip->ecc.hwctl = s3c2410_nand_enable_hwecc; in s3c2410_nand_attach_chip()
957 chip->ecc.calculate = s3c2410_nand_calculate_ecc; in s3c2410_nand_attach_chip()
961 chip->ecc.hwctl = s3c2412_nand_enable_hwecc; in s3c2410_nand_attach_chip()
962 chip->ecc.calculate = s3c2412_nand_calculate_ecc; in s3c2410_nand_attach_chip()
966 chip->ecc.hwctl = s3c2440_nand_enable_hwecc; in s3c2410_nand_attach_chip()
967 chip->ecc.calculate = s3c2440_nand_calculate_ecc; in s3c2410_nand_attach_chip()
971 dev_dbg(info->device, "chip %p => page shift %d\n", in s3c2410_nand_attach_chip()
972 chip, chip->page_shift); in s3c2410_nand_attach_chip()
975 * the large or small page nand device */ in s3c2410_nand_attach_chip()
976 if (chip->page_shift > 10) { in s3c2410_nand_attach_chip()
977 chip->ecc.size = 256; in s3c2410_nand_attach_chip()
978 chip->ecc.bytes = 3; in s3c2410_nand_attach_chip()
980 chip->ecc.size = 512; in s3c2410_nand_attach_chip()
981 chip->ecc.bytes = 3; in s3c2410_nand_attach_chip()
986 dev_info(info->device, "hardware ECC\n"); in s3c2410_nand_attach_chip()
990 dev_err(info->device, "invalid ECC mode!\n"); in s3c2410_nand_attach_chip()
991 return -EINVAL; in s3c2410_nand_attach_chip()
994 if (chip->bbt_options & NAND_BBT_USE_FLASH) in s3c2410_nand_attach_chip()
995 chip->options |= NAND_SKIP_BBTSCAN; in s3c2410_nand_attach_chip()
1007 .compatible = "samsung,s3c2410-nand",
1011 .compatible = "samsung,s3c2412-nand",
1014 .compatible = "samsung,s3c2440-nand",
1026 struct device_node *np = pdev->dev.of_node, *child; in s3c24xx_nand_probe_dt()
1029 devtype_data = of_device_get_match_data(&pdev->dev); in s3c24xx_nand_probe_dt()
1031 return -ENODEV; in s3c24xx_nand_probe_dt()
1033 info->cpu_type = devtype_data->type; in s3c24xx_nand_probe_dt()
1035 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); in s3c24xx_nand_probe_dt()
1037 return -ENOMEM; in s3c24xx_nand_probe_dt()
1039 pdev->dev.platform_data = pdata; in s3c24xx_nand_probe_dt()
1041 pdata->nr_sets = of_get_child_count(np); in s3c24xx_nand_probe_dt()
1042 if (!pdata->nr_sets) in s3c24xx_nand_probe_dt()
1045 sets = devm_kcalloc(&pdev->dev, pdata->nr_sets, sizeof(*sets), in s3c24xx_nand_probe_dt()
1048 return -ENOMEM; in s3c24xx_nand_probe_dt()
1050 pdata->sets = sets; in s3c24xx_nand_probe_dt()
1053 sets->name = (char *)child->name; in s3c24xx_nand_probe_dt()
1054 sets->of_node = child; in s3c24xx_nand_probe_dt()
1055 sets->nr_chips = 1; in s3c24xx_nand_probe_dt()
1069 info->cpu_type = platform_get_device_id(pdev)->driver_data; in s3c24xx_nand_probe_pdata()
1079 * nand layer to look for devices
1093 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); in s3c24xx_nand_probe()
1095 err = -ENOMEM; in s3c24xx_nand_probe()
1101 nand_controller_init(&info->controller); in s3c24xx_nand_probe()
1102 info->controller.ops = &s3c24xx_nand_controller_ops; in s3c24xx_nand_probe()
1106 info->clk = devm_clk_get(&pdev->dev, "nand"); in s3c24xx_nand_probe()
1107 if (IS_ERR(info->clk)) { in s3c24xx_nand_probe()
1108 dev_err(&pdev->dev, "failed to get clock\n"); in s3c24xx_nand_probe()
1109 err = -ENOENT; in s3c24xx_nand_probe()
1115 if (pdev->dev.of_node) in s3c24xx_nand_probe()
1128 res = pdev->resource; in s3c24xx_nand_probe()
1131 info->device = &pdev->dev; in s3c24xx_nand_probe()
1132 info->platform = plat; in s3c24xx_nand_probe()
1134 info->regs = devm_ioremap_resource(&pdev->dev, res); in s3c24xx_nand_probe()
1135 if (IS_ERR(info->regs)) { in s3c24xx_nand_probe()
1136 err = PTR_ERR(info->regs); in s3c24xx_nand_probe()
1140 dev_dbg(&pdev->dev, "mapped registers at %p\n", info->regs); in s3c24xx_nand_probe()
1142 if (!plat->sets || plat->nr_sets < 1) { in s3c24xx_nand_probe()
1143 err = -EINVAL; in s3c24xx_nand_probe()
1147 sets = plat->sets; in s3c24xx_nand_probe()
1148 nr_sets = plat->nr_sets; in s3c24xx_nand_probe()
1150 info->mtd_count = nr_sets; in s3c24xx_nand_probe()
1154 size = nr_sets * sizeof(*info->mtds); in s3c24xx_nand_probe()
1155 info->mtds = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); in s3c24xx_nand_probe()
1156 if (info->mtds == NULL) { in s3c24xx_nand_probe()
1157 err = -ENOMEM; in s3c24xx_nand_probe()
1163 nmtd = info->mtds; in s3c24xx_nand_probe()
1166 struct mtd_info *mtd = nand_to_mtd(&nmtd->chip); in s3c24xx_nand_probe()
1171 mtd->dev.parent = &pdev->dev; in s3c24xx_nand_probe()
1174 err = nand_scan(&nmtd->chip, sets ? sets->nr_chips : 1); in s3c24xx_nand_probe()
1188 dev_err(&pdev->dev, "failed to init cpufreq support\n"); in s3c24xx_nand_probe()
1193 dev_info(&pdev->dev, "clock idle support enabled\n"); in s3c24xx_nand_probe()
1203 err = -EINVAL; in s3c24xx_nand_probe()
1215 info->save_sel = readl(info->sel_reg); in s3c24xx_nand_suspend()
1222 writel(info->save_sel | info->sel_bit, info->sel_reg); in s3c24xx_nand_suspend()
1241 sel = readl(info->sel_reg); in s3c24xx_nand_resume()
1242 sel &= ~info->sel_bit; in s3c24xx_nand_resume()
1243 sel |= info->save_sel & info->sel_bit; in s3c24xx_nand_resume()
1244 writel(sel, info->sel_reg); in s3c24xx_nand_resume()
1261 .name = "s3c2410-nand",
1264 .name = "s3c2440-nand",
1267 .name = "s3c2412-nand",
1270 .name = "s3c6400-nand",
1285 .name = "s3c24xx-nand",
1294 MODULE_DESCRIPTION("S3C24XX MTD NAND driver");