brintos

brintos / linux-shallow public Read only

0
0
Text · 3.4 KiB · e22094e Raw
145 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * NAND Flash Controller Device Driver4 * Copyright © 2009-2010, Intel Corporation and its suppliers.5 */6 7#include <linux/errno.h>8#include <linux/io.h>9#include <linux/kernel.h>10#include <linux/module.h>11#include <linux/pci.h>12 13#include "denali.h"14 15#define DENALI_NAND_NAME    "denali-nand-pci"16 17#define INTEL_CE4100	118#define INTEL_MRST	219 20/* List of platforms this NAND controller has be integrated into */21static const struct pci_device_id denali_pci_ids[] = {22	{ PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 },23	{ PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST },24	{ /* end: all zeroes */ }25};26MODULE_DEVICE_TABLE(pci, denali_pci_ids);27 28NAND_ECC_CAPS_SINGLE(denali_pci_ecc_caps, denali_calc_ecc_bytes, 512, 8, 15);29 30static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)31{32	resource_size_t csr_base, mem_base;33	unsigned long csr_len, mem_len;34	struct denali_controller *denali;35	struct denali_chip *dchip;36	int nsels, ret, i;37 38	denali = devm_kzalloc(&dev->dev, sizeof(*denali), GFP_KERNEL);39	if (!denali)40		return -ENOMEM;41 42	ret = pcim_enable_device(dev);43	if (ret) {44		dev_err(&dev->dev, "Spectra: pci_enable_device failed.\n");45		return ret;46	}47 48	if (id->driver_data == INTEL_CE4100) {49		mem_base = pci_resource_start(dev, 0);50		mem_len = pci_resource_len(dev, 1);51		csr_base = pci_resource_start(dev, 1);52		csr_len = pci_resource_len(dev, 1);53	} else {54		csr_base = pci_resource_start(dev, 0);55		csr_len = pci_resource_len(dev, 0);56		mem_base = pci_resource_start(dev, 1);57		mem_len = pci_resource_len(dev, 1);58		if (!mem_len) {59			mem_base = csr_base + csr_len;60			mem_len = csr_len;61		}62	}63 64	pci_set_master(dev);65	denali->dev = &dev->dev;66	denali->irq = dev->irq;67	denali->ecc_caps = &denali_pci_ecc_caps;68	denali->clk_rate = 50000000;		/* 50 MHz */69	denali->clk_x_rate = 200000000;		/* 200 MHz */70 71	ret = pci_request_regions(dev, DENALI_NAND_NAME);72	if (ret) {73		dev_err(&dev->dev, "Spectra: Unable to request memory regions\n");74		return ret;75	}76 77	denali->reg = devm_ioremap(denali->dev, csr_base, csr_len);78	if (!denali->reg) {79		dev_err(&dev->dev, "Spectra: Unable to remap memory region\n");80		ret = -ENOMEM;81		goto regions_release;82	}83 84	denali->host = devm_ioremap(denali->dev, mem_base, mem_len);85	if (!denali->host) {86		dev_err(&dev->dev, "Spectra: ioremap failed!");87		ret = -ENOMEM;88		goto regions_release;89	}90 91	ret = denali_init(denali);92	if (ret)93		goto regions_release;94 95	nsels = denali->nbanks;96 97	dchip = devm_kzalloc(denali->dev, struct_size(dchip, sels, nsels),98			     GFP_KERNEL);99	if (!dchip) {100		ret = -ENOMEM;101		goto out_remove_denali;102	}103 104	dchip->chip.base.ecc.user_conf.flags |= NAND_ECC_MAXIMIZE_STRENGTH;105 106	dchip->nsels = nsels;107 108	for (i = 0; i < nsels; i++)109		dchip->sels[i].bank = i;110 111	ret = denali_chip_init(denali, dchip);112	if (ret)113		goto out_remove_denali;114 115	pci_set_drvdata(dev, denali);116 117	return 0;118 119out_remove_denali:120	denali_remove(denali);121regions_release:122	pci_release_regions(dev);123	return ret;124}125 126static void denali_pci_remove(struct pci_dev *dev)127{128	struct denali_controller *denali = pci_get_drvdata(dev);129 130	pci_release_regions(dev);131	denali_remove(denali);132}133 134static struct pci_driver denali_pci_driver = {135	.name = DENALI_NAND_NAME,136	.id_table = denali_pci_ids,137	.probe = denali_pci_probe,138	.remove = denali_pci_remove,139};140module_pci_driver(denali_pci_driver);141 142MODULE_DESCRIPTION("PCI driver for Denali NAND controller");143MODULE_AUTHOR("Intel Corporation and its suppliers");144MODULE_LICENSE("GPL v2");145