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

mtd: onenand: omap2: Configure driver from DT

Move away from platform data configuration and use pure DT approach.

Use generic probe function to deal with OneNAND node and remove now useless
gpmc_probe_onenand_child function. Import sync mode timing calculation
function from mach-omap2/gpmc-onenand.c

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
Reviewed-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Tested-by: Tony Lindgren <tony@atomide.com>
Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Acked-by: Roger Quadros <rogerq@ti.com>
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>

authored by

Ladislav Michl and committed by
Boris Brezillon
a758f50f bdaca934

+300 -138
+117 -41
drivers/memory/omap-gpmc.c
··· 32 32 #include <linux/pm_runtime.h> 33 33 34 34 #include <linux/platform_data/mtd-nand-omap2.h> 35 - #include <linux/platform_data/mtd-onenand-omap2.h> 36 35 37 36 #include <asm/mach-types.h> 38 37 ··· 1137 1138 } 1138 1139 EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops); 1139 1140 1141 + static void gpmc_omap_onenand_calc_sync_timings(struct gpmc_timings *t, 1142 + struct gpmc_settings *s, 1143 + int freq, int latency) 1144 + { 1145 + struct gpmc_device_timings dev_t; 1146 + const int t_cer = 15; 1147 + const int t_avdp = 12; 1148 + const int t_cez = 20; /* max of t_cez, t_oez */ 1149 + const int t_wpl = 40; 1150 + const int t_wph = 30; 1151 + int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; 1152 + 1153 + switch (freq) { 1154 + case 104: 1155 + min_gpmc_clk_period = 9600; /* 104 MHz */ 1156 + t_ces = 3; 1157 + t_avds = 4; 1158 + t_avdh = 2; 1159 + t_ach = 3; 1160 + t_aavdh = 6; 1161 + t_rdyo = 6; 1162 + break; 1163 + case 83: 1164 + min_gpmc_clk_period = 12000; /* 83 MHz */ 1165 + t_ces = 5; 1166 + t_avds = 4; 1167 + t_avdh = 2; 1168 + t_ach = 6; 1169 + t_aavdh = 6; 1170 + t_rdyo = 9; 1171 + break; 1172 + case 66: 1173 + min_gpmc_clk_period = 15000; /* 66 MHz */ 1174 + t_ces = 6; 1175 + t_avds = 5; 1176 + t_avdh = 2; 1177 + t_ach = 6; 1178 + t_aavdh = 6; 1179 + t_rdyo = 11; 1180 + break; 1181 + default: 1182 + min_gpmc_clk_period = 18500; /* 54 MHz */ 1183 + t_ces = 7; 1184 + t_avds = 7; 1185 + t_avdh = 7; 1186 + t_ach = 9; 1187 + t_aavdh = 7; 1188 + t_rdyo = 15; 1189 + break; 1190 + } 1191 + 1192 + /* Set synchronous read timings */ 1193 + memset(&dev_t, 0, sizeof(dev_t)); 1194 + 1195 + if (!s->sync_write) { 1196 + dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000; 1197 + dev_t.t_wpl = t_wpl * 1000; 1198 + dev_t.t_wph = t_wph * 1000; 1199 + dev_t.t_aavdh = t_aavdh * 1000; 1200 + } 1201 + dev_t.ce_xdelay = true; 1202 + dev_t.avd_xdelay = true; 1203 + dev_t.oe_xdelay = true; 1204 + dev_t.we_xdelay = true; 1205 + dev_t.clk = min_gpmc_clk_period; 1206 + dev_t.t_bacc = dev_t.clk; 1207 + dev_t.t_ces = t_ces * 1000; 1208 + dev_t.t_avds = t_avds * 1000; 1209 + dev_t.t_avdh = t_avdh * 1000; 1210 + dev_t.t_ach = t_ach * 1000; 1211 + dev_t.cyc_iaa = (latency + 1); 1212 + dev_t.t_cez_r = t_cez * 1000; 1213 + dev_t.t_cez_w = dev_t.t_cez_r; 1214 + dev_t.cyc_aavdh_oe = 1; 1215 + dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period; 1216 + 1217 + gpmc_calc_timings(t, s, &dev_t); 1218 + } 1219 + 1220 + int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq, 1221 + int latency, 1222 + struct gpmc_onenand_info *info) 1223 + { 1224 + int ret; 1225 + struct gpmc_timings gpmc_t; 1226 + struct gpmc_settings gpmc_s; 1227 + 1228 + gpmc_read_settings_dt(dev->of_node, &gpmc_s); 1229 + 1230 + info->sync_read = gpmc_s.sync_read; 1231 + info->sync_write = gpmc_s.sync_write; 1232 + info->burst_len = gpmc_s.burst_len; 1233 + 1234 + if (!gpmc_s.sync_read && !gpmc_s.sync_write) 1235 + return 0; 1236 + 1237 + gpmc_omap_onenand_calc_sync_timings(&gpmc_t, &gpmc_s, freq, latency); 1238 + 1239 + ret = gpmc_cs_program_settings(cs, &gpmc_s); 1240 + if (ret < 0) 1241 + return ret; 1242 + 1243 + return gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s); 1244 + } 1245 + EXPORT_SYMBOL_GPL(gpmc_omap_onenand_set_timings); 1246 + 1140 1247 int gpmc_get_client_irq(unsigned irq_config) 1141 1248 { 1142 1249 if (!gpmc_irq_domain) { ··· 2021 1916 of_property_read_bool(np, "gpmc,time-para-granularity"); 2022 1917 } 2023 1918 2024 - #if IS_ENABLED(CONFIG_MTD_ONENAND) 2025 - static int gpmc_probe_onenand_child(struct platform_device *pdev, 2026 - struct device_node *child) 2027 - { 2028 - u32 val; 2029 - struct omap_onenand_platform_data *gpmc_onenand_data; 2030 - 2031 - if (of_property_read_u32(child, "reg", &val) < 0) { 2032 - dev_err(&pdev->dev, "%pOF has no 'reg' property\n", 2033 - child); 2034 - return -ENODEV; 2035 - } 2036 - 2037 - gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data), 2038 - GFP_KERNEL); 2039 - if (!gpmc_onenand_data) 2040 - return -ENOMEM; 2041 - 2042 - gpmc_onenand_data->cs = val; 2043 - gpmc_onenand_data->of_node = child; 2044 - gpmc_onenand_data->dma_channel = -1; 2045 - 2046 - if (!of_property_read_u32(child, "dma-channel", &val)) 2047 - gpmc_onenand_data->dma_channel = val; 2048 - 2049 - return gpmc_onenand_init(gpmc_onenand_data); 2050 - } 2051 - #else 2052 - static int gpmc_probe_onenand_child(struct platform_device *pdev, 2053 - struct device_node *child) 2054 - { 2055 - return 0; 2056 - } 2057 - #endif 2058 - 2059 1919 /** 2060 1920 * gpmc_probe_generic_child - configures the gpmc for a child device 2061 1921 * @pdev: pointer to gpmc platform device ··· 2118 2048 if (!of_property_read_bool(child, "compatible")) { 2119 2049 dev_warn(&pdev->dev, 2120 2050 "Incompatible NAND node: missing compatible"); 2051 + ret = -EINVAL; 2052 + goto err; 2053 + } 2054 + } 2055 + 2056 + if (of_node_cmp(child->name, "onenand") == 0) { 2057 + /* Warn about older DT blobs with no compatible property */ 2058 + if (!of_property_read_bool(child, "compatible")) { 2059 + dev_warn(&pdev->dev, 2060 + "Incompatible OneNAND node: missing compatible"); 2121 2061 ret = -EINVAL; 2122 2062 goto err; 2123 2063 } ··· 2269 2189 if (!child->name) 2270 2190 continue; 2271 2191 2272 - if (of_node_cmp(child->name, "onenand") == 0) 2273 - ret = gpmc_probe_onenand_child(pdev, child); 2274 - else 2275 - ret = gpmc_probe_generic_child(pdev, child); 2276 - 2192 + ret = gpmc_probe_generic_child(pdev, child); 2277 2193 if (ret) { 2278 2194 dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n", 2279 2195 child->name, ret);
+3 -1
drivers/mtd/onenand/Kconfig
··· 25 25 config MTD_ONENAND_OMAP2 26 26 tristate "OneNAND on OMAP2/OMAP3 support" 27 27 depends on ARCH_OMAP2 || ARCH_OMAP3 28 + depends on OF || COMPILE_TEST 28 29 help 29 - Support for a OneNAND flash device connected to an OMAP2/OMAP3 CPU 30 + Support for a OneNAND flash device connected to an OMAP2/OMAP3 SoC 30 31 via the GPMC memory controller. 32 + Enable dmaengine and gpiolib for better performance. 31 33 32 34 config MTD_ONENAND_SAMSUNG 33 35 tristate "OneNAND on Samsung SOC controller support"
+152 -96
drivers/mtd/onenand/omap2.c
··· 28 28 #include <linux/mtd/mtd.h> 29 29 #include <linux/mtd/onenand.h> 30 30 #include <linux/mtd/partitions.h> 31 + #include <linux/of_device.h> 32 + #include <linux/omap-gpmc.h> 31 33 #include <linux/platform_device.h> 32 34 #include <linux/interrupt.h> 33 35 #include <linux/delay.h> ··· 37 35 #include <linux/dmaengine.h> 38 36 #include <linux/io.h> 39 37 #include <linux/slab.h> 40 - #include <linux/gpio.h> 38 + #include <linux/gpio/consumer.h> 41 39 42 40 #include <asm/mach/flash.h> 43 - #include <linux/platform_data/mtd-onenand-omap2.h> 44 41 45 42 #define DRIVER_NAME "omap2-onenand" 46 43 ··· 49 48 struct platform_device *pdev; 50 49 int gpmc_cs; 51 50 unsigned long phys_base; 52 - unsigned int mem_size; 53 - int gpio_irq; 51 + struct gpio_desc *int_gpiod; 54 52 struct mtd_info mtd; 55 53 struct onenand_chip onenand; 56 54 struct completion irq_done; 57 55 struct completion dma_done; 58 56 struct dma_chan *dma_chan; 59 - int freq; 60 - int (*setup)(void __iomem *base, int *freq_ptr); 61 57 }; 62 58 63 59 static void omap2_onenand_dma_complete_func(void *completion) ··· 80 82 int reg) 81 83 { 82 84 writew(value, c->onenand.base + reg); 85 + } 86 + 87 + static int omap2_onenand_set_cfg(struct omap2_onenand *c, 88 + bool sr, bool sw, 89 + int latency, int burst_len) 90 + { 91 + unsigned short reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT; 92 + 93 + reg |= latency << ONENAND_SYS_CFG1_BRL_SHIFT; 94 + 95 + switch (burst_len) { 96 + case 0: /* continuous */ 97 + break; 98 + case 4: 99 + reg |= ONENAND_SYS_CFG1_BL_4; 100 + break; 101 + case 8: 102 + reg |= ONENAND_SYS_CFG1_BL_8; 103 + break; 104 + case 16: 105 + reg |= ONENAND_SYS_CFG1_BL_16; 106 + break; 107 + case 32: 108 + reg |= ONENAND_SYS_CFG1_BL_32; 109 + break; 110 + default: 111 + return -EINVAL; 112 + } 113 + 114 + if (latency > 5) 115 + reg |= ONENAND_SYS_CFG1_HF; 116 + if (latency > 7) 117 + reg |= ONENAND_SYS_CFG1_VHF; 118 + if (sr) 119 + reg |= ONENAND_SYS_CFG1_SYNC_READ; 120 + if (sw) 121 + reg |= ONENAND_SYS_CFG1_SYNC_WRITE; 122 + 123 + write_reg(c, reg, ONENAND_REG_SYS_CFG1); 124 + 125 + return 0; 126 + } 127 + 128 + static int omap2_onenand_get_freq(int ver) 129 + { 130 + switch ((ver >> 4) & 0xf) { 131 + case 0: 132 + return 40; 133 + case 1: 134 + return 54; 135 + case 2: 136 + return 66; 137 + case 3: 138 + return 83; 139 + case 4: 140 + return 104; 141 + } 142 + 143 + return -EINVAL; 83 144 } 84 145 85 146 static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr) ··· 209 152 } 210 153 211 154 reinit_completion(&c->irq_done); 212 - result = gpio_get_value(c->gpio_irq); 155 + result = gpiod_get_value(c->int_gpiod); 213 156 if (result < 0) { 214 157 ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS); 215 158 intr = read_reg(c, ONENAND_REG_INTERRUPT); 216 159 wait_err("gpio error", state, ctrl, intr); 217 - return -EIO; 160 + return result; 218 161 } else if (result == 0) { 219 162 int retry_cnt = 0; 220 163 retry: ··· 488 431 return 0; 489 432 } 490 433 491 - static struct platform_driver omap2_onenand_driver; 492 - 493 434 static void omap2_onenand_shutdown(struct platform_device *pdev) 494 435 { 495 436 struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); ··· 501 446 502 447 static int omap2_onenand_probe(struct platform_device *pdev) 503 448 { 449 + u32 val; 504 450 dma_cap_mask_t mask; 505 - struct omap_onenand_platform_data *pdata; 506 - struct omap2_onenand *c; 507 - struct onenand_chip *this; 508 - int r; 451 + int freq, latency, r; 509 452 struct resource *res; 453 + struct omap2_onenand *c; 454 + struct gpmc_onenand_info info; 455 + struct device *dev = &pdev->dev; 456 + struct device_node *np = dev->of_node; 510 457 511 - pdata = dev_get_platdata(&pdev->dev); 512 - if (pdata == NULL) { 513 - dev_err(&pdev->dev, "platform data missing\n"); 514 - return -ENODEV; 458 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 459 + if (!res) { 460 + dev_err(dev, "error getting memory resource\n"); 461 + return -EINVAL; 515 462 } 516 463 517 - c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL); 464 + r = of_property_read_u32(np, "reg", &val); 465 + if (r) { 466 + dev_err(dev, "reg not found in DT\n"); 467 + return r; 468 + } 469 + 470 + c = devm_kzalloc(dev, sizeof(struct omap2_onenand), GFP_KERNEL); 518 471 if (!c) 519 472 return -ENOMEM; 520 473 521 474 init_completion(&c->irq_done); 522 475 init_completion(&c->dma_done); 523 - c->gpmc_cs = pdata->cs; 524 - c->gpio_irq = pdata->gpio_irq; 525 - if (pdata->dma_channel < 0) { 526 - /* if -1, don't use DMA */ 527 - c->gpio_irq = 0; 528 - } 529 - 530 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 531 - if (res == NULL) { 532 - r = -EINVAL; 533 - dev_err(&pdev->dev, "error getting memory resource\n"); 534 - goto err_kfree; 535 - } 536 - 476 + c->gpmc_cs = val; 537 477 c->phys_base = res->start; 538 - c->mem_size = resource_size(res); 539 478 540 - if (request_mem_region(c->phys_base, c->mem_size, 541 - pdev->dev.driver->name) == NULL) { 542 - dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n", 543 - c->phys_base, c->mem_size); 544 - r = -EBUSY; 545 - goto err_kfree; 546 - } 547 - c->onenand.base = ioremap(c->phys_base, c->mem_size); 548 - if (c->onenand.base == NULL) { 549 - r = -ENOMEM; 550 - goto err_release_mem_region; 479 + c->onenand.base = devm_ioremap_resource(dev, res); 480 + if (IS_ERR(c->onenand.base)) { 481 + dev_err(dev, "Cannot reserve memory region at 0x%08x, size: 0x%x\n", 482 + res->start, resource_size(res)); 483 + return PTR_ERR(c->onenand.base); 551 484 } 552 485 553 - if (pdata->onenand_setup != NULL) { 554 - r = pdata->onenand_setup(c->onenand.base, &c->freq); 555 - if (r < 0) { 556 - dev_err(&pdev->dev, "Onenand platform setup failed: " 557 - "%d\n", r); 558 - goto err_iounmap; 559 - } 560 - c->setup = pdata->onenand_setup; 486 + c->int_gpiod = devm_gpiod_get_optional(dev, "int", GPIOD_IN); 487 + if (IS_ERR(c->int_gpiod)) { 488 + r = PTR_ERR(c->int_gpiod); 489 + /* Just try again if this happens */ 490 + if (r != -EPROBE_DEFER) 491 + dev_err(dev, "error getting gpio: %d\n", r); 492 + return r; 561 493 } 562 494 563 - if (c->gpio_irq) { 564 - if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) { 565 - dev_err(&pdev->dev, "Failed to request GPIO%d for " 566 - "OneNAND\n", c->gpio_irq); 567 - goto err_iounmap; 568 - } 569 - gpio_direction_input(c->gpio_irq); 495 + if (c->int_gpiod) { 496 + r = devm_request_irq(dev, gpiod_to_irq(c->int_gpiod), 497 + omap2_onenand_interrupt, 498 + IRQF_TRIGGER_RISING, "onenand", c); 499 + if (r) 500 + return r; 570 501 571 - if ((r = request_irq(gpio_to_irq(c->gpio_irq), 572 - omap2_onenand_interrupt, IRQF_TRIGGER_RISING, 573 - pdev->dev.driver->name, c)) < 0) 574 - goto err_release_gpio; 575 - 576 - this->wait = omap2_onenand_wait; 502 + c->onenand.wait = omap2_onenand_wait; 577 503 } 578 504 579 505 dma_cap_zero(mask); 580 506 dma_cap_set(DMA_MEMCPY, mask); 581 507 582 508 c->dma_chan = dma_request_channel(mask, NULL, NULL); 583 - 584 - dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual " 585 - "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base, 586 - c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO"); 509 + if (c->dma_chan) { 510 + c->onenand.read_bufferram = omap2_onenand_read_bufferram; 511 + c->onenand.write_bufferram = omap2_onenand_write_bufferram; 512 + } 587 513 588 514 c->pdev = pdev; 589 515 c->mtd.priv = &c->onenand; 516 + c->mtd.dev.parent = dev; 517 + mtd_set_of_node(&c->mtd, dev->of_node); 590 518 591 - c->mtd.dev.parent = &pdev->dev; 592 - mtd_set_of_node(&c->mtd, pdata->of_node); 593 - 594 - this = &c->onenand; 595 - if (c->dma_chan) { 596 - this->read_bufferram = omap2_onenand_read_bufferram; 597 - this->write_bufferram = omap2_onenand_write_bufferram; 598 - } 519 + dev_info(dev, "initializing on CS%d (0x%08lx), va %p, %s mode\n", 520 + c->gpmc_cs, c->phys_base, c->onenand.base, 521 + c->dma_chan ? "DMA" : "PIO"); 599 522 600 523 if ((r = onenand_scan(&c->mtd, 1)) < 0) 601 524 goto err_release_dma; 525 + 526 + freq = omap2_onenand_get_freq(c->onenand.version_id); 527 + if (freq > 0) { 528 + switch (freq) { 529 + case 104: 530 + latency = 7; 531 + break; 532 + case 83: 533 + latency = 6; 534 + break; 535 + case 66: 536 + latency = 5; 537 + break; 538 + case 56: 539 + latency = 4; 540 + break; 541 + default: /* 40 MHz or lower */ 542 + latency = 3; 543 + break; 544 + } 545 + 546 + r = gpmc_omap_onenand_set_timings(dev, c->gpmc_cs, 547 + freq, latency, &info); 548 + if (r) 549 + goto err_release_onenand; 550 + 551 + r = omap2_onenand_set_cfg(c, info.sync_read, info.sync_write, 552 + latency, info.burst_len); 553 + if (r) 554 + goto err_release_onenand; 555 + 556 + if (info.sync_read || info.sync_write) 557 + dev_info(dev, "optimized timings for %d MHz\n", freq); 558 + } 602 559 603 560 r = mtd_device_register(&c->mtd, NULL, 0); 604 561 if (r) ··· 625 558 err_release_dma: 626 559 if (c->dma_chan) 627 560 dma_release_channel(c->dma_chan); 628 - if (c->gpio_irq) 629 - free_irq(gpio_to_irq(c->gpio_irq), c); 630 - err_release_gpio: 631 - if (c->gpio_irq) 632 - gpio_free(c->gpio_irq); 633 - err_iounmap: 634 - iounmap(c->onenand.base); 635 - err_release_mem_region: 636 - release_mem_region(c->phys_base, c->mem_size); 637 - err_kfree: 638 - kfree(c); 639 561 640 562 return r; 641 563 } ··· 637 581 if (c->dma_chan) 638 582 dma_release_channel(c->dma_chan); 639 583 omap2_onenand_shutdown(pdev); 640 - if (c->gpio_irq) { 641 - free_irq(gpio_to_irq(c->gpio_irq), c); 642 - gpio_free(c->gpio_irq); 643 - } 644 - iounmap(c->onenand.base); 645 - release_mem_region(c->phys_base, c->mem_size); 646 - kfree(c); 647 584 648 585 return 0; 649 586 } 587 + 588 + static const struct of_device_id omap2_onenand_id_table[] = { 589 + { .compatible = "ti,omap2-onenand", }, 590 + {}, 591 + }; 592 + MODULE_DEVICE_TABLE(of, omap2_onenand_id_table); 650 593 651 594 static struct platform_driver omap2_onenand_driver = { 652 595 .probe = omap2_onenand_probe, ··· 653 598 .shutdown = omap2_onenand_shutdown, 654 599 .driver = { 655 600 .name = DRIVER_NAME, 601 + .of_match_table = omap2_onenand_id_table, 656 602 }, 657 603 }; 658 604
+28
include/linux/omap-gpmc.h
··· 25 25 26 26 struct gpmc_nand_regs; 27 27 28 + struct gpmc_onenand_info { 29 + bool sync_read; 30 + bool sync_write; 31 + int burst_len; 32 + }; 33 + 28 34 #if IS_ENABLED(CONFIG_OMAP_GPMC) 29 35 struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs, 30 36 int cs); 37 + /** 38 + * gpmc_omap_onenand_set_timings - set optimized sync timings. 39 + * @cs: Chip Select Region 40 + * @freq: Chip frequency 41 + * @latency: Burst latency cycle count 42 + * @info: Structure describing parameters used 43 + * 44 + * Sets optimized timings for the @cs region based on @freq and @latency. 45 + * Updates the @info structure based on the GPMC settings. 46 + */ 47 + int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq, 48 + int latency, 49 + struct gpmc_onenand_info *info); 50 + 31 51 #else 32 52 static inline struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs, 33 53 int cs) 34 54 { 35 55 return NULL; 56 + } 57 + 58 + static inline 59 + int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq, 60 + int latency, 61 + struct gpmc_onenand_info *info) 62 + { 63 + return -EINVAL; 36 64 } 37 65 #endif /* CONFIG_OMAP_GPMC */ 38 66