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
35 #include <linux/platform_data/mtd-nand-s3c2410.h>
72 /* new oob placement block for use with hardware ecc generation
78 return -ERANGE; in s3c2410_ooblayout_ecc()
80 oobregion->offset = 0; in s3c2410_ooblayout_ecc()
81 oobregion->length = 3; in s3c2410_ooblayout_ecc()
90 return -ERANGE; in s3c2410_ooblayout_free()
92 oobregion->offset = 8; in s3c2410_ooblayout_free()
93 oobregion->length = 8; in s3c2410_ooblayout_free()
99 .ecc = s3c2410_ooblayout_ecc,
108 * struct s3c2410_nand_mtd - driver MTD structure
110 * @chip: The NAND chip information.
111 * @set: The platform information supplied for this set of NAND chips.
132 /* overview of the s3c2410 nand state */
135 * 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.
201 return s3c2410_nand_mtd_toours(mtd)->info; in s3c2410_nand_mtd_toinfo()
211 return dev_get_platdata(&dev->dev); in to_nand_plat()
224 * s3c2410_nand_clk_set_state - Enable, disable or suspend NAND clock.
234 if (info->clk_state == CLOCK_ENABLE) { in s3c2410_nand_clk_set_state()
236 clk_disable_unprepare(info->clk); in s3c2410_nand_clk_set_state()
239 clk_prepare_enable(info->clk); in s3c2410_nand_clk_set_state()
242 info->clk_state = new_state; in s3c2410_nand_clk_set_state()
250 * s3c_nand_calc_rate - calculate timing data.
268 return -1; in s3c_nand_calc_rate()
282 * s3c2410_nand_setrate - setup controller timing information.
291 struct s3c2410_platform_nand *plat = info->platform; in s3c2410_nand_setrate()
292 int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4; in s3c2410_nand_setrate()
294 unsigned long clkrate = clk_get_rate(info->clk); in s3c2410_nand_setrate()
300 info->clk_rate = clkrate; in s3c2410_nand_setrate()
304 tacls = s3c_nand_calc_rate(plat->tacls, clkrate, tacls_max); in s3c2410_nand_setrate()
305 twrph0 = s3c_nand_calc_rate(plat->twrph0, clkrate, 8); in s3c2410_nand_setrate()
306 twrph1 = s3c_nand_calc_rate(plat->twrph1, clkrate, 8); in s3c2410_nand_setrate()
315 dev_err(info->device, "cannot get suitable timings\n"); in s3c2410_nand_setrate()
316 return -EINVAL; in s3c2410_nand_setrate()
319 dev_info(info->device, "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", in s3c2410_nand_setrate()
323 switch (info->cpu_type) { in s3c2410_nand_setrate()
329 set |= S3C2410_NFCONF_TACLS(tacls - 1); in s3c2410_nand_setrate()
330 set |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); in s3c2410_nand_setrate()
331 set |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); in s3c2410_nand_setrate()
336 mask = (S3C2440_NFCONF_TACLS(tacls_max - 1) | in s3c2410_nand_setrate()
340 set = S3C2440_NFCONF_TACLS(tacls - 1); in s3c2410_nand_setrate()
341 set |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); in s3c2410_nand_setrate()
342 set |= S3C2440_NFCONF_TWRPH1(twrph1 - 1); in s3c2410_nand_setrate()
351 cfg = readl(info->regs + S3C2410_NFCONF); in s3c2410_nand_setrate()
354 writel(cfg, info->regs + S3C2410_NFCONF); in s3c2410_nand_setrate()
358 dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg); in s3c2410_nand_setrate()
364 * s3c2410_nand_inithw - basic hardware initialisation
378 switch (info->cpu_type) { in s3c2410_nand_inithw()
385 /* enable the controller and de-assert nFCE */ in s3c2410_nand_inithw()
387 writel(S3C2440_NFCONT_ENABLE, info->regs + S3C2440_NFCONT); in s3c2410_nand_inithw()
394 * s3c2410_nand_select_chip - select the given nand chip
395 * @this: NAND chip object.
400 * chip can be de-selected.
413 info = nmtd->info; in s3c2410_nand_select_chip()
415 if (chip != -1) in s3c2410_nand_select_chip()
418 cur = readl(info->sel_reg); in s3c2410_nand_select_chip()
420 if (chip == -1) { in s3c2410_nand_select_chip()
421 cur |= info->sel_bit; in s3c2410_nand_select_chip()
423 if (nmtd->set != NULL && chip > nmtd->set->nr_chips) { in s3c2410_nand_select_chip()
424 dev_err(info->device, "invalid chip %d\n", chip); in s3c2410_nand_select_chip()
428 if (info->platform != NULL) { in s3c2410_nand_select_chip()
429 if (info->platform->select_chip != NULL) in s3c2410_nand_select_chip()
430 (info->platform->select_chip) (nmtd->set, chip); in s3c2410_nand_select_chip()
433 cur &= ~info->sel_bit; in s3c2410_nand_select_chip()
436 writel(cur, info->sel_reg); in s3c2410_nand_select_chip()
438 if (chip == -1) in s3c2410_nand_select_chip()
457 writeb(cmd, info->regs + S3C2410_NFCMD); in s3c2410_nand_hwcontrol()
459 writeb(cmd, info->regs + S3C2410_NFADDR); in s3c2410_nand_hwcontrol()
474 writeb(cmd, info->regs + S3C2440_NFCMD); in s3c2440_nand_hwcontrol()
476 writeb(cmd, info->regs + S3C2440_NFADDR); in s3c2440_nand_hwcontrol()
481 * returns 0 if the nand is busy, 1 if it is ready
488 return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; in s3c2410_nand_devready()
495 return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; in s3c2440_nand_devready()
502 return readb(info->regs + S3C2412_NFSTAT) & S3C2412_NFSTAT_READY; in s3c2412_nand_devready()
505 /* ECC handling functions */
526 return 0; /* ECC is ok */ in s3c2410_nand_correct_data()
528 /* sometimes people do not think about using the ECC, so check in s3c2410_nand_correct_data()
529 * to see if we have an 0xff,0xff,0xff read ECC and then ignore in s3c2410_nand_correct_data()
530 * the error, on the assumption that this is an un-eccd page. in s3c2410_nand_correct_data()
533 && info->platform->ignore_unset_ecc) in s3c2410_nand_correct_data()
536 /* Can we correct this ECC (ie, one row and column change). in s3c2410_nand_correct_data()
560 dev_dbg(info->device, "correcting error bit %d, byte %d\n", in s3c2410_nand_correct_data()
567 /* if there is only one bit difference in the ECC, then in s3c2410_nand_correct_data()
569 * means the error is most probably in the ECC itself */ in s3c2410_nand_correct_data()
575 if ((diff0 & (diff0 - 1)) == 0) in s3c2410_nand_correct_data()
578 return -1; in s3c2410_nand_correct_data()
581 /* ECC functions
583 * These allow the s3c2410 and s3c2440 to use the controller's ECC
584 * generator block to ECC the data as it passes through]
593 ctrl = readl(info->regs + S3C2410_NFCONF); in s3c2410_nand_enable_hwecc()
595 writel(ctrl, info->regs + S3C2410_NFCONF); in s3c2410_nand_enable_hwecc()
604 ctrl = readl(info->regs + S3C2440_NFCONT); in s3c2412_nand_enable_hwecc()
606 info->regs + S3C2440_NFCONT); in s3c2412_nand_enable_hwecc()
615 ctrl = readl(info->regs + S3C2440_NFCONT); in s3c2440_nand_enable_hwecc()
616 writel(ctrl | S3C2440_NFCONT_INITECC, info->regs + S3C2440_NFCONT); in s3c2440_nand_enable_hwecc()
625 ecc_code[0] = readb(info->regs + S3C2410_NFECC + 0); in s3c2410_nand_calculate_ecc()
626 ecc_code[1] = readb(info->regs + S3C2410_NFECC + 1); in s3c2410_nand_calculate_ecc()
627 ecc_code[2] = readb(info->regs + S3C2410_NFECC + 2); in s3c2410_nand_calculate_ecc()
629 pr_debug("%s: returning ecc %*phN\n", __func__, 3, ecc_code); in s3c2410_nand_calculate_ecc()
639 unsigned long ecc = readl(info->regs + S3C2412_NFMECC0); in s3c2412_nand_calculate_ecc() local
641 ecc_code[0] = ecc; in s3c2412_nand_calculate_ecc()
642 ecc_code[1] = ecc >> 8; in s3c2412_nand_calculate_ecc()
643 ecc_code[2] = ecc >> 16; in s3c2412_nand_calculate_ecc()
645 pr_debug("%s: returning ecc %*phN\n", __func__, 3, ecc_code); in s3c2412_nand_calculate_ecc()
655 unsigned long ecc = readl(info->regs + S3C2440_NFMECC0); in s3c2440_nand_calculate_ecc() local
657 ecc_code[0] = ecc; in s3c2440_nand_calculate_ecc()
658 ecc_code[1] = ecc >> 8; in s3c2440_nand_calculate_ecc()
659 ecc_code[2] = ecc >> 16; in s3c2440_nand_calculate_ecc()
661 pr_debug("%s: returning ecc %06lx\n", __func__, ecc & 0xffffff); in s3c2440_nand_calculate_ecc()
666 /* over-ride the standard functions for a little more speed. We can
672 readsb(this->legacy.IO_ADDR_R, buf, len); in s3c2410_nand_read_buf()
680 readsl(info->regs + S3C2440_NFDATA, buf, len >> 2); in s3c2440_nand_read_buf()
686 for (; len & 3; len--) in s3c2440_nand_read_buf()
687 *buf++ = readb(info->regs + S3C2440_NFDATA); in s3c2440_nand_read_buf()
694 writesb(this->legacy.IO_ADDR_W, buf, len); in s3c2410_nand_write_buf()
703 writesl(info->regs + S3C2440_NFDATA, buf, len >> 2); in s3c2440_nand_write_buf()
709 for (; len & 3; len--, buf++) in s3c2440_nand_write_buf()
710 writeb(*buf, info->regs + S3C2440_NFDATA); in s3c2440_nand_write_buf()
725 newclk = clk_get_rate(info->clk); in s3c2410_nand_cpufreq_transition()
727 if ((val == CPUFREQ_POSTCHANGE && newclk < info->clk_rate) || in s3c2410_nand_cpufreq_transition()
728 (val == CPUFREQ_PRECHANGE && newclk > info->clk_rate)) { in s3c2410_nand_cpufreq_transition()
737 info->freq_transition.notifier_call = s3c2410_nand_cpufreq_transition; in s3c2410_nand_cpufreq_register()
739 return cpufreq_register_notifier(&info->freq_transition, in s3c2410_nand_cpufreq_register()
746 cpufreq_unregister_notifier(&info->freq_transition, in s3c2410_nand_cpufreq_deregister()
777 if (info->mtds != NULL) { in s3c24xx_nand_remove()
778 struct s3c2410_nand_mtd *ptr = info->mtds; in s3c24xx_nand_remove()
781 for (mtdno = 0; mtdno < info->mtd_count; mtdno++, ptr++) { in s3c24xx_nand_remove()
783 WARN_ON(mtd_device_unregister(nand_to_mtd(&ptr->chip))); in s3c24xx_nand_remove()
784 nand_cleanup(&ptr->chip); in s3c24xx_nand_remove()
790 if (!IS_ERR(info->clk)) in s3c24xx_nand_remove()
801 struct mtd_info *mtdinfo = nand_to_mtd(&mtd->chip); in s3c2410_nand_add_partition()
803 mtdinfo->name = set->name; in s3c2410_nand_add_partition()
805 return mtd_device_register(mtdinfo, set->partitions, in s3c2410_nand_add_partition()
806 set->nr_partitions); in s3c2410_nand_add_partition()
809 return -ENODEV; in s3c2410_nand_add_partition()
817 struct s3c2410_platform_nand *pdata = info->platform; in s3c2410_nand_setup_interface()
823 return -ENOTSUPP; in s3c2410_nand_setup_interface()
825 tacls = timings->tCLS_min - timings->tWP_min; in s3c2410_nand_setup_interface()
829 pdata->tacls = DIV_ROUND_UP(tacls, 1000); in s3c2410_nand_setup_interface()
830 pdata->twrph0 = DIV_ROUND_UP(timings->tWP_min, 1000); in s3c2410_nand_setup_interface()
831 pdata->twrph1 = DIV_ROUND_UP(timings->tCLH_min, 1000); in s3c2410_nand_setup_interface()
837 * s3c2410_nand_init_chip - initialise a single instance of an chip
838 * @info: The base NAND controller the chip is on.
850 struct device_node *np = info->device->of_node; in s3c2410_nand_init_chip()
851 struct nand_chip *chip = &nmtd->chip; in s3c2410_nand_init_chip()
852 void __iomem *regs = info->regs; in s3c2410_nand_init_chip()
854 nand_set_flash_node(chip, set->of_node); in s3c2410_nand_init_chip()
856 chip->legacy.write_buf = s3c2410_nand_write_buf; in s3c2410_nand_init_chip()
857 chip->legacy.read_buf = s3c2410_nand_read_buf; in s3c2410_nand_init_chip()
858 chip->legacy.select_chip = s3c2410_nand_select_chip; in s3c2410_nand_init_chip()
859 chip->legacy.chip_delay = 50; in s3c2410_nand_init_chip()
861 chip->options = set->options; in s3c2410_nand_init_chip()
862 chip->controller = &info->controller; in s3c2410_nand_init_chip()
866 * auto-detect timings only when booting with a device tree. in s3c2410_nand_init_chip()
869 chip->options |= NAND_KEEP_TIMINGS; in s3c2410_nand_init_chip()
871 switch (info->cpu_type) { in s3c2410_nand_init_chip()
873 chip->legacy.IO_ADDR_W = regs + S3C2410_NFDATA; in s3c2410_nand_init_chip()
874 info->sel_reg = regs + S3C2410_NFCONF; in s3c2410_nand_init_chip()
875 info->sel_bit = S3C2410_NFCONF_nFCE; in s3c2410_nand_init_chip()
876 chip->legacy.cmd_ctrl = s3c2410_nand_hwcontrol; in s3c2410_nand_init_chip()
877 chip->legacy.dev_ready = s3c2410_nand_devready; in s3c2410_nand_init_chip()
881 chip->legacy.IO_ADDR_W = regs + S3C2440_NFDATA; in s3c2410_nand_init_chip()
882 info->sel_reg = regs + S3C2440_NFCONT; in s3c2410_nand_init_chip()
883 info->sel_bit = S3C2440_NFCONT_nFCE; in s3c2410_nand_init_chip()
884 chip->legacy.cmd_ctrl = s3c2440_nand_hwcontrol; in s3c2410_nand_init_chip()
885 chip->legacy.dev_ready = s3c2440_nand_devready; in s3c2410_nand_init_chip()
886 chip->legacy.read_buf = s3c2440_nand_read_buf; in s3c2410_nand_init_chip()
887 chip->legacy.write_buf = s3c2440_nand_write_buf; in s3c2410_nand_init_chip()
891 chip->legacy.IO_ADDR_W = regs + S3C2440_NFDATA; in s3c2410_nand_init_chip()
892 info->sel_reg = regs + S3C2440_NFCONT; in s3c2410_nand_init_chip()
893 info->sel_bit = S3C2412_NFCONT_nFCE0; in s3c2410_nand_init_chip()
894 chip->legacy.cmd_ctrl = s3c2440_nand_hwcontrol; in s3c2410_nand_init_chip()
895 chip->legacy.dev_ready = s3c2412_nand_devready; in s3c2410_nand_init_chip()
898 dev_info(info->device, "System booted from NAND\n"); in s3c2410_nand_init_chip()
903 chip->legacy.IO_ADDR_R = chip->legacy.IO_ADDR_W; in s3c2410_nand_init_chip()
905 nmtd->info = info; in s3c2410_nand_init_chip()
906 nmtd->set = set; in s3c2410_nand_init_chip()
908 chip->ecc.engine_type = info->platform->engine_type; in s3c2410_nand_init_chip()
911 * If you use u-boot BBT creation code, specifying this flag will in s3c2410_nand_init_chip()
912 * let the kernel fish out the BBT from the NAND. in s3c2410_nand_init_chip()
914 if (set->flash_bbt) in s3c2410_nand_init_chip()
915 chip->bbt_options |= NAND_BBT_USE_FLASH; in s3c2410_nand_init_chip()
919 * s3c2410_nand_attach_chip - Init the ECC engine after NAND scan
920 * @chip: The NAND chip
922 * This hook is called by the core after the identification of the NAND chip,
923 * once the relevant per-chip information is up to date.. This call ensure that
926 * The internal state is currently limited to the ECC state information.
933 switch (chip->ecc.engine_type) { in s3c2410_nand_attach_chip()
936 dev_info(info->device, "ECC disabled\n"); in s3c2410_nand_attach_chip()
941 * This driver expects Hamming based ECC when engine_type is set in s3c2410_nand_attach_chip()
942 * to NAND_ECC_ENGINE_TYPE_SOFT. Force ecc.algo to in s3c2410_nand_attach_chip()
946 chip->ecc.algo = NAND_ECC_ALGO_HAMMING; in s3c2410_nand_attach_chip()
947 dev_info(info->device, "soft ECC\n"); in s3c2410_nand_attach_chip()
951 chip->ecc.calculate = s3c2410_nand_calculate_ecc; in s3c2410_nand_attach_chip()
952 chip->ecc.correct = s3c2410_nand_correct_data; in s3c2410_nand_attach_chip()
953 chip->ecc.strength = 1; in s3c2410_nand_attach_chip()
955 switch (info->cpu_type) { in s3c2410_nand_attach_chip()
957 chip->ecc.hwctl = s3c2410_nand_enable_hwecc; in s3c2410_nand_attach_chip()
958 chip->ecc.calculate = s3c2410_nand_calculate_ecc; in s3c2410_nand_attach_chip()
962 chip->ecc.hwctl = s3c2412_nand_enable_hwecc; in s3c2410_nand_attach_chip()
963 chip->ecc.calculate = s3c2412_nand_calculate_ecc; in s3c2410_nand_attach_chip()
967 chip->ecc.hwctl = s3c2440_nand_enable_hwecc; in s3c2410_nand_attach_chip()
968 chip->ecc.calculate = s3c2440_nand_calculate_ecc; in s3c2410_nand_attach_chip()
972 dev_dbg(info->device, "chip %p => page shift %d\n", in s3c2410_nand_attach_chip()
973 chip, chip->page_shift); in s3c2410_nand_attach_chip()
976 * the large or small page nand device */ in s3c2410_nand_attach_chip()
977 if (chip->page_shift > 10) { in s3c2410_nand_attach_chip()
978 chip->ecc.size = 256; in s3c2410_nand_attach_chip()
979 chip->ecc.bytes = 3; in s3c2410_nand_attach_chip()
981 chip->ecc.size = 512; in s3c2410_nand_attach_chip()
982 chip->ecc.bytes = 3; in s3c2410_nand_attach_chip()
987 dev_info(info->device, "hardware ECC\n"); in s3c2410_nand_attach_chip()
991 dev_err(info->device, "invalid ECC mode!\n"); in s3c2410_nand_attach_chip()
992 return -EINVAL; in s3c2410_nand_attach_chip()
995 if (chip->bbt_options & NAND_BBT_USE_FLASH) in s3c2410_nand_attach_chip()
996 chip->options |= NAND_SKIP_BBTSCAN; in s3c2410_nand_attach_chip()
1008 .compatible = "samsung,s3c2410-nand",
1012 .compatible = "samsung,s3c2412-nand",
1015 .compatible = "samsung,s3c2440-nand",
1027 struct device_node *np = pdev->dev.of_node, *child; in s3c24xx_nand_probe_dt()
1030 devtype_data = of_device_get_match_data(&pdev->dev); in s3c24xx_nand_probe_dt()
1032 return -ENODEV; in s3c24xx_nand_probe_dt()
1034 info->cpu_type = devtype_data->type; in s3c24xx_nand_probe_dt()
1036 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); in s3c24xx_nand_probe_dt()
1038 return -ENOMEM; in s3c24xx_nand_probe_dt()
1040 pdev->dev.platform_data = pdata; in s3c24xx_nand_probe_dt()
1042 pdata->nr_sets = of_get_child_count(np); in s3c24xx_nand_probe_dt()
1043 if (!pdata->nr_sets) in s3c24xx_nand_probe_dt()
1046 sets = devm_kcalloc(&pdev->dev, pdata->nr_sets, sizeof(*sets), in s3c24xx_nand_probe_dt()
1049 return -ENOMEM; in s3c24xx_nand_probe_dt()
1051 pdata->sets = sets; in s3c24xx_nand_probe_dt()
1054 sets->name = (char *)child->name; in s3c24xx_nand_probe_dt()
1055 sets->of_node = child; in s3c24xx_nand_probe_dt()
1056 sets->nr_chips = 1; in s3c24xx_nand_probe_dt()
1070 info->cpu_type = platform_get_device_id(pdev)->driver_data; in s3c24xx_nand_probe_pdata()
1080 * nand layer to look for devices
1094 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); in s3c24xx_nand_probe()
1096 err = -ENOMEM; in s3c24xx_nand_probe()
1102 nand_controller_init(&info->controller); in s3c24xx_nand_probe()
1103 info->controller.ops = &s3c24xx_nand_controller_ops; in s3c24xx_nand_probe()
1107 info->clk = devm_clk_get(&pdev->dev, "nand"); in s3c24xx_nand_probe()
1108 if (IS_ERR(info->clk)) { in s3c24xx_nand_probe()
1109 dev_err(&pdev->dev, "failed to get clock\n"); in s3c24xx_nand_probe()
1110 err = -ENOENT; in s3c24xx_nand_probe()
1116 if (pdev->dev.of_node) in s3c24xx_nand_probe()
1129 res = pdev->resource; in s3c24xx_nand_probe()
1132 info->device = &pdev->dev; in s3c24xx_nand_probe()
1133 info->platform = plat; in s3c24xx_nand_probe()
1135 info->regs = devm_ioremap_resource(&pdev->dev, res); in s3c24xx_nand_probe()
1136 if (IS_ERR(info->regs)) { in s3c24xx_nand_probe()
1137 err = PTR_ERR(info->regs); in s3c24xx_nand_probe()
1141 dev_dbg(&pdev->dev, "mapped registers at %p\n", info->regs); in s3c24xx_nand_probe()
1143 if (!plat->sets || plat->nr_sets < 1) { in s3c24xx_nand_probe()
1144 err = -EINVAL; in s3c24xx_nand_probe()
1148 sets = plat->sets; in s3c24xx_nand_probe()
1149 nr_sets = plat->nr_sets; in s3c24xx_nand_probe()
1151 info->mtd_count = nr_sets; in s3c24xx_nand_probe()
1155 size = nr_sets * sizeof(*info->mtds); in s3c24xx_nand_probe()
1156 info->mtds = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); in s3c24xx_nand_probe()
1157 if (info->mtds == NULL) { in s3c24xx_nand_probe()
1158 err = -ENOMEM; in s3c24xx_nand_probe()
1164 nmtd = info->mtds; in s3c24xx_nand_probe()
1167 struct mtd_info *mtd = nand_to_mtd(&nmtd->chip); in s3c24xx_nand_probe()
1172 mtd->dev.parent = &pdev->dev; in s3c24xx_nand_probe()
1175 err = nand_scan(&nmtd->chip, sets ? sets->nr_chips : 1); in s3c24xx_nand_probe()
1189 dev_err(&pdev->dev, "failed to init cpufreq support\n"); in s3c24xx_nand_probe()
1194 dev_info(&pdev->dev, "clock idle support enabled\n"); in s3c24xx_nand_probe()
1204 err = -EINVAL; in s3c24xx_nand_probe()
1216 info->save_sel = readl(info->sel_reg); in s3c24xx_nand_suspend()
1223 writel(info->save_sel | info->sel_bit, info->sel_reg); in s3c24xx_nand_suspend()
1242 sel = readl(info->sel_reg); in s3c24xx_nand_resume()
1243 sel &= ~info->sel_bit; in s3c24xx_nand_resume()
1244 sel |= info->save_sel & info->sel_bit; in s3c24xx_nand_resume()
1245 writel(sel, info->sel_reg); in s3c24xx_nand_resume()
1262 .name = "s3c2410-nand",
1265 .name = "s3c2440-nand",
1268 .name = "s3c2412-nand",
1271 .name = "s3c6400-nand",
1286 .name = "s3c24xx-nand",
1295 MODULE_DESCRIPTION("S3C24XX MTD NAND driver");