oxnas_nand.c (4932B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Oxford Semiconductor OXNAS NAND driver 4 5 * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com> 6 * Heavily based on plat_nand.c : 7 * Author: Vitaly Wool <vitalywool@gmail.com> 8 * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com> 9 * Copyright (C) 2012 John Crispin <blogic@openwrt.org> 10 */ 11 12#include <linux/err.h> 13#include <linux/io.h> 14#include <linux/module.h> 15#include <linux/platform_device.h> 16#include <linux/slab.h> 17#include <linux/clk.h> 18#include <linux/reset.h> 19#include <linux/mtd/mtd.h> 20#include <linux/mtd/rawnand.h> 21#include <linux/mtd/partitions.h> 22#include <linux/of.h> 23 24/* Nand commands */ 25#define OXNAS_NAND_CMD_ALE BIT(18) 26#define OXNAS_NAND_CMD_CLE BIT(19) 27 28#define OXNAS_NAND_MAX_CHIPS 1 29 30struct oxnas_nand_ctrl { 31 struct nand_controller base; 32 void __iomem *io_base; 33 struct clk *clk; 34 struct nand_chip *chips[OXNAS_NAND_MAX_CHIPS]; 35 unsigned int nchips; 36}; 37 38static uint8_t oxnas_nand_read_byte(struct nand_chip *chip) 39{ 40 struct oxnas_nand_ctrl *oxnas = nand_get_controller_data(chip); 41 42 return readb(oxnas->io_base); 43} 44 45static void oxnas_nand_read_buf(struct nand_chip *chip, u8 *buf, int len) 46{ 47 struct oxnas_nand_ctrl *oxnas = nand_get_controller_data(chip); 48 49 ioread8_rep(oxnas->io_base, buf, len); 50} 51 52static void oxnas_nand_write_buf(struct nand_chip *chip, const u8 *buf, 53 int len) 54{ 55 struct oxnas_nand_ctrl *oxnas = nand_get_controller_data(chip); 56 57 iowrite8_rep(oxnas->io_base, buf, len); 58} 59 60/* Single CS command control */ 61static void oxnas_nand_cmd_ctrl(struct nand_chip *chip, int cmd, 62 unsigned int ctrl) 63{ 64 struct oxnas_nand_ctrl *oxnas = nand_get_controller_data(chip); 65 66 if (ctrl & NAND_CLE) 67 writeb(cmd, oxnas->io_base + OXNAS_NAND_CMD_CLE); 68 else if (ctrl & NAND_ALE) 69 writeb(cmd, oxnas->io_base + OXNAS_NAND_CMD_ALE); 70} 71 72/* 73 * Probe for the NAND device. 74 */ 75static int oxnas_nand_probe(struct platform_device *pdev) 76{ 77 struct device_node *np = pdev->dev.of_node; 78 struct device_node *nand_np; 79 struct oxnas_nand_ctrl *oxnas; 80 struct nand_chip *chip; 81 struct mtd_info *mtd; 82 int count = 0; 83 int err = 0; 84 int i; 85 86 /* Allocate memory for the device structure (and zero it) */ 87 oxnas = devm_kzalloc(&pdev->dev, sizeof(*oxnas), 88 GFP_KERNEL); 89 if (!oxnas) 90 return -ENOMEM; 91 92 nand_controller_init(&oxnas->base); 93 94 oxnas->io_base = devm_platform_ioremap_resource(pdev, 0); 95 if (IS_ERR(oxnas->io_base)) 96 return PTR_ERR(oxnas->io_base); 97 98 oxnas->clk = devm_clk_get(&pdev->dev, NULL); 99 if (IS_ERR(oxnas->clk)) 100 oxnas->clk = NULL; 101 102 /* Only a single chip node is supported */ 103 count = of_get_child_count(np); 104 if (count > 1) 105 return -EINVAL; 106 107 err = clk_prepare_enable(oxnas->clk); 108 if (err) 109 return err; 110 111 device_reset_optional(&pdev->dev); 112 113 for_each_child_of_node(np, nand_np) { 114 chip = devm_kzalloc(&pdev->dev, sizeof(struct nand_chip), 115 GFP_KERNEL); 116 if (!chip) { 117 err = -ENOMEM; 118 goto err_release_child; 119 } 120 121 chip->controller = &oxnas->base; 122 123 nand_set_flash_node(chip, nand_np); 124 nand_set_controller_data(chip, oxnas); 125 126 mtd = nand_to_mtd(chip); 127 mtd->dev.parent = &pdev->dev; 128 mtd->priv = chip; 129 130 chip->legacy.cmd_ctrl = oxnas_nand_cmd_ctrl; 131 chip->legacy.read_buf = oxnas_nand_read_buf; 132 chip->legacy.read_byte = oxnas_nand_read_byte; 133 chip->legacy.write_buf = oxnas_nand_write_buf; 134 chip->legacy.chip_delay = 30; 135 136 /* Scan to find existence of the device */ 137 err = nand_scan(chip, 1); 138 if (err) 139 goto err_release_child; 140 141 err = mtd_device_register(mtd, NULL, 0); 142 if (err) 143 goto err_cleanup_nand; 144 145 oxnas->chips[oxnas->nchips++] = chip; 146 } 147 148 /* Exit if no chips found */ 149 if (!oxnas->nchips) { 150 err = -ENODEV; 151 goto err_clk_unprepare; 152 } 153 154 platform_set_drvdata(pdev, oxnas); 155 156 return 0; 157 158err_cleanup_nand: 159 nand_cleanup(chip); 160err_release_child: 161 of_node_put(nand_np); 162 163 for (i = 0; i < oxnas->nchips; i++) { 164 chip = oxnas->chips[i]; 165 WARN_ON(mtd_device_unregister(nand_to_mtd(chip))); 166 nand_cleanup(chip); 167 } 168 169err_clk_unprepare: 170 clk_disable_unprepare(oxnas->clk); 171 return err; 172} 173 174static int oxnas_nand_remove(struct platform_device *pdev) 175{ 176 struct oxnas_nand_ctrl *oxnas = platform_get_drvdata(pdev); 177 struct nand_chip *chip; 178 int i; 179 180 for (i = 0; i < oxnas->nchips; i++) { 181 chip = oxnas->chips[i]; 182 WARN_ON(mtd_device_unregister(nand_to_mtd(chip))); 183 nand_cleanup(chip); 184 } 185 186 clk_disable_unprepare(oxnas->clk); 187 188 return 0; 189} 190 191static const struct of_device_id oxnas_nand_match[] = { 192 { .compatible = "oxsemi,ox820-nand" }, 193 {}, 194}; 195MODULE_DEVICE_TABLE(of, oxnas_nand_match); 196 197static struct platform_driver oxnas_nand_driver = { 198 .probe = oxnas_nand_probe, 199 .remove = oxnas_nand_remove, 200 .driver = { 201 .name = "oxnas_nand", 202 .of_match_table = oxnas_nand_match, 203 }, 204}; 205 206module_platform_driver(oxnas_nand_driver); 207 208MODULE_LICENSE("GPL"); 209MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); 210MODULE_DESCRIPTION("Oxnas NAND driver"); 211MODULE_ALIAS("platform:oxnas_nand");