diff options
Diffstat (limited to 'drivers/mtd/nand/denali.c')
| -rw-r--r-- | drivers/mtd/nand/denali.c | 162 |
1 files changed, 30 insertions, 132 deletions
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 */ | ||
| 93 | static 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 */ |
| 100 | static void clear_interrupts(struct denali_nand_info *denali); | 91 | static void clear_interrupts(struct denali_nand_info *denali); |
| 101 | static uint32_t wait_for_irq(struct denali_nand_info *denali, | 92 | static 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 */ | 1418 | int denali_init(struct denali_nand_info *denali) |
| 1429 | static 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 | ||
| 1664 | failed_req_irq: | 1594 | failed_req_irq: |
| 1665 | denali_irq_cleanup(dev->irq, denali); | 1595 | denali_irq_cleanup(denali->irq, denali); |
| 1666 | failed_remap_mem: | 1596 | |
| 1667 | iounmap(denali->flash_mem); | ||
| 1668 | failed_remap_reg: | ||
| 1669 | iounmap(denali->flash_reg); | ||
| 1670 | failed_req_regions: | ||
| 1671 | pci_release_regions(dev); | ||
| 1672 | failed_dma_map: | ||
| 1673 | dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE, | ||
| 1674 | DMA_BIDIRECTIONAL); | ||
| 1675 | failed_enable_dev: | ||
| 1676 | pci_disable_device(dev); | ||
| 1677 | failed_alloc_memery: | ||
| 1678 | kfree(denali); | ||
| 1679 | return ret; | 1597 | return ret; |
| 1680 | } | 1598 | } |
| 1599 | EXPORT_SYMBOL(denali_init); | ||
| 1681 | 1600 | ||
| 1682 | /* driver exit point */ | 1601 | /* driver exit point */ |
| 1683 | static void denali_pci_remove(struct pci_dev *dev) | 1602 | void 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 | 1608 | EXPORT_SYMBOL(denali_remove); | |
| 1701 | MODULE_DEVICE_TABLE(pci, denali_pci_ids); | ||
| 1702 | |||
| 1703 | static 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 | |||
| 1710 | module_pci_driver(denali_pci_driver); | ||
