| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * NAND Flash Controller Device Driver |
|---|
| 3 | 4 | * Copyright © 2009-2010, Intel Corporation and its suppliers. |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 6 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 7 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 10 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 11 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 12 | | - * more details. |
|---|
| 13 | 5 | */ |
|---|
| 14 | 6 | |
|---|
| 15 | 7 | #include <linux/errno.h> |
|---|
| .. | .. |
|---|
| 37 | 29 | |
|---|
| 38 | 30 | static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) |
|---|
| 39 | 31 | { |
|---|
| 40 | | - int ret; |
|---|
| 41 | 32 | resource_size_t csr_base, mem_base; |
|---|
| 42 | 33 | unsigned long csr_len, mem_len; |
|---|
| 43 | | - struct denali_nand_info *denali; |
|---|
| 34 | + struct denali_controller *denali; |
|---|
| 35 | + struct denali_chip *dchip; |
|---|
| 36 | + int nsels, ret, i; |
|---|
| 44 | 37 | |
|---|
| 45 | 38 | denali = devm_kzalloc(&dev->dev, sizeof(*denali), GFP_KERNEL); |
|---|
| 46 | 39 | if (!denali) |
|---|
| .. | .. |
|---|
| 72 | 65 | denali->dev = &dev->dev; |
|---|
| 73 | 66 | denali->irq = dev->irq; |
|---|
| 74 | 67 | denali->ecc_caps = &denali_pci_ecc_caps; |
|---|
| 75 | | - denali->nand.ecc.options |= NAND_ECC_MAXIMIZE; |
|---|
| 76 | 68 | denali->clk_rate = 50000000; /* 50 MHz */ |
|---|
| 77 | 69 | denali->clk_x_rate = 200000000; /* 200 MHz */ |
|---|
| 78 | 70 | |
|---|
| .. | .. |
|---|
| 82 | 74 | return ret; |
|---|
| 83 | 75 | } |
|---|
| 84 | 76 | |
|---|
| 85 | | - denali->reg = ioremap_nocache(csr_base, csr_len); |
|---|
| 77 | + denali->reg = devm_ioremap(denali->dev, csr_base, csr_len); |
|---|
| 86 | 78 | if (!denali->reg) { |
|---|
| 87 | 79 | dev_err(&dev->dev, "Spectra: Unable to remap memory region\n"); |
|---|
| 88 | 80 | return -ENOMEM; |
|---|
| 89 | 81 | } |
|---|
| 90 | 82 | |
|---|
| 91 | | - denali->host = ioremap_nocache(mem_base, mem_len); |
|---|
| 83 | + denali->host = devm_ioremap(denali->dev, mem_base, mem_len); |
|---|
| 92 | 84 | if (!denali->host) { |
|---|
| 93 | | - dev_err(&dev->dev, "Spectra: ioremap_nocache failed!"); |
|---|
| 94 | | - ret = -ENOMEM; |
|---|
| 95 | | - goto failed_remap_reg; |
|---|
| 85 | + dev_err(&dev->dev, "Spectra: ioremap failed!"); |
|---|
| 86 | + return -ENOMEM; |
|---|
| 96 | 87 | } |
|---|
| 97 | 88 | |
|---|
| 98 | 89 | ret = denali_init(denali); |
|---|
| 99 | 90 | if (ret) |
|---|
| 100 | | - goto failed_remap_mem; |
|---|
| 91 | + return ret; |
|---|
| 92 | + |
|---|
| 93 | + nsels = denali->nbanks; |
|---|
| 94 | + |
|---|
| 95 | + dchip = devm_kzalloc(denali->dev, struct_size(dchip, sels, nsels), |
|---|
| 96 | + GFP_KERNEL); |
|---|
| 97 | + if (!dchip) { |
|---|
| 98 | + ret = -ENOMEM; |
|---|
| 99 | + goto out_remove_denali; |
|---|
| 100 | + } |
|---|
| 101 | + |
|---|
| 102 | + dchip->chip.base.ecc.user_conf.flags |= NAND_ECC_MAXIMIZE_STRENGTH; |
|---|
| 103 | + |
|---|
| 104 | + dchip->nsels = nsels; |
|---|
| 105 | + |
|---|
| 106 | + for (i = 0; i < nsels; i++) |
|---|
| 107 | + dchip->sels[i].bank = i; |
|---|
| 108 | + |
|---|
| 109 | + ret = denali_chip_init(denali, dchip); |
|---|
| 110 | + if (ret) |
|---|
| 111 | + goto out_remove_denali; |
|---|
| 101 | 112 | |
|---|
| 102 | 113 | pci_set_drvdata(dev, denali); |
|---|
| 103 | 114 | |
|---|
| 104 | 115 | return 0; |
|---|
| 105 | 116 | |
|---|
| 106 | | -failed_remap_mem: |
|---|
| 107 | | - iounmap(denali->host); |
|---|
| 108 | | -failed_remap_reg: |
|---|
| 109 | | - iounmap(denali->reg); |
|---|
| 117 | +out_remove_denali: |
|---|
| 118 | + denali_remove(denali); |
|---|
| 110 | 119 | return ret; |
|---|
| 111 | 120 | } |
|---|
| 112 | 121 | |
|---|
| 113 | 122 | static void denali_pci_remove(struct pci_dev *dev) |
|---|
| 114 | 123 | { |
|---|
| 115 | | - struct denali_nand_info *denali = pci_get_drvdata(dev); |
|---|
| 124 | + struct denali_controller *denali = pci_get_drvdata(dev); |
|---|
| 116 | 125 | |
|---|
| 117 | 126 | denali_remove(denali); |
|---|
| 118 | | - iounmap(denali->reg); |
|---|
| 119 | | - iounmap(denali->host); |
|---|
| 120 | 127 | } |
|---|
| 121 | 128 | |
|---|
| 122 | 129 | static struct pci_driver denali_pci_driver = { |
|---|