Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 347140
b: refs/heads/master
c: 2a0a288
h: refs/heads/master
v: v3
  • Loading branch information
Dinh Nguyen authored and Artem Bityutskiy committed Nov 15, 2012
1 parent 9f78b03 commit cd15915
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 135 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 30fad64325ba368ffe1f92bd37f4b96c1fa4da83
refs/heads/master: 2a0a288ec258bd38d8855fad9419aeb45b7e8499
11 changes: 9 additions & 2 deletions trunk/drivers/mtd/nand/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,23 @@ config MTD_NAND_AUTCPU12
access the SmartMediaCard.

config MTD_NAND_DENALI
depends on PCI
tristate "Support Denali NAND controller"
help
Enable support for the Denali NAND controller. This should be
combined with either the PCI or platform drivers to provide device
registration.

config MTD_NAND_DENALI_PCI
tristate "Support Denali NAND controller on Intel Moorestown"
depends on PCI && MTD_NAND_DENALI
help
Enable the driver for NAND flash on Intel Moorestown, using the
Denali NAND controller core.

config MTD_NAND_DENALI_SCRATCH_REG_ADDR
hex "Denali NAND size scratch register address"
default "0xFF108018"
depends on MTD_NAND_DENALI
depends on MTD_NAND_DENALI_PCI
help
Some platforms place the NAND chip size in a scratch register
because (some versions of) the driver aren't able to automatically
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/mtd/nand/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o
obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
obj-$(CONFIG_MTD_NAND_DENALI) += denali.o
obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o
obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o
obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o
Expand Down
162 changes: 30 additions & 132 deletions trunk/drivers/mtd/nand/denali.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,12 @@
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
*/

#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/mtd/mtd.h>
#include <linux/module.h>

Expand Down Expand Up @@ -89,13 +87,6 @@ MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting."
* format the bank into the proper bits for the controller */
#define BANK(x) ((x) << 24)

/* List of platforms this NAND controller has be integrated into */
static const struct pci_device_id denali_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 },
{ PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST },
{ /* end: all zeroes */ }
};

/* forward declarations */
static void clear_interrupts(struct denali_nand_info *denali);
static uint32_t wait_for_irq(struct denali_nand_info *denali,
Expand Down Expand Up @@ -699,7 +690,7 @@ static uint32_t wait_for_irq(struct denali_nand_info *denali, uint32_t irq_mask)

if (comp_res == 0) {
/* timeout */
printk(KERN_ERR "timeout occurred, status = 0x%x, mask = 0x%x\n",
pr_err("timeout occurred, status = 0x%x, mask = 0x%x\n",
intr_status, irq_mask);

intr_status = 0;
Expand Down Expand Up @@ -1305,8 +1296,7 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
/* TODO: Read OOB data */
break;
default:
printk(KERN_ERR ": unsupported command"
" received 0x%x\n", cmd);
pr_err(": unsupported command received 0x%x\n", cmd);
break;
}
}
Expand Down Expand Up @@ -1425,107 +1415,48 @@ void denali_drv_init(struct denali_nand_info *denali)
denali->irq_status = 0;
}

/* driver entry point */
static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
int denali_init(struct denali_nand_info *denali)
{
int ret = -ENODEV;
resource_size_t csr_base, mem_base;
unsigned long csr_len, mem_len;
struct denali_nand_info *denali;

denali = kzalloc(sizeof(*denali), GFP_KERNEL);
if (!denali)
return -ENOMEM;
int ret;

ret = pci_enable_device(dev);
if (ret) {
printk(KERN_ERR "Spectra: pci_enable_device failed.\n");
goto failed_alloc_memery;
}

if (id->driver_data == INTEL_CE4100) {
if (denali->platform == INTEL_CE4100) {
/* Due to a silicon limitation, we can only support
* ONFI timing mode 1 and below.
*/
if (onfi_timing_mode < -1 || onfi_timing_mode > 1) {
printk(KERN_ERR "Intel CE4100 only supports"
" ONFI timing mode 1 or below\n");
ret = -EINVAL;
goto failed_enable_dev;
}
denali->platform = INTEL_CE4100;
mem_base = pci_resource_start(dev, 0);
mem_len = pci_resource_len(dev, 1);
csr_base = pci_resource_start(dev, 1);
csr_len = pci_resource_len(dev, 1);
} else {
denali->platform = INTEL_MRST;
csr_base = pci_resource_start(dev, 0);
csr_len = pci_resource_len(dev, 0);
mem_base = pci_resource_start(dev, 1);
mem_len = pci_resource_len(dev, 1);
if (!mem_len) {
mem_base = csr_base + csr_len;
mem_len = csr_len;
pr_err("Intel CE4100 only supports ONFI timing mode 1 or below\n");
return -EINVAL;
}
}

/* Is 32-bit DMA supported? */
ret = dma_set_mask(&dev->dev, DMA_BIT_MASK(32));
ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32));
if (ret) {
printk(KERN_ERR "Spectra: no usable DMA configuration\n");
goto failed_enable_dev;
pr_err("Spectra: no usable DMA configuration\n");
return ret;
}
denali->buf.dma_buf = dma_map_single(&dev->dev, denali->buf.buf,
denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf,
DENALI_BUF_SIZE,
DMA_BIDIRECTIONAL);

if (dma_mapping_error(&dev->dev, denali->buf.dma_buf)) {
dev_err(&dev->dev, "Spectra: failed to map DMA buffer\n");
goto failed_enable_dev;
}

pci_set_master(dev);
denali->dev = &dev->dev;
denali->mtd.dev.parent = &dev->dev;

ret = pci_request_regions(dev, DENALI_NAND_NAME);
if (ret) {
printk(KERN_ERR "Spectra: Unable to request memory regions\n");
goto failed_dma_map;
}

denali->flash_reg = ioremap_nocache(csr_base, csr_len);
if (!denali->flash_reg) {
printk(KERN_ERR "Spectra: Unable to remap memory region\n");
ret = -ENOMEM;
goto failed_req_regions;
}

denali->flash_mem = ioremap_nocache(mem_base, mem_len);
if (!denali->flash_mem) {
printk(KERN_ERR "Spectra: ioremap_nocache failed!");
ret = -ENOMEM;
goto failed_remap_reg;
if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) {
dev_err(denali->dev, "Spectra: failed to map DMA buffer\n");
return -EIO;
}

denali->mtd.dev.parent = denali->dev;
denali_hw_init(denali);
denali_drv_init(denali);

/* denali_isr register is done after all the hardware
* initilization is finished*/
if (request_irq(dev->irq, denali_isr, IRQF_SHARED,
if (request_irq(denali->irq, denali_isr, IRQF_SHARED,
DENALI_NAND_NAME, denali)) {
printk(KERN_ERR "Spectra: Unable to allocate IRQ\n");
ret = -ENODEV;
goto failed_remap_mem;
pr_err("Spectra: Unable to allocate IRQ\n");
return -ENODEV;
}

/* now that our ISR is registered, we can enable interrupts */
denali_set_intr_modes(denali, true);

pci_set_drvdata(dev, denali);

denali->mtd.name = "denali-nand";
denali->mtd.owner = THIS_MODULE;
denali->mtd.priv = &denali->nand;
Expand All @@ -1549,8 +1480,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
*/
if (denali->mtd.writesize > NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) {
ret = -ENODEV;
printk(KERN_ERR "Spectra: device size not supported by this "
"version of MTD.");
pr_err("Spectra: device size not supported by this version of MTD.");
goto failed_req_irq;
}

Expand Down Expand Up @@ -1602,8 +1532,8 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
} else if (denali->mtd.oobsize < (denali->bbtskipbytes +
ECC_8BITS * (denali->mtd.writesize /
ECC_SECTOR_SIZE))) {
printk(KERN_ERR "Your NAND chip OOB is not large enough to"
" contain 8bit ECC correction codes");
pr_err("Your NAND chip OOB is not large enough to \
contain 8bit ECC correction codes");
goto failed_req_irq;
} else {
denali->nand.ecc.strength = 8;
Expand Down Expand Up @@ -1655,56 +1585,24 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)

ret = mtd_device_register(&denali->mtd, NULL, 0);
if (ret) {
dev_err(&dev->dev, "Spectra: Failed to register MTD: %d\n",
dev_err(denali->dev, "Spectra: Failed to register MTD: %d\n",
ret);
goto failed_req_irq;
}
return 0;

failed_req_irq:
denali_irq_cleanup(dev->irq, denali);
failed_remap_mem:
iounmap(denali->flash_mem);
failed_remap_reg:
iounmap(denali->flash_reg);
failed_req_regions:
pci_release_regions(dev);
failed_dma_map:
dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
DMA_BIDIRECTIONAL);
failed_enable_dev:
pci_disable_device(dev);
failed_alloc_memery:
kfree(denali);
denali_irq_cleanup(denali->irq, denali);

return ret;
}
EXPORT_SYMBOL(denali_init);

/* driver exit point */
static void denali_pci_remove(struct pci_dev *dev)
void denali_remove(struct denali_nand_info *denali)
{
struct denali_nand_info *denali = pci_get_drvdata(dev);

nand_release(&denali->mtd);

denali_irq_cleanup(dev->irq, denali);

iounmap(denali->flash_reg);
iounmap(denali->flash_mem);
pci_release_regions(dev);
pci_disable_device(dev);
dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
DMA_BIDIRECTIONAL);
pci_set_drvdata(dev, NULL);
kfree(denali);
denali_irq_cleanup(denali->irq, denali);
dma_unmap_single(denali->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
DMA_BIDIRECTIONAL);
}

MODULE_DEVICE_TABLE(pci, denali_pci_ids);

static struct pci_driver denali_pci_driver = {
.name = DENALI_NAND_NAME,
.id_table = denali_pci_ids,
.probe = denali_pci_probe,
.remove = denali_pci_remove,
};

module_pci_driver(denali_pci_driver);
EXPORT_SYMBOL(denali_remove);
4 changes: 4 additions & 0 deletions trunk/drivers/mtd/nand/denali.h
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ struct denali_nand_info {
uint32_t irq_status;
int irq_debug_array[32];
int idx;
int irq;

uint32_t devnum; /* represent how many nands connected */
uint32_t fwblks; /* represent how many blocks FW used */
Expand All @@ -496,4 +497,7 @@ struct denali_nand_info {
uint32_t max_banks;
};

extern int denali_init(struct denali_nand_info *denali);
extern void denali_remove(struct denali_nand_info *denali);

#endif /*_LLD_NAND_*/
Loading

0 comments on commit cd15915

Please sign in to comment.