Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: gpmi: add device tree support to gpmi-nand

This patch just adds the DT support to gpmi-nand.

Signed-off-by: Huang Shijie <b32955@freescale.com>
Signed-off-by: Huang Shijie <shijie8@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>

authored by

Huang Shijie and committed by
David Woodhouse
e10db1f0 279f08d4

+108 -76
+33
Documentation/devicetree/bindings/mtd/gpmi-nand.txt
··· 1 + * Freescale General-Purpose Media Interface (GPMI) 2 + 3 + The GPMI nand controller provides an interface to control the 4 + NAND flash chips. We support only one NAND chip now. 5 + 6 + Required properties: 7 + - compatible : should be "fsl,<chip>-gpmi-nand" 8 + - reg : should contain registers location and length for gpmi and bch. 9 + - reg-names: Should contain the reg names "gpmi-nand" and "bch" 10 + - interrupts : The first is the DMA interrupt number for GPMI. 11 + The second is the BCH interrupt number. 12 + - interrupt-names : The interrupt names "gpmi-dma", "bch"; 13 + - fsl,gpmi-dma-channel : Should contain the dma channel it uses. 14 + 15 + The device tree may optionally contain sub-nodes describing partitions of the 16 + address space. See partition.txt for more detail. 17 + 18 + Examples: 19 + 20 + gpmi-nand@8000c000 { 21 + compatible = "fsl,imx28-gpmi-nand"; 22 + #address-cells = <1>; 23 + #size-cells = <1>; 24 + reg = <0x8000c000 2000>, <0x8000a000 2000>; 25 + reg-names = "gpmi-nand", "bch"; 26 + interrupts = <88>, <41>; 27 + interrupt-names = "gpmi-dma", "bch"; 28 + fsl,gpmi-dma-channel = <4>; 29 + 30 + partition@0 { 31 + ... 32 + }; 33 + };
+4 -3
drivers/mtd/nand/gpmi-nand/gpmi-lib.c
··· 256 256 return max(k, min); 257 257 } 258 258 259 + #define DEF_MIN_PROP_DELAY 5 260 + #define DEF_MAX_PROP_DELAY 9 259 261 /* Apply timing to current hardware conditions. */ 260 262 static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this, 261 263 struct gpmi_nfc_hardware_timing *hw) 262 264 { 263 - struct gpmi_nand_platform_data *pdata = this->pdata; 264 265 struct timing_threshod *nfc = &timing_default_threshold; 265 266 struct nand_chip *nand = &this->nand; 266 267 struct nand_timing target = this->timing; ··· 278 277 int ideal_sample_delay_in_ns; 279 278 unsigned int sample_delay_factor; 280 279 int tEYE; 281 - unsigned int min_prop_delay_in_ns = pdata->min_prop_delay_in_ns; 282 - unsigned int max_prop_delay_in_ns = pdata->max_prop_delay_in_ns; 280 + unsigned int min_prop_delay_in_ns = DEF_MIN_PROP_DELAY; 281 + unsigned int max_prop_delay_in_ns = DEF_MAX_PROP_DELAY; 283 282 284 283 /* 285 284 * If there are multiple chips, we need to relax the timings to allow
+65 -67
drivers/mtd/nand/gpmi-nand/gpmi-nand.c
··· 24 24 #include <linux/module.h> 25 25 #include <linux/mtd/gpmi-nand.h> 26 26 #include <linux/mtd/partitions.h> 27 + #include <linux/of.h> 28 + #include <linux/of_device.h> 27 29 #include "gpmi-nand.h" 28 30 29 31 /* add our owner bbt descriptor */ ··· 388 386 static bool gpmi_dma_filter(struct dma_chan *chan, void *param) 389 387 { 390 388 struct gpmi_nand_data *this = param; 391 - struct resource *r = this->private; 389 + int dma_channel = (int)this->private; 392 390 393 391 if (!mxs_dma_is_apbh(chan)) 394 392 return false; ··· 400 398 * for mx28 : MX28_DMA_GPMI0 ~ MX28_DMA_GPMI7 401 399 * (These eight channels share the same IRQ!) 402 400 */ 403 - if (r->start <= chan->chan_id && chan->chan_id <= r->end) { 401 + if (dma_channel == chan->chan_id) { 404 402 chan->private = &this->dma_data; 405 403 return true; 406 404 } ··· 420 418 static int __devinit acquire_dma_channels(struct gpmi_nand_data *this) 421 419 { 422 420 struct platform_device *pdev = this->pdev; 423 - struct gpmi_nand_platform_data *pdata = this->pdata; 424 - struct resources *res = &this->resources; 425 - struct resource *r, *r_dma; 426 - unsigned int i; 421 + struct resource *r_dma; 422 + struct device_node *dn; 423 + int dma_channel; 424 + unsigned int ret; 425 + struct dma_chan *dma_chan; 426 + dma_cap_mask_t mask; 427 427 428 - r = platform_get_resource_byname(pdev, IORESOURCE_DMA, 429 - GPMI_NAND_DMA_CHANNELS_RES_NAME); 428 + /* dma channel, we only use the first one. */ 429 + dn = pdev->dev.of_node; 430 + ret = of_property_read_u32(dn, "fsl,gpmi-dma-channel", &dma_channel); 431 + if (ret) { 432 + pr_err("unable to get DMA channel from dt.\n"); 433 + goto acquire_err; 434 + } 435 + this->private = (void *)dma_channel; 436 + 437 + /* gpmi dma interrupt */ 430 438 r_dma = platform_get_resource_byname(pdev, IORESOURCE_IRQ, 431 439 GPMI_NAND_DMA_INTERRUPT_RES_NAME); 432 - if (!r || !r_dma) { 440 + if (!r_dma) { 433 441 pr_err("Can't get resource for DMA\n"); 434 - return -ENXIO; 442 + goto acquire_err; 443 + } 444 + this->dma_data.chan_irq = r_dma->start; 445 + 446 + /* request dma channel */ 447 + dma_cap_zero(mask); 448 + dma_cap_set(DMA_SLAVE, mask); 449 + 450 + dma_chan = dma_request_channel(mask, gpmi_dma_filter, this); 451 + if (!dma_chan) { 452 + pr_err("dma_request_channel failed.\n"); 453 + goto acquire_err; 435 454 } 436 455 437 - /* used in gpmi_dma_filter() */ 438 - this->private = r; 439 - 440 - for (i = r->start; i <= r->end; i++) { 441 - struct dma_chan *dma_chan; 442 - dma_cap_mask_t mask; 443 - 444 - if (i - r->start >= pdata->max_chip_count) 445 - break; 446 - 447 - dma_cap_zero(mask); 448 - dma_cap_set(DMA_SLAVE, mask); 449 - 450 - /* get the DMA interrupt */ 451 - if (r_dma->start == r_dma->end) { 452 - /* only register the first. */ 453 - if (i == r->start) 454 - this->dma_data.chan_irq = r_dma->start; 455 - else 456 - this->dma_data.chan_irq = NO_IRQ; 457 - } else 458 - this->dma_data.chan_irq = r_dma->start + (i - r->start); 459 - 460 - dma_chan = dma_request_channel(mask, gpmi_dma_filter, this); 461 - if (!dma_chan) 462 - goto acquire_err; 463 - 464 - /* fill the first empty item */ 465 - this->dma_chans[i - r->start] = dma_chan; 466 - } 467 - 468 - res->dma_low_channel = r->start; 469 - res->dma_high_channel = i; 456 + this->dma_chans[0] = dma_chan; 470 457 return 0; 471 458 472 459 acquire_err: 473 - pr_err("Can't acquire DMA channel %u\n", i); 474 460 release_dma_channels(this); 475 461 return -EINVAL; 476 462 } ··· 1455 1465 1456 1466 static int __devinit gpmi_nfc_init(struct gpmi_nand_data *this) 1457 1467 { 1458 - struct gpmi_nand_platform_data *pdata = this->pdata; 1459 1468 struct mtd_info *mtd = &this->mtd; 1460 1469 struct nand_chip *chip = &this->nand; 1470 + struct mtd_part_parser_data ppdata = {}; 1461 1471 int ret; 1462 1472 1463 1473 /* init current chip */ ··· 1495 1505 if (ret) 1496 1506 goto err_out; 1497 1507 1498 - ret = nand_scan(mtd, pdata->max_chip_count); 1508 + ret = nand_scan(mtd, 1); 1499 1509 if (ret) { 1500 1510 pr_err("Chip scan failed\n"); 1501 1511 goto err_out; 1502 1512 } 1503 1513 1504 - ret = mtd_device_parse_register(mtd, NULL, NULL, 1505 - pdata->partitions, pdata->partition_count); 1514 + ppdata.of_node = this->pdev->dev.of_node; 1515 + ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); 1506 1516 if (ret) 1507 1517 goto err_out; 1508 1518 return 0; ··· 1512 1522 return ret; 1513 1523 } 1514 1524 1525 + static const struct platform_device_id gpmi_ids[] = { 1526 + { .name = "imx23-gpmi-nand", .driver_data = IS_MX23, }, 1527 + { .name = "imx28-gpmi-nand", .driver_data = IS_MX28, }, 1528 + {}, 1529 + }; 1530 + 1531 + static const struct of_device_id gpmi_nand_id_table[] = { 1532 + { 1533 + .compatible = "fsl,imx23-gpmi-nand", 1534 + .data = (void *)&gpmi_ids[IS_MX23] 1535 + }, { 1536 + .compatible = "fsl,imx28-gpmi-nand", 1537 + .data = (void *)&gpmi_ids[IS_MX28] 1538 + }, {} 1539 + }; 1540 + MODULE_DEVICE_TABLE(of, gpmi_nand_id_table); 1541 + 1515 1542 static int __devinit gpmi_nand_probe(struct platform_device *pdev) 1516 1543 { 1517 - struct gpmi_nand_platform_data *pdata = pdev->dev.platform_data; 1518 1544 struct gpmi_nand_data *this; 1545 + const struct of_device_id *of_id; 1519 1546 int ret; 1547 + 1548 + of_id = of_match_device(gpmi_nand_id_table, &pdev->dev); 1549 + if (of_id) { 1550 + pdev->id_entry = of_id->data; 1551 + } else { 1552 + pr_err("Failed to find the right device id.\n"); 1553 + return -ENOMEM; 1554 + } 1520 1555 1521 1556 this = kzalloc(sizeof(*this), GFP_KERNEL); 1522 1557 if (!this) { ··· 1552 1537 platform_set_drvdata(pdev, this); 1553 1538 this->pdev = pdev; 1554 1539 this->dev = &pdev->dev; 1555 - this->pdata = pdata; 1556 - 1557 - if (pdata->platform_init) { 1558 - ret = pdata->platform_init(); 1559 - if (ret) 1560 - goto platform_init_error; 1561 - } 1562 1540 1563 1541 ret = acquire_resources(this); 1564 1542 if (ret) ··· 1569 1561 1570 1562 exit_nfc_init: 1571 1563 release_resources(this); 1572 - platform_init_error: 1573 1564 exit_acquire_resources: 1574 1565 platform_set_drvdata(pdev, NULL); 1575 1566 kfree(this); ··· 1586 1579 return 0; 1587 1580 } 1588 1581 1589 - static const struct platform_device_id gpmi_ids[] = { 1590 - { 1591 - .name = "imx23-gpmi-nand", 1592 - .driver_data = IS_MX23, 1593 - }, { 1594 - .name = "imx28-gpmi-nand", 1595 - .driver_data = IS_MX28, 1596 - }, {}, 1597 - }; 1598 - 1599 1582 static struct platform_driver gpmi_nand_driver = { 1600 1583 .driver = { 1601 1584 .name = "gpmi-nand", 1585 + .of_match_table = gpmi_nand_id_table, 1602 1586 }, 1603 1587 .probe = gpmi_nand_probe, 1604 1588 .remove = __exit_p(gpmi_nand_remove),
+2 -2
drivers/mtd/nand/gpmi-nand/gpmi-nand.h
··· 266 266 #define STATUS_UNCORRECTABLE 0xfe 267 267 268 268 /* Use the platform_id to distinguish different Archs. */ 269 - #define IS_MX23 0x1 270 - #define IS_MX28 0x2 269 + #define IS_MX23 0x0 270 + #define IS_MX28 0x1 271 271 #define GPMI_IS_MX23(x) ((x)->pdev->id_entry->driver_data == IS_MX23) 272 272 #define GPMI_IS_MX28(x) ((x)->pdev->id_entry->driver_data == IS_MX28) 273 273 #endif
+4 -4
include/linux/mtd/gpmi-nand.h
··· 23 23 #define GPMI_NAND_RES_SIZE 6 24 24 25 25 /* Resource names for the GPMI NAND driver. */ 26 - #define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "GPMI NAND GPMI Registers" 26 + #define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "gpmi-nand" 27 27 #define GPMI_NAND_GPMI_INTERRUPT_RES_NAME "GPMI NAND GPMI Interrupt" 28 - #define GPMI_NAND_BCH_REGS_ADDR_RES_NAME "GPMI NAND BCH Registers" 29 - #define GPMI_NAND_BCH_INTERRUPT_RES_NAME "GPMI NAND BCH Interrupt" 28 + #define GPMI_NAND_BCH_REGS_ADDR_RES_NAME "bch" 29 + #define GPMI_NAND_BCH_INTERRUPT_RES_NAME "bch" 30 30 #define GPMI_NAND_DMA_CHANNELS_RES_NAME "GPMI NAND DMA Channels" 31 - #define GPMI_NAND_DMA_INTERRUPT_RES_NAME "GPMI NAND DMA Interrupt" 31 + #define GPMI_NAND_DMA_INTERRUPT_RES_NAME "gpmi-dma" 32 32 33 33 /** 34 34 * struct gpmi_nand_platform_data - GPMI NAND driver platform data.