aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/Kconfig11
-rw-r--r--drivers/mtd/nand/Makefile1
-rw-r--r--drivers/mtd/nand/denali.c162
-rw-r--r--drivers/mtd/nand/denali.h4
-rw-r--r--drivers/mtd/nand/denali_pci.c144
5 files changed, 188 insertions, 134 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 4883139460be..5102e87f8df0 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -57,8 +57,15 @@ config MTD_NAND_AUTCPU12
57 access the SmartMediaCard. 57 access the SmartMediaCard.
58 58
59config MTD_NAND_DENALI 59config MTD_NAND_DENALI
60 depends on PCI 60 tristate "Support Denali NAND controller"
61 help
62 Enable support for the Denali NAND controller. This should be
63 combined with either the PCI or platform drivers to provide device
64 registration.
65
66config MTD_NAND_DENALI_PCI
61 tristate "Support Denali NAND controller on Intel Moorestown" 67 tristate "Support Denali NAND controller on Intel Moorestown"
68 depends on PCI && MTD_NAND_DENALI
62 help 69 help
63 Enable the driver for NAND flash on Intel Moorestown, using the 70 Enable the driver for NAND flash on Intel Moorestown, using the
64 Denali NAND controller core. 71 Denali NAND controller core.
@@ -66,7 +73,7 @@ config MTD_NAND_DENALI
66config MTD_NAND_DENALI_SCRATCH_REG_ADDR 73config MTD_NAND_DENALI_SCRATCH_REG_ADDR
67 hex "Denali NAND size scratch register address" 74 hex "Denali NAND size scratch register address"
68 default "0xFF108018" 75 default "0xFF108018"
69 depends on MTD_NAND_DENALI 76 depends on MTD_NAND_DENALI_PCI
70 help 77 help
71 Some platforms place the NAND chip size in a scratch register 78 Some platforms place the NAND chip size in a scratch register
72 because (some versions of) the driver aren't able to automatically 79 because (some versions of) the driver aren't able to automatically
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 2cbd0916b733..96a6171c9d8f 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
13obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o 13obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o
14obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o 14obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
15obj-$(CONFIG_MTD_NAND_DENALI) += denali.o 15obj-$(CONFIG_MTD_NAND_DENALI) += denali.o
16obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o
16obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o 17obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
17obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o 18obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o
18obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o 19obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index e706a237170f..0c8bb6bf8424 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -16,14 +16,12 @@
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 * 17 *
18 */ 18 */
19
20#include <linux/interrupt.h> 19#include <linux/interrupt.h>
21#include <linux/delay.h> 20#include <linux/delay.h>
22#include <linux/dma-mapping.h> 21#include <linux/dma-mapping.h>
23#include <linux/wait.h> 22#include <linux/wait.h>
24#include <linux/mutex.h> 23#include <linux/mutex.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
26#include <linux/pci.h>
27#include <linux/mtd/mtd.h> 25#include <linux/mtd/mtd.h>
28#include <linux/module.h> 26#include <linux/module.h>
29 27
@@ -89,13 +87,6 @@ MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting."
89 * format the bank into the proper bits for the controller */ 87 * format the bank into the proper bits for the controller */
90#define BANK(x) ((x) << 24) 88#define BANK(x) ((x) << 24)
91 89
92/* List of platforms this NAND controller has be integrated into */
93static const struct pci_device_id denali_pci_ids[] = {
94 { PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 },
95 { PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST },
96 { /* end: all zeroes */ }
97};
98
99/* forward declarations */ 90/* forward declarations */
100static void clear_interrupts(struct denali_nand_info *denali); 91static void clear_interrupts(struct denali_nand_info *denali);
101static uint32_t wait_for_irq(struct denali_nand_info *denali, 92static uint32_t wait_for_irq(struct denali_nand_info *denali,
@@ -699,7 +690,7 @@ static uint32_t wait_for_irq(struct denali_nand_info *denali, uint32_t irq_mask)
699 690
700 if (comp_res == 0) { 691 if (comp_res == 0) {
701 /* timeout */ 692 /* timeout */
702 printk(KERN_ERR "timeout occurred, status = 0x%x, mask = 0x%x\n", 693 pr_err("timeout occurred, status = 0x%x, mask = 0x%x\n",
703 intr_status, irq_mask); 694 intr_status, irq_mask);
704 695
705 intr_status = 0; 696 intr_status = 0;
@@ -1305,8 +1296,7 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col,
1305 /* TODO: Read OOB data */ 1296 /* TODO: Read OOB data */
1306 break; 1297 break;
1307 default: 1298 default:
1308 printk(KERN_ERR ": unsupported command" 1299 pr_err(": unsupported command received 0x%x\n", cmd);
1309 " received 0x%x\n", cmd);
1310 break; 1300 break;
1311 } 1301 }
1312} 1302}
@@ -1425,107 +1415,48 @@ void denali_drv_init(struct denali_nand_info *denali)
1425 denali->irq_status = 0; 1415 denali->irq_status = 0;
1426} 1416}
1427 1417
1428/* driver entry point */ 1418int denali_init(struct denali_nand_info *denali)
1429static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
1430{ 1419{
1431 int ret = -ENODEV; 1420 int ret;
1432 resource_size_t csr_base, mem_base;
1433 unsigned long csr_len, mem_len;
1434 struct denali_nand_info *denali;
1435
1436 denali = kzalloc(sizeof(*denali), GFP_KERNEL);
1437 if (!denali)
1438 return -ENOMEM;
1439 1421
1440 ret = pci_enable_device(dev); 1422 if (denali->platform == INTEL_CE4100) {
1441 if (ret) {
1442 printk(KERN_ERR "Spectra: pci_enable_device failed.\n");
1443 goto failed_alloc_memery;
1444 }
1445
1446 if (id->driver_data == INTEL_CE4100) {
1447 /* Due to a silicon limitation, we can only support 1423 /* Due to a silicon limitation, we can only support
1448 * ONFI timing mode 1 and below. 1424 * ONFI timing mode 1 and below.
1449 */ 1425 */
1450 if (onfi_timing_mode < -1 || onfi_timing_mode > 1) { 1426 if (onfi_timing_mode < -1 || onfi_timing_mode > 1) {
1451 printk(KERN_ERR "Intel CE4100 only supports" 1427 pr_err("Intel CE4100 only supports ONFI timing mode 1 or below\n");
1452 " ONFI timing mode 1 or below\n"); 1428 return -EINVAL;
1453 ret = -EINVAL;
1454 goto failed_enable_dev;
1455 }
1456 denali->platform = INTEL_CE4100;
1457 mem_base = pci_resource_start(dev, 0);
1458 mem_len = pci_resource_len(dev, 1);
1459 csr_base = pci_resource_start(dev, 1);
1460 csr_len = pci_resource_len(dev, 1);
1461 } else {
1462 denali->platform = INTEL_MRST;
1463 csr_base = pci_resource_start(dev, 0);
1464 csr_len = pci_resource_len(dev, 0);
1465 mem_base = pci_resource_start(dev, 1);
1466 mem_len = pci_resource_len(dev, 1);
1467 if (!mem_len) {
1468 mem_base = csr_base + csr_len;
1469 mem_len = csr_len;
1470 } 1429 }
1471 } 1430 }
1472 1431
1473 /* Is 32-bit DMA supported? */ 1432 /* Is 32-bit DMA supported? */
1474 ret = dma_set_mask(&dev->dev, DMA_BIT_MASK(32)); 1433 ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32));
1475 if (ret) { 1434 if (ret) {
1476 printk(KERN_ERR "Spectra: no usable DMA configuration\n"); 1435 pr_err("Spectra: no usable DMA configuration\n");
1477 goto failed_enable_dev; 1436 return ret;
1478 } 1437 }
1479 denali->buf.dma_buf = dma_map_single(&dev->dev, denali->buf.buf, 1438 denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf,
1480 DENALI_BUF_SIZE, 1439 DENALI_BUF_SIZE,
1481 DMA_BIDIRECTIONAL); 1440 DMA_BIDIRECTIONAL);
1482 1441
1483 if (dma_mapping_error(&dev->dev, denali->buf.dma_buf)) { 1442 if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) {
1484 dev_err(&dev->dev, "Spectra: failed to map DMA buffer\n"); 1443 dev_err(denali->dev, "Spectra: failed to map DMA buffer\n");
1485 goto failed_enable_dev; 1444 return -EIO;
1486 }
1487
1488 pci_set_master(dev);
1489 denali->dev = &dev->dev;
1490 denali->mtd.dev.parent = &dev->dev;
1491
1492 ret = pci_request_regions(dev, DENALI_NAND_NAME);
1493 if (ret) {
1494 printk(KERN_ERR "Spectra: Unable to request memory regions\n");
1495 goto failed_dma_map;
1496 }
1497
1498 denali->flash_reg = ioremap_nocache(csr_base, csr_len);
1499 if (!denali->flash_reg) {
1500 printk(KERN_ERR "Spectra: Unable to remap memory region\n");
1501 ret = -ENOMEM;
1502 goto failed_req_regions;
1503 }
1504
1505 denali->flash_mem = ioremap_nocache(mem_base, mem_len);
1506 if (!denali->flash_mem) {
1507 printk(KERN_ERR "Spectra: ioremap_nocache failed!");
1508 ret = -ENOMEM;
1509 goto failed_remap_reg;
1510 } 1445 }
1511 1446 denali->mtd.dev.parent = denali->dev;
1512 denali_hw_init(denali); 1447 denali_hw_init(denali);
1513 denali_drv_init(denali); 1448 denali_drv_init(denali);
1514 1449
1515 /* denali_isr register is done after all the hardware 1450 /* denali_isr register is done after all the hardware
1516 * initilization is finished*/ 1451 * initilization is finished*/
1517 if (request_irq(dev->irq, denali_isr, IRQF_SHARED, 1452 if (request_irq(denali->irq, denali_isr, IRQF_SHARED,
1518 DENALI_NAND_NAME, denali)) { 1453 DENALI_NAND_NAME, denali)) {
1519 printk(KERN_ERR "Spectra: Unable to allocate IRQ\n"); 1454 pr_err("Spectra: Unable to allocate IRQ\n");
1520 ret = -ENODEV; 1455 return -ENODEV;
1521 goto failed_remap_mem;
1522 } 1456 }
1523 1457
1524 /* now that our ISR is registered, we can enable interrupts */ 1458 /* now that our ISR is registered, we can enable interrupts */
1525 denali_set_intr_modes(denali, true); 1459 denali_set_intr_modes(denali, true);
1526
1527 pci_set_drvdata(dev, denali);
1528
1529 denali->mtd.name = "denali-nand"; 1460 denali->mtd.name = "denali-nand";
1530 denali->mtd.owner = THIS_MODULE; 1461 denali->mtd.owner = THIS_MODULE;
1531 denali->mtd.priv = &denali->nand; 1462 denali->mtd.priv = &denali->nand;
@@ -1549,8 +1480,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
1549 */ 1480 */
1550 if (denali->mtd.writesize > NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) { 1481 if (denali->mtd.writesize > NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) {
1551 ret = -ENODEV; 1482 ret = -ENODEV;
1552 printk(KERN_ERR "Spectra: device size not supported by this " 1483 pr_err("Spectra: device size not supported by this version of MTD.");
1553 "version of MTD.");
1554 goto failed_req_irq; 1484 goto failed_req_irq;
1555 } 1485 }
1556 1486
@@ -1602,8 +1532,8 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
1602 } else if (denali->mtd.oobsize < (denali->bbtskipbytes + 1532 } else if (denali->mtd.oobsize < (denali->bbtskipbytes +
1603 ECC_8BITS * (denali->mtd.writesize / 1533 ECC_8BITS * (denali->mtd.writesize /
1604 ECC_SECTOR_SIZE))) { 1534 ECC_SECTOR_SIZE))) {
1605 printk(KERN_ERR "Your NAND chip OOB is not large enough to" 1535 pr_err("Your NAND chip OOB is not large enough to \
1606 " contain 8bit ECC correction codes"); 1536 contain 8bit ECC correction codes");
1607 goto failed_req_irq; 1537 goto failed_req_irq;
1608 } else { 1538 } else {
1609 denali->nand.ecc.strength = 8; 1539 denali->nand.ecc.strength = 8;
@@ -1655,56 +1585,24 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
1655 1585
1656 ret = mtd_device_register(&denali->mtd, NULL, 0); 1586 ret = mtd_device_register(&denali->mtd, NULL, 0);
1657 if (ret) { 1587 if (ret) {
1658 dev_err(&dev->dev, "Spectra: Failed to register MTD: %d\n", 1588 dev_err(denali->dev, "Spectra: Failed to register MTD: %d\n",
1659 ret); 1589 ret);
1660 goto failed_req_irq; 1590 goto failed_req_irq;
1661 } 1591 }
1662 return 0; 1592 return 0;
1663 1593
1664failed_req_irq: 1594failed_req_irq:
1665 denali_irq_cleanup(dev->irq, denali); 1595 denali_irq_cleanup(denali->irq, denali);
1666failed_remap_mem: 1596
1667 iounmap(denali->flash_mem);
1668failed_remap_reg:
1669 iounmap(denali->flash_reg);
1670failed_req_regions:
1671 pci_release_regions(dev);
1672failed_dma_map:
1673 dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
1674 DMA_BIDIRECTIONAL);
1675failed_enable_dev:
1676 pci_disable_device(dev);
1677failed_alloc_memery:
1678 kfree(denali);
1679 return ret; 1597 return ret;
1680} 1598}
1599EXPORT_SYMBOL(denali_init);
1681 1600
1682/* driver exit point */ 1601/* driver exit point */
1683static void denali_pci_remove(struct pci_dev *dev) 1602void denali_remove(struct denali_nand_info *denali)
1684{ 1603{
1685 struct denali_nand_info *denali = pci_get_drvdata(dev); 1604 denali_irq_cleanup(denali->irq, denali);
1686 1605 dma_unmap_single(denali->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
1687 nand_release(&denali->mtd); 1606 DMA_BIDIRECTIONAL);
1688
1689 denali_irq_cleanup(dev->irq, denali);
1690
1691 iounmap(denali->flash_reg);
1692 iounmap(denali->flash_mem);
1693 pci_release_regions(dev);
1694 pci_disable_device(dev);
1695 dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
1696 DMA_BIDIRECTIONAL);
1697 pci_set_drvdata(dev, NULL);
1698 kfree(denali);
1699} 1607}
1700 1608EXPORT_SYMBOL(denali_remove);
1701MODULE_DEVICE_TABLE(pci, denali_pci_ids);
1702
1703static struct pci_driver denali_pci_driver = {
1704 .name = DENALI_NAND_NAME,
1705 .id_table = denali_pci_ids,
1706 .probe = denali_pci_probe,
1707 .remove = denali_pci_remove,
1708};
1709
1710module_pci_driver(denali_pci_driver);
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h
index fabb9d56b39e..e5aa99583e43 100644
--- a/drivers/mtd/nand/denali.h
+++ b/drivers/mtd/nand/denali.h
@@ -487,6 +487,7 @@ struct denali_nand_info {
487 uint32_t irq_status; 487 uint32_t irq_status;
488 int irq_debug_array[32]; 488 int irq_debug_array[32];
489 int idx; 489 int idx;
490 int irq;
490 491
491 uint32_t devnum; /* represent how many nands connected */ 492 uint32_t devnum; /* represent how many nands connected */
492 uint32_t fwblks; /* represent how many blocks FW used */ 493 uint32_t fwblks; /* represent how many blocks FW used */
@@ -496,4 +497,7 @@ struct denali_nand_info {
496 uint32_t max_banks; 497 uint32_t max_banks;
497}; 498};
498 499
500extern int denali_init(struct denali_nand_info *denali);
501extern void denali_remove(struct denali_nand_info *denali);
502
499#endif /*_LLD_NAND_*/ 503#endif /*_LLD_NAND_*/
diff --git a/drivers/mtd/nand/denali_pci.c b/drivers/mtd/nand/denali_pci.c
new file mode 100644
index 000000000000..ea074e6c7622
--- /dev/null
+++ b/drivers/mtd/nand/denali_pci.c
@@ -0,0 +1,144 @@
1/*
2 * NAND Flash Controller Device Driver
3 * 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 */
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/pci.h>
17#include <linux/slab.h>
18
19#include "denali.h"
20
21#define DENALI_NAND_NAME "denali-nand-pci"
22
23/* List of platforms this NAND controller has be integrated into */
24static DEFINE_PCI_DEVICE_TABLE(denali_pci_ids) = {
25 { PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 },
26 { PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST },
27 { /* end: all zeroes */ }
28};
29MODULE_DEVICE_TABLE(pci, denali_pci_ids);
30
31static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
32{
33 int ret = -ENODEV;
34 resource_size_t csr_base, mem_base;
35 unsigned long csr_len, mem_len;
36 struct denali_nand_info *denali;
37
38 denali = kzalloc(sizeof(*denali), GFP_KERNEL);
39 if (!denali)
40 return -ENOMEM;
41
42 ret = pci_enable_device(dev);
43 if (ret) {
44 pr_err("Spectra: pci_enable_device failed.\n");
45 goto failed_alloc_memery;
46 }
47
48 if (id->driver_data == INTEL_CE4100) {
49 denali->platform = INTEL_CE4100;
50 mem_base = pci_resource_start(dev, 0);
51 mem_len = pci_resource_len(dev, 1);
52 csr_base = pci_resource_start(dev, 1);
53 csr_len = pci_resource_len(dev, 1);
54 } else {
55 denali->platform = INTEL_MRST;
56 csr_base = pci_resource_start(dev, 0);
57 csr_len = pci_resource_len(dev, 0);
58 mem_base = pci_resource_start(dev, 1);
59 mem_len = pci_resource_len(dev, 1);
60 if (!mem_len) {
61 mem_base = csr_base + csr_len;
62 mem_len = csr_len;
63 }
64 }
65
66 pci_set_master(dev);
67 denali->dev = &dev->dev;
68 denali->irq = dev->irq;
69
70 ret = pci_request_regions(dev, DENALI_NAND_NAME);
71 if (ret) {
72 pr_err("Spectra: Unable to request memory regions\n");
73 goto failed_enable_dev;
74 }
75
76 denali->flash_reg = ioremap_nocache(csr_base, csr_len);
77 if (!denali->flash_reg) {
78 pr_err("Spectra: Unable to remap memory region\n");
79 ret = -ENOMEM;
80 goto failed_req_regions;
81 }
82
83 denali->flash_mem = ioremap_nocache(mem_base, mem_len);
84 if (!denali->flash_mem) {
85 pr_err("Spectra: ioremap_nocache failed!");
86 ret = -ENOMEM;
87 goto failed_remap_reg;
88 }
89
90 ret = denali_init(denali);
91 if (ret)
92 goto failed_remap_mem;
93
94 pci_set_drvdata(dev, denali);
95
96 return 0;
97
98failed_remap_mem:
99 iounmap(denali->flash_mem);
100failed_remap_reg:
101 iounmap(denali->flash_reg);
102failed_req_regions:
103 pci_release_regions(dev);
104failed_enable_dev:
105 pci_disable_device(dev);
106failed_alloc_memery:
107 kfree(denali);
108
109 return ret;
110}
111
112/* driver exit point */
113static void denali_pci_remove(struct pci_dev *dev)
114{
115 struct denali_nand_info *denali = pci_get_drvdata(dev);
116
117 denali_remove(denali);
118 iounmap(denali->flash_reg);
119 iounmap(denali->flash_mem);
120 pci_release_regions(dev);
121 pci_disable_device(dev);
122 pci_set_drvdata(dev, NULL);
123 kfree(denali);
124}
125
126static struct pci_driver denali_pci_driver = {
127 .name = DENALI_NAND_NAME,
128 .id_table = denali_pci_ids,
129 .probe = denali_pci_probe,
130 .remove = denali_pci_remove,
131};
132
133static int __devinit denali_init_pci(void)
134{
135 pr_info("Spectra MTD driver built on %s @ %s\n", __DATE__, __TIME__);
136 return pci_register_driver(&denali_pci_driver);
137}
138module_init(denali_init_pci);
139
140static void __devexit denali_exit_pci(void)
141{
142 pci_unregister_driver(&denali_pci_driver);
143}
144module_exit(denali_exit_pci);