| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2016, The Linux Foundation. All rights reserved. |
|---|
| 3 | | - * |
|---|
| 4 | | - * This software is licensed under the terms of the GNU General Public |
|---|
| 5 | | - * License version 2, as published by the Free Software Foundation, and |
|---|
| 6 | | - * may be copied, distributed, and modified under those terms. |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 9 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 11 | | - * GNU General Public License for more details. |
|---|
| 12 | 4 | */ |
|---|
| 13 | 5 | #include <linux/clk.h> |
|---|
| 14 | 6 | #include <linux/slab.h> |
|---|
| .. | .. |
|---|
| 348 | 340 | * @data_buffer: our local DMA buffer for page read/writes, |
|---|
| 349 | 341 | * used when we can't use the buffer provided |
|---|
| 350 | 342 | * by upper layers directly |
|---|
| 351 | | - * @buf_size/count/start: markers for chip->read_buf/write_buf functions |
|---|
| 343 | + * @buf_size/count/start: markers for chip->legacy.read_buf/write_buf |
|---|
| 344 | + * functions |
|---|
| 352 | 345 | * @reg_read_buf: local buffer for reading back registers via DMA |
|---|
| 353 | 346 | * @reg_read_dma: contains dma address for register read buffer |
|---|
| 354 | 347 | * @reg_read_pos: marker for data read in reg_read_buf |
|---|
| .. | .. |
|---|
| 1155 | 1148 | } |
|---|
| 1156 | 1149 | |
|---|
| 1157 | 1150 | /* |
|---|
| 1158 | | - * the following functions are used within chip->cmdfunc() to perform different |
|---|
| 1159 | | - * NAND_CMD_* commands |
|---|
| 1151 | + * the following functions are used within chip->legacy.cmdfunc() to |
|---|
| 1152 | + * perform different NAND_CMD_* commands |
|---|
| 1160 | 1153 | */ |
|---|
| 1161 | 1154 | |
|---|
| 1162 | 1155 | /* sets up descriptors for NAND_CMD_PARAM */ |
|---|
| .. | .. |
|---|
| 1436 | 1429 | } |
|---|
| 1437 | 1430 | |
|---|
| 1438 | 1431 | /* |
|---|
| 1439 | | - * Implements chip->cmdfunc. It's only used for a limited set of commands. |
|---|
| 1440 | | - * The rest of the commands wouldn't be called by upper layers. For example, |
|---|
| 1441 | | - * NAND_CMD_READOOB would never be called because we have our own versions |
|---|
| 1442 | | - * of read_oob ops for nand_ecc_ctrl. |
|---|
| 1432 | + * Implements chip->legacy.cmdfunc. It's only used for a limited set of |
|---|
| 1433 | + * commands. The rest of the commands wouldn't be called by upper layers. |
|---|
| 1434 | + * For example, NAND_CMD_READOOB would never be called because we have our own |
|---|
| 1435 | + * versions of read_oob ops for nand_ecc_ctrl. |
|---|
| 1443 | 1436 | */ |
|---|
| 1444 | | -static void qcom_nandc_command(struct mtd_info *mtd, unsigned int command, |
|---|
| 1437 | +static void qcom_nandc_command(struct nand_chip *chip, unsigned int command, |
|---|
| 1445 | 1438 | int column, int page_addr) |
|---|
| 1446 | 1439 | { |
|---|
| 1447 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 1448 | 1440 | struct qcom_nand_host *host = to_qcom_nand_host(chip); |
|---|
| 1449 | 1441 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
|---|
| 1450 | 1442 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
|---|
| .. | .. |
|---|
| 1683 | 1675 | u8 *cw_data_buf, *cw_oob_buf; |
|---|
| 1684 | 1676 | int cw, data_size, oob_size, ret = 0; |
|---|
| 1685 | 1677 | |
|---|
| 1686 | | - if (!data_buf) { |
|---|
| 1687 | | - data_buf = chip->data_buf; |
|---|
| 1688 | | - chip->pagebuf = -1; |
|---|
| 1689 | | - } |
|---|
| 1678 | + if (!data_buf) |
|---|
| 1679 | + data_buf = nand_get_data_buf(chip); |
|---|
| 1690 | 1680 | |
|---|
| 1691 | 1681 | if (!oob_buf) { |
|---|
| 1682 | + nand_get_data_buf(chip); |
|---|
| 1692 | 1683 | oob_buf = chip->oob_poi; |
|---|
| 1693 | | - chip->pagebuf = -1; |
|---|
| 1694 | 1684 | } |
|---|
| 1695 | 1685 | |
|---|
| 1696 | 1686 | for_each_set_bit(cw, &uncorrectable_cws, ecc->steps) { |
|---|
| .. | .. |
|---|
| 1951 | 1941 | } |
|---|
| 1952 | 1942 | |
|---|
| 1953 | 1943 | /* implements ecc->read_page() */ |
|---|
| 1954 | | -static int qcom_nandc_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
|---|
| 1955 | | - uint8_t *buf, int oob_required, int page) |
|---|
| 1944 | +static int qcom_nandc_read_page(struct nand_chip *chip, uint8_t *buf, |
|---|
| 1945 | + int oob_required, int page) |
|---|
| 1956 | 1946 | { |
|---|
| 1957 | 1947 | struct qcom_nand_host *host = to_qcom_nand_host(chip); |
|---|
| 1958 | 1948 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
|---|
| .. | .. |
|---|
| 1968 | 1958 | } |
|---|
| 1969 | 1959 | |
|---|
| 1970 | 1960 | /* implements ecc->read_page_raw() */ |
|---|
| 1971 | | -static int qcom_nandc_read_page_raw(struct mtd_info *mtd, |
|---|
| 1972 | | - struct nand_chip *chip, uint8_t *buf, |
|---|
| 1961 | +static int qcom_nandc_read_page_raw(struct nand_chip *chip, uint8_t *buf, |
|---|
| 1973 | 1962 | int oob_required, int page) |
|---|
| 1974 | 1963 | { |
|---|
| 1964 | + struct mtd_info *mtd = nand_to_mtd(chip); |
|---|
| 1975 | 1965 | struct qcom_nand_host *host = to_qcom_nand_host(chip); |
|---|
| 1976 | 1966 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
|---|
| 1977 | 1967 | int cw, ret; |
|---|
| .. | .. |
|---|
| 1991 | 1981 | } |
|---|
| 1992 | 1982 | |
|---|
| 1993 | 1983 | /* implements ecc->read_oob() */ |
|---|
| 1994 | | -static int qcom_nandc_read_oob(struct mtd_info *mtd, struct nand_chip *chip, |
|---|
| 1995 | | - int page) |
|---|
| 1984 | +static int qcom_nandc_read_oob(struct nand_chip *chip, int page) |
|---|
| 1996 | 1985 | { |
|---|
| 1997 | 1986 | struct qcom_nand_host *host = to_qcom_nand_host(chip); |
|---|
| 1998 | 1987 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
|---|
| .. | .. |
|---|
| 2009 | 1998 | } |
|---|
| 2010 | 1999 | |
|---|
| 2011 | 2000 | /* implements ecc->write_page() */ |
|---|
| 2012 | | -static int qcom_nandc_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
|---|
| 2013 | | - const uint8_t *buf, int oob_required, int page) |
|---|
| 2001 | +static int qcom_nandc_write_page(struct nand_chip *chip, const uint8_t *buf, |
|---|
| 2002 | + int oob_required, int page) |
|---|
| 2014 | 2003 | { |
|---|
| 2015 | 2004 | struct qcom_nand_host *host = to_qcom_nand_host(chip); |
|---|
| 2016 | 2005 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
|---|
| .. | .. |
|---|
| 2079 | 2068 | } |
|---|
| 2080 | 2069 | |
|---|
| 2081 | 2070 | /* implements ecc->write_page_raw() */ |
|---|
| 2082 | | -static int qcom_nandc_write_page_raw(struct mtd_info *mtd, |
|---|
| 2083 | | - struct nand_chip *chip, const uint8_t *buf, |
|---|
| 2084 | | - int oob_required, int page) |
|---|
| 2071 | +static int qcom_nandc_write_page_raw(struct nand_chip *chip, |
|---|
| 2072 | + const uint8_t *buf, int oob_required, |
|---|
| 2073 | + int page) |
|---|
| 2085 | 2074 | { |
|---|
| 2075 | + struct mtd_info *mtd = nand_to_mtd(chip); |
|---|
| 2086 | 2076 | struct qcom_nand_host *host = to_qcom_nand_host(chip); |
|---|
| 2087 | 2077 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
|---|
| 2088 | 2078 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
|---|
| .. | .. |
|---|
| 2157 | 2147 | * since ECC is calculated for the combined codeword. So update the OOB from |
|---|
| 2158 | 2148 | * chip->oob_poi, and pad the data area with OxFF before writing. |
|---|
| 2159 | 2149 | */ |
|---|
| 2160 | | -static int qcom_nandc_write_oob(struct mtd_info *mtd, struct nand_chip *chip, |
|---|
| 2161 | | - int page) |
|---|
| 2150 | +static int qcom_nandc_write_oob(struct nand_chip *chip, int page) |
|---|
| 2162 | 2151 | { |
|---|
| 2152 | + struct mtd_info *mtd = nand_to_mtd(chip); |
|---|
| 2163 | 2153 | struct qcom_nand_host *host = to_qcom_nand_host(chip); |
|---|
| 2164 | 2154 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
|---|
| 2165 | 2155 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
|---|
| .. | .. |
|---|
| 2199 | 2189 | return nand_prog_page_end_op(chip); |
|---|
| 2200 | 2190 | } |
|---|
| 2201 | 2191 | |
|---|
| 2202 | | -static int qcom_nandc_block_bad(struct mtd_info *mtd, loff_t ofs) |
|---|
| 2192 | +static int qcom_nandc_block_bad(struct nand_chip *chip, loff_t ofs) |
|---|
| 2203 | 2193 | { |
|---|
| 2204 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 2194 | + struct mtd_info *mtd = nand_to_mtd(chip); |
|---|
| 2205 | 2195 | struct qcom_nand_host *host = to_qcom_nand_host(chip); |
|---|
| 2206 | 2196 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
|---|
| 2207 | 2197 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
|---|
| .. | .. |
|---|
| 2237 | 2227 | return bad; |
|---|
| 2238 | 2228 | } |
|---|
| 2239 | 2229 | |
|---|
| 2240 | | -static int qcom_nandc_block_markbad(struct mtd_info *mtd, loff_t ofs) |
|---|
| 2230 | +static int qcom_nandc_block_markbad(struct nand_chip *chip, loff_t ofs) |
|---|
| 2241 | 2231 | { |
|---|
| 2242 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 2243 | 2232 | struct qcom_nand_host *host = to_qcom_nand_host(chip); |
|---|
| 2244 | 2233 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
|---|
| 2245 | 2234 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
|---|
| .. | .. |
|---|
| 2280 | 2269 | } |
|---|
| 2281 | 2270 | |
|---|
| 2282 | 2271 | /* |
|---|
| 2283 | | - * the three functions below implement chip->read_byte(), chip->read_buf() |
|---|
| 2284 | | - * and chip->write_buf() respectively. these aren't used for |
|---|
| 2285 | | - * reading/writing page data, they are used for smaller data like reading |
|---|
| 2286 | | - * id, status etc |
|---|
| 2272 | + * the three functions below implement chip->legacy.read_byte(), |
|---|
| 2273 | + * chip->legacy.read_buf() and chip->legacy.write_buf() respectively. these |
|---|
| 2274 | + * aren't used for reading/writing page data, they are used for smaller data |
|---|
| 2275 | + * like reading id, status etc |
|---|
| 2287 | 2276 | */ |
|---|
| 2288 | | -static uint8_t qcom_nandc_read_byte(struct mtd_info *mtd) |
|---|
| 2277 | +static uint8_t qcom_nandc_read_byte(struct nand_chip *chip) |
|---|
| 2289 | 2278 | { |
|---|
| 2290 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 2291 | 2279 | struct qcom_nand_host *host = to_qcom_nand_host(chip); |
|---|
| 2292 | 2280 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
|---|
| 2293 | 2281 | u8 *buf = nandc->data_buffer; |
|---|
| .. | .. |
|---|
| 2307 | 2295 | return ret; |
|---|
| 2308 | 2296 | } |
|---|
| 2309 | 2297 | |
|---|
| 2310 | | -static void qcom_nandc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
|---|
| 2298 | +static void qcom_nandc_read_buf(struct nand_chip *chip, uint8_t *buf, int len) |
|---|
| 2311 | 2299 | { |
|---|
| 2312 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 2313 | 2300 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
|---|
| 2314 | 2301 | int real_len = min_t(size_t, len, nandc->buf_count - nandc->buf_start); |
|---|
| 2315 | 2302 | |
|---|
| .. | .. |
|---|
| 2317 | 2304 | nandc->buf_start += real_len; |
|---|
| 2318 | 2305 | } |
|---|
| 2319 | 2306 | |
|---|
| 2320 | | -static void qcom_nandc_write_buf(struct mtd_info *mtd, const uint8_t *buf, |
|---|
| 2307 | +static void qcom_nandc_write_buf(struct nand_chip *chip, const uint8_t *buf, |
|---|
| 2321 | 2308 | int len) |
|---|
| 2322 | 2309 | { |
|---|
| 2323 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 2324 | 2310 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
|---|
| 2325 | 2311 | int real_len = min_t(size_t, len, nandc->buf_count - nandc->buf_start); |
|---|
| 2326 | 2312 | |
|---|
| .. | .. |
|---|
| 2330 | 2316 | } |
|---|
| 2331 | 2317 | |
|---|
| 2332 | 2318 | /* we support only one external chip for now */ |
|---|
| 2333 | | -static void qcom_nandc_select_chip(struct mtd_info *mtd, int chipnr) |
|---|
| 2319 | +static void qcom_nandc_select_chip(struct nand_chip *chip, int chipnr) |
|---|
| 2334 | 2320 | { |
|---|
| 2335 | | - struct nand_chip *chip = mtd_to_nand(mtd); |
|---|
| 2336 | 2321 | struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip); |
|---|
| 2337 | 2322 | |
|---|
| 2338 | 2323 | if (chipnr <= 0) |
|---|
| .. | .. |
|---|
| 2566 | 2551 | ecc->write_page_raw = qcom_nandc_write_page_raw; |
|---|
| 2567 | 2552 | ecc->write_oob = qcom_nandc_write_oob; |
|---|
| 2568 | 2553 | |
|---|
| 2569 | | - ecc->mode = NAND_ECC_HW; |
|---|
| 2554 | + ecc->engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; |
|---|
| 2570 | 2555 | |
|---|
| 2571 | 2556 | mtd_set_ooblayout(mtd, &qcom_nand_ooblayout_ops); |
|---|
| 2572 | 2557 | |
|---|
| .. | .. |
|---|
| 2646 | 2631 | .attach_chip = qcom_nand_attach_chip, |
|---|
| 2647 | 2632 | }; |
|---|
| 2648 | 2633 | |
|---|
| 2634 | +static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc) |
|---|
| 2635 | +{ |
|---|
| 2636 | + if (nandc->props->is_bam) { |
|---|
| 2637 | + if (!dma_mapping_error(nandc->dev, nandc->reg_read_dma)) |
|---|
| 2638 | + dma_unmap_single(nandc->dev, nandc->reg_read_dma, |
|---|
| 2639 | + MAX_REG_RD * |
|---|
| 2640 | + sizeof(*nandc->reg_read_buf), |
|---|
| 2641 | + DMA_FROM_DEVICE); |
|---|
| 2642 | + |
|---|
| 2643 | + if (nandc->tx_chan) |
|---|
| 2644 | + dma_release_channel(nandc->tx_chan); |
|---|
| 2645 | + |
|---|
| 2646 | + if (nandc->rx_chan) |
|---|
| 2647 | + dma_release_channel(nandc->rx_chan); |
|---|
| 2648 | + |
|---|
| 2649 | + if (nandc->cmd_chan) |
|---|
| 2650 | + dma_release_channel(nandc->cmd_chan); |
|---|
| 2651 | + } else { |
|---|
| 2652 | + if (nandc->chan) |
|---|
| 2653 | + dma_release_channel(nandc->chan); |
|---|
| 2654 | + } |
|---|
| 2655 | +} |
|---|
| 2656 | + |
|---|
| 2649 | 2657 | static int qcom_nandc_alloc(struct qcom_nand_controller *nandc) |
|---|
| 2650 | 2658 | { |
|---|
| 2651 | 2659 | int ret; |
|---|
| .. | .. |
|---|
| 2691 | 2699 | return -EIO; |
|---|
| 2692 | 2700 | } |
|---|
| 2693 | 2701 | |
|---|
| 2694 | | - nandc->tx_chan = dma_request_slave_channel(nandc->dev, "tx"); |
|---|
| 2695 | | - if (!nandc->tx_chan) { |
|---|
| 2696 | | - dev_err(nandc->dev, "failed to request tx channel\n"); |
|---|
| 2697 | | - return -ENODEV; |
|---|
| 2702 | + nandc->tx_chan = dma_request_chan(nandc->dev, "tx"); |
|---|
| 2703 | + if (IS_ERR(nandc->tx_chan)) { |
|---|
| 2704 | + ret = PTR_ERR(nandc->tx_chan); |
|---|
| 2705 | + nandc->tx_chan = NULL; |
|---|
| 2706 | + dev_err_probe(nandc->dev, ret, |
|---|
| 2707 | + "tx DMA channel request failed\n"); |
|---|
| 2708 | + goto unalloc; |
|---|
| 2698 | 2709 | } |
|---|
| 2699 | 2710 | |
|---|
| 2700 | | - nandc->rx_chan = dma_request_slave_channel(nandc->dev, "rx"); |
|---|
| 2701 | | - if (!nandc->rx_chan) { |
|---|
| 2702 | | - dev_err(nandc->dev, "failed to request rx channel\n"); |
|---|
| 2703 | | - return -ENODEV; |
|---|
| 2711 | + nandc->rx_chan = dma_request_chan(nandc->dev, "rx"); |
|---|
| 2712 | + if (IS_ERR(nandc->rx_chan)) { |
|---|
| 2713 | + ret = PTR_ERR(nandc->rx_chan); |
|---|
| 2714 | + nandc->rx_chan = NULL; |
|---|
| 2715 | + dev_err_probe(nandc->dev, ret, |
|---|
| 2716 | + "rx DMA channel request failed\n"); |
|---|
| 2717 | + goto unalloc; |
|---|
| 2704 | 2718 | } |
|---|
| 2705 | 2719 | |
|---|
| 2706 | | - nandc->cmd_chan = dma_request_slave_channel(nandc->dev, "cmd"); |
|---|
| 2707 | | - if (!nandc->cmd_chan) { |
|---|
| 2708 | | - dev_err(nandc->dev, "failed to request cmd channel\n"); |
|---|
| 2709 | | - return -ENODEV; |
|---|
| 2720 | + nandc->cmd_chan = dma_request_chan(nandc->dev, "cmd"); |
|---|
| 2721 | + if (IS_ERR(nandc->cmd_chan)) { |
|---|
| 2722 | + ret = PTR_ERR(nandc->cmd_chan); |
|---|
| 2723 | + nandc->cmd_chan = NULL; |
|---|
| 2724 | + dev_err_probe(nandc->dev, ret, |
|---|
| 2725 | + "cmd DMA channel request failed\n"); |
|---|
| 2726 | + goto unalloc; |
|---|
| 2710 | 2727 | } |
|---|
| 2711 | 2728 | |
|---|
| 2712 | 2729 | /* |
|---|
| .. | .. |
|---|
| 2720 | 2737 | if (!nandc->bam_txn) { |
|---|
| 2721 | 2738 | dev_err(nandc->dev, |
|---|
| 2722 | 2739 | "failed to allocate bam transaction\n"); |
|---|
| 2723 | | - return -ENOMEM; |
|---|
| 2740 | + ret = -ENOMEM; |
|---|
| 2741 | + goto unalloc; |
|---|
| 2724 | 2742 | } |
|---|
| 2725 | 2743 | } else { |
|---|
| 2726 | | - nandc->chan = dma_request_slave_channel(nandc->dev, "rxtx"); |
|---|
| 2727 | | - if (!nandc->chan) { |
|---|
| 2728 | | - dev_err(nandc->dev, |
|---|
| 2729 | | - "failed to request slave channel\n"); |
|---|
| 2730 | | - return -ENODEV; |
|---|
| 2744 | + nandc->chan = dma_request_chan(nandc->dev, "rxtx"); |
|---|
| 2745 | + if (IS_ERR(nandc->chan)) { |
|---|
| 2746 | + ret = PTR_ERR(nandc->chan); |
|---|
| 2747 | + nandc->chan = NULL; |
|---|
| 2748 | + dev_err_probe(nandc->dev, ret, |
|---|
| 2749 | + "rxtx DMA channel request failed\n"); |
|---|
| 2750 | + return ret; |
|---|
| 2731 | 2751 | } |
|---|
| 2732 | 2752 | } |
|---|
| 2733 | 2753 | |
|---|
| .. | .. |
|---|
| 2738 | 2758 | nandc->controller.ops = &qcom_nandc_ops; |
|---|
| 2739 | 2759 | |
|---|
| 2740 | 2760 | return 0; |
|---|
| 2741 | | -} |
|---|
| 2742 | | - |
|---|
| 2743 | | -static void qcom_nandc_unalloc(struct qcom_nand_controller *nandc) |
|---|
| 2744 | | -{ |
|---|
| 2745 | | - if (nandc->props->is_bam) { |
|---|
| 2746 | | - if (!dma_mapping_error(nandc->dev, nandc->reg_read_dma)) |
|---|
| 2747 | | - dma_unmap_single(nandc->dev, nandc->reg_read_dma, |
|---|
| 2748 | | - MAX_REG_RD * |
|---|
| 2749 | | - sizeof(*nandc->reg_read_buf), |
|---|
| 2750 | | - DMA_FROM_DEVICE); |
|---|
| 2751 | | - |
|---|
| 2752 | | - if (nandc->tx_chan) |
|---|
| 2753 | | - dma_release_channel(nandc->tx_chan); |
|---|
| 2754 | | - |
|---|
| 2755 | | - if (nandc->rx_chan) |
|---|
| 2756 | | - dma_release_channel(nandc->rx_chan); |
|---|
| 2757 | | - |
|---|
| 2758 | | - if (nandc->cmd_chan) |
|---|
| 2759 | | - dma_release_channel(nandc->cmd_chan); |
|---|
| 2760 | | - } else { |
|---|
| 2761 | | - if (nandc->chan) |
|---|
| 2762 | | - dma_release_channel(nandc->chan); |
|---|
| 2763 | | - } |
|---|
| 2761 | +unalloc: |
|---|
| 2762 | + qcom_nandc_unalloc(nandc); |
|---|
| 2763 | + return ret; |
|---|
| 2764 | 2764 | } |
|---|
| 2765 | 2765 | |
|---|
| 2766 | 2766 | /* one time setup of a few nand controller registers */ |
|---|
| .. | .. |
|---|
| 2777 | 2777 | /* enable ADM or BAM DMA */ |
|---|
| 2778 | 2778 | if (nandc->props->is_bam) { |
|---|
| 2779 | 2779 | nand_ctrl = nandc_read(nandc, NAND_CTRL); |
|---|
| 2780 | | - nandc_write(nandc, NAND_CTRL, nand_ctrl | BAM_MODE_EN); |
|---|
| 2780 | + |
|---|
| 2781 | + /* |
|---|
| 2782 | + *NAND_CTRL is an operational registers, and CPU |
|---|
| 2783 | + * access to operational registers are read only |
|---|
| 2784 | + * in BAM mode. So update the NAND_CTRL register |
|---|
| 2785 | + * only if it is not in BAM mode. In most cases BAM |
|---|
| 2786 | + * mode will be enabled in bootloader |
|---|
| 2787 | + */ |
|---|
| 2788 | + if (!(nand_ctrl & BAM_MODE_EN)) |
|---|
| 2789 | + nandc_write(nandc, NAND_CTRL, nand_ctrl | BAM_MODE_EN); |
|---|
| 2781 | 2790 | } else { |
|---|
| 2782 | 2791 | nandc_write(nandc, NAND_FLASH_CHIP_SELECT, DM_EN); |
|---|
| 2783 | 2792 | } |
|---|
| .. | .. |
|---|
| 2812 | 2821 | mtd->owner = THIS_MODULE; |
|---|
| 2813 | 2822 | mtd->dev.parent = dev; |
|---|
| 2814 | 2823 | |
|---|
| 2815 | | - chip->cmdfunc = qcom_nandc_command; |
|---|
| 2816 | | - chip->select_chip = qcom_nandc_select_chip; |
|---|
| 2817 | | - chip->read_byte = qcom_nandc_read_byte; |
|---|
| 2818 | | - chip->read_buf = qcom_nandc_read_buf; |
|---|
| 2819 | | - chip->write_buf = qcom_nandc_write_buf; |
|---|
| 2820 | | - chip->set_features = nand_get_set_features_notsupp; |
|---|
| 2821 | | - chip->get_features = nand_get_set_features_notsupp; |
|---|
| 2824 | + chip->legacy.cmdfunc = qcom_nandc_command; |
|---|
| 2825 | + chip->legacy.select_chip = qcom_nandc_select_chip; |
|---|
| 2826 | + chip->legacy.read_byte = qcom_nandc_read_byte; |
|---|
| 2827 | + chip->legacy.read_buf = qcom_nandc_read_buf; |
|---|
| 2828 | + chip->legacy.write_buf = qcom_nandc_write_buf; |
|---|
| 2829 | + chip->legacy.set_features = nand_get_set_features_notsupp; |
|---|
| 2830 | + chip->legacy.get_features = nand_get_set_features_notsupp; |
|---|
| 2822 | 2831 | |
|---|
| 2823 | 2832 | /* |
|---|
| 2824 | 2833 | * the bad block marker is readable only when we read the last codeword |
|---|
| .. | .. |
|---|
| 2828 | 2837 | * and block_markbad helpers until we permanently switch to using |
|---|
| 2829 | 2838 | * MTD_OPS_RAW for all drivers (with the help of badblockbits) |
|---|
| 2830 | 2839 | */ |
|---|
| 2831 | | - chip->block_bad = qcom_nandc_block_bad; |
|---|
| 2832 | | - chip->block_markbad = qcom_nandc_block_markbad; |
|---|
| 2840 | + chip->legacy.block_bad = qcom_nandc_block_bad; |
|---|
| 2841 | + chip->legacy.block_markbad = qcom_nandc_block_markbad; |
|---|
| 2833 | 2842 | |
|---|
| 2834 | 2843 | chip->controller = &nandc->controller; |
|---|
| 2835 | | - chip->options |= NAND_NO_SUBPAGE_WRITE | NAND_USE_BOUNCE_BUFFER | |
|---|
| 2844 | + chip->options |= NAND_NO_SUBPAGE_WRITE | NAND_USES_DMA | |
|---|
| 2836 | 2845 | NAND_SKIP_BBTSCAN; |
|---|
| 2837 | 2846 | |
|---|
| 2838 | 2847 | /* set up initial status value */ |
|---|
| .. | .. |
|---|
| 2997 | 3006 | struct qcom_nand_controller *nandc = platform_get_drvdata(pdev); |
|---|
| 2998 | 3007 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
|---|
| 2999 | 3008 | struct qcom_nand_host *host; |
|---|
| 3009 | + struct nand_chip *chip; |
|---|
| 3010 | + int ret; |
|---|
| 3000 | 3011 | |
|---|
| 3001 | | - list_for_each_entry(host, &nandc->host_list, node) |
|---|
| 3002 | | - nand_release(&host->chip); |
|---|
| 3003 | | - |
|---|
| 3012 | + list_for_each_entry(host, &nandc->host_list, node) { |
|---|
| 3013 | + chip = &host->chip; |
|---|
| 3014 | + ret = mtd_device_unregister(nand_to_mtd(chip)); |
|---|
| 3015 | + WARN_ON(ret); |
|---|
| 3016 | + nand_cleanup(chip); |
|---|
| 3017 | + } |
|---|
| 3004 | 3018 | |
|---|
| 3005 | 3019 | qcom_nandc_unalloc(nandc); |
|---|
| 3006 | 3020 | |
|---|