aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2013-02-05 17:03:31 -0500
committerOlof Johansson <olof@lixom.net>2013-02-05 17:03:45 -0500
commitb6a03d0492dedb5c10b8a5708ee92e04b0590c07 (patch)
tree21774ee93c50847fe1ea044f2cabae0746ac39d3
parent3e93093ecd0c144e86a86cc1f165221b6cd3e7fb (diff)
parent97c794a1e37b1ca128ef38f17c069186bfa5fb1b (diff)
Merge tag 'omap-for-v3.9/gpmc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/drivers
From Tony Lindgren: OMAP GPMC (General Purpose Memory Controller) changes to add device tree bindings. * tag 'omap-for-v3.9/gpmc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: ARM: OMAP2+: gpmc: Add device tree documentation for elm handle ARM: OMAP2+: gpmc: add DT bindings for OneNAND ARM: OMAP2+: gpmc-onenand: drop __init annotation mtd: omap-onenand: pass device_node in platform data ARM: OMAP2+: Prevent potential crash if GPMC probe fails ARM: OMAP2+: gpmc: Remove unneeded of_node_put() ARM: OMAP: gpmc: add DT bindings for GPMC timings and NAND ARM: OMAP: gpmc: enable hwecc for AM33xx SoCs ARM: OMAP: gpmc-nand: drop __init annotation mtd: omap-nand: pass device_node in platform data ARM: OMAP: gpmc: don't create devices from initcall on DT Signed-off-by: Olof Johansson <olof@lixom.net>
-rw-r--r--Documentation/devicetree/bindings/bus/ti-gpmc.txt84
-rw-r--r--Documentation/devicetree/bindings/mtd/gpmc-nand.txt80
-rw-r--r--Documentation/devicetree/bindings/mtd/gpmc-onenand.txt43
-rw-r--r--arch/arm/mach-omap2/gpmc-nand.c15
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c2
-rw-r--r--arch/arm/mach-omap2/gpmc.c232
-rw-r--r--drivers/mtd/nand/omap2.c4
-rw-r--r--drivers/mtd/onenand/omap2.c4
-rw-r--r--include/linux/platform_data/mtd-nand-omap2.h4
-rw-r--r--include/linux/platform_data/mtd-onenand-omap2.h3
10 files changed, 459 insertions, 12 deletions
diff --git a/Documentation/devicetree/bindings/bus/ti-gpmc.txt b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
new file mode 100644
index 000000000000..5ddb2e9efaaa
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/ti-gpmc.txt
@@ -0,0 +1,84 @@
1Device tree bindings for OMAP general purpose memory controllers (GPMC)
2
3The actual devices are instantiated from the child nodes of a GPMC node.
4
5Required properties:
6
7 - compatible: Should be set to one of the following:
8
9 ti,omap2420-gpmc (omap2420)
10 ti,omap2430-gpmc (omap2430)
11 ti,omap3430-gpmc (omap3430 & omap3630)
12 ti,omap4430-gpmc (omap4430 & omap4460 & omap543x)
13 ti,am3352-gpmc (am335x devices)
14
15 - reg: A resource specifier for the register space
16 (see the example below)
17 - ti,hwmods: Should be set to "ti,gpmc" until the DT transition is
18 completed.
19 - #address-cells: Must be set to 2 to allow memory address translation
20 - #size-cells: Must be set to 1 to allow CS address passing
21 - gpmc,num-cs: The maximum number of chip-select lines that controller
22 can support.
23 - gpmc,num-waitpins: The maximum number of wait pins that controller can
24 support.
25 - ranges: Must be set up to reflect the memory layout with four
26 integer values for each chip-select line in use:
27
28 <cs-number> 0 <physical address of mapping> <size>
29
30 Currently, calculated values derived from the contents
31 of the per-CS register GPMC_CONFIG7 (as set up by the
32 bootloader) are used for the physical address decoding.
33 As this will change in the future, filling correct
34 values here is a requirement.
35
36Timing properties for child nodes. All are optional and default to 0.
37
38 - gpmc,sync-clk: Minimum clock period for synchronous mode, in picoseconds
39
40 Chip-select signal timings corresponding to GPMC_CONFIG2:
41 - gpmc,cs-on: Assertion time
42 - gpmc,cs-rd-off: Read deassertion time
43 - gpmc,cs-wr-off: Write deassertion time
44
45 ADV signal timings corresponding to GPMC_CONFIG3:
46 - gpmc,adv-on: Assertion time
47 - gpmc,adv-rd-off: Read deassertion time
48 - gpmc,adv-wr-off: Write deassertion time
49
50 WE signals timings corresponding to GPMC_CONFIG4:
51 - gpmc,we-on: Assertion time
52 - gpmc,we-off: Deassertion time
53
54 OE signals timings corresponding to GPMC_CONFIG4:
55 - gpmc,oe-on: Assertion time
56 - gpmc,oe-off: Deassertion time
57
58 Access time and cycle time timings corresponding to GPMC_CONFIG5:
59 - gpmc,page-burst-access: Multiple access word delay
60 - gpmc,access: Start-cycle to first data valid delay
61 - gpmc,rd-cycle: Total read cycle time
62 - gpmc,wr-cycle: Total write cycle time
63
64The following are only applicable to OMAP3+ and AM335x:
65 - gpmc,wr-access
66 - gpmc,wr-data-mux-bus
67
68
69Example for an AM33xx board:
70
71 gpmc: gpmc@50000000 {
72 compatible = "ti,am3352-gpmc";
73 ti,hwmods = "gpmc";
74 reg = <0x50000000 0x2000>;
75 interrupts = <100>;
76
77 gpmc,num-cs = <8>;
78 gpmc,num-waitpins = <2>;
79 #address-cells = <2>;
80 #size-cells = <1>;
81 ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
82
83 /* child nodes go here */
84 };
diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
new file mode 100644
index 000000000000..e7f8d7ed47eb
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -0,0 +1,80 @@
1Device tree bindings for GPMC connected NANDs
2
3GPMC connected NAND (found on OMAP boards) are represented as child nodes of
4the GPMC controller with a name of "nand".
5
6All timing relevant properties as well as generic gpmc child properties are
7explained in a separate documents - please refer to
8Documentation/devicetree/bindings/bus/ti-gpmc.txt
9
10For NAND specific properties such as ECC modes or bus width, please refer to
11Documentation/devicetree/bindings/mtd/nand.txt
12
13
14Required properties:
15
16 - reg: The CS line the peripheral is connected to
17
18Optional properties:
19
20 - nand-bus-width: Set this numeric value to 16 if the hardware
21 is wired that way. If not specified, a bus
22 width of 8 is assumed.
23
24 - ti,nand-ecc-opt: A string setting the ECC layout to use. One of:
25
26 "sw" Software method (default)
27 "hw" Hardware method
28 "hw-romcode" gpmc hamming mode method & romcode layout
29 "bch4" 4-bit BCH ecc code
30 "bch8" 8-bit BCH ecc code
31
32 - elm_id: Specifies elm device node. This is required to support BCH
33 error correction using ELM module.
34
35For inline partiton table parsing (optional):
36
37 - #address-cells: should be set to 1
38 - #size-cells: should be set to 1
39
40Example for an AM33xx board:
41
42 gpmc: gpmc@50000000 {
43 compatible = "ti,am3352-gpmc";
44 ti,hwmods = "gpmc";
45 reg = <0x50000000 0x1000000>;
46 interrupts = <100>;
47 gpmc,num-cs = <8>;
48 gpmc,num-waitpins = <2>;
49 #address-cells = <2>;
50 #size-cells = <1>;
51 ranges = <0 0 0x08000000 0x2000>; /* CS0: NAND */
52 elm_id = <&elm>;
53
54 nand@0,0 {
55 reg = <0 0 0>; /* CS0, offset 0 */
56 nand-bus-width = <16>;
57 ti,nand-ecc-opt = "bch8";
58
59 gpmc,sync-clk = <0>;
60 gpmc,cs-on = <0>;
61 gpmc,cs-rd-off = <44>;
62 gpmc,cs-wr-off = <44>;
63 gpmc,adv-on = <6>;
64 gpmc,adv-rd-off = <34>;
65 gpmc,adv-wr-off = <44>;
66 gpmc,we-off = <40>;
67 gpmc,oe-off = <54>;
68 gpmc,access = <64>;
69 gpmc,rd-cycle = <82>;
70 gpmc,wr-cycle = <82>;
71 gpmc,wr-access = <40>;
72 gpmc,wr-data-mux-bus = <0>;
73
74 #address-cells = <1>;
75 #size-cells = <1>;
76
77 /* partitions go here */
78 };
79 };
80
diff --git a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
new file mode 100644
index 000000000000..deec9da224a2
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
@@ -0,0 +1,43 @@
1Device tree bindings for GPMC connected OneNANDs
2
3GPMC connected OneNAND (found on OMAP boards) are represented as child nodes of
4the GPMC controller with a name of "onenand".
5
6All timing relevant properties as well as generic gpmc child properties are
7explained in a separate documents - please refer to
8Documentation/devicetree/bindings/bus/ti-gpmc.txt
9
10Required properties:
11
12 - reg: The CS line the peripheral is connected to
13
14Optional properties:
15
16 - dma-channel: DMA Channel index
17
18For inline partiton table parsing (optional):
19
20 - #address-cells: should be set to 1
21 - #size-cells: should be set to 1
22
23Example for an OMAP3430 board:
24
25 gpmc: gpmc@6e000000 {
26 compatible = "ti,omap3430-gpmc";
27 ti,hwmods = "gpmc";
28 reg = <0x6e000000 0x1000000>;
29 interrupts = <20>;
30 gpmc,num-cs = <8>;
31 gpmc,num-waitpins = <4>;
32 #address-cells = <2>;
33 #size-cells = <1>;
34
35 onenand@0 {
36 reg = <0 0 0>; /* CS0, offset 0 */
37
38 #address-cells = <1>;
39 #size-cells = <1>;
40
41 /* partitions go here */
42 };
43 };
diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index db969a5c4998..afc1e8c32d6c 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -89,20 +89,21 @@ static int omap2_nand_gpmc_retime(
89 return 0; 89 return 0;
90} 90}
91 91
92static bool __init gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt) 92static bool gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
93{ 93{
94 /* support only OMAP3 class */ 94 /* support only OMAP3 class */
95 if (!cpu_is_omap34xx()) { 95 if (!cpu_is_omap34xx() && !soc_is_am33xx()) {
96 pr_err("BCH ecc is not supported on this CPU\n"); 96 pr_err("BCH ecc is not supported on this CPU\n");
97 return 0; 97 return 0;
98 } 98 }
99 99
100 /* 100 /*
101 * For now, assume 4-bit mode is only supported on OMAP3630 ES1.x, x>=1. 101 * For now, assume 4-bit mode is only supported on OMAP3630 ES1.x, x>=1
102 * Other chips may be added if confirmed to work. 102 * and AM33xx derivates. Other chips may be added if confirmed to work.
103 */ 103 */
104 if ((ecc_opt == OMAP_ECC_BCH4_CODE_HW) && 104 if ((ecc_opt == OMAP_ECC_BCH4_CODE_HW) &&
105 (!cpu_is_omap3630() || (GET_OMAP_REVISION() == 0))) { 105 (!cpu_is_omap3630() || (GET_OMAP_REVISION() == 0)) &&
106 (!soc_is_am33xx())) {
106 pr_err("BCH 4-bit mode is not supported on this CPU\n"); 107 pr_err("BCH 4-bit mode is not supported on this CPU\n");
107 return 0; 108 return 0;
108 } 109 }
@@ -110,8 +111,8 @@ static bool __init gpmc_hwecc_bch_capable(enum omap_ecc ecc_opt)
110 return 1; 111 return 1;
111} 112}
112 113
113int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data, 114int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
114 struct gpmc_timings *gpmc_t) 115 struct gpmc_timings *gpmc_t)
115{ 116{
116 int err = 0; 117 int err = 0;
117 struct device *dev = &gpmc_nand_device.dev; 118 struct device *dev = &gpmc_nand_device.dev;
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 94a349e4dc96..fadd87435cd0 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -356,7 +356,7 @@ static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
356 return ret; 356 return ret;
357} 357}
358 358
359void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) 359void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
360{ 360{
361 int err; 361 int err;
362 362
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 8033cb747c86..1adb2d4496f6 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -25,6 +25,10 @@
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/of.h>
29#include <linux/of_mtd.h>
30#include <linux/of_device.h>
31#include <linux/mtd/nand.h>
28 32
29#include <linux/platform_data/mtd-nand-omap2.h> 33#include <linux/platform_data/mtd-nand-omap2.h>
30 34
@@ -34,6 +38,8 @@
34#include "common.h" 38#include "common.h"
35#include "omap_device.h" 39#include "omap_device.h"
36#include "gpmc.h" 40#include "gpmc.h"
41#include "gpmc-nand.h"
42#include "gpmc-onenand.h"
37 43
38#define DEVICE_NAME "omap-gpmc" 44#define DEVICE_NAME "omap-gpmc"
39 45
@@ -145,7 +151,8 @@ static unsigned gpmc_irq_start;
145static struct resource gpmc_mem_root; 151static struct resource gpmc_mem_root;
146static struct resource gpmc_cs_mem[GPMC_CS_NUM]; 152static struct resource gpmc_cs_mem[GPMC_CS_NUM];
147static DEFINE_SPINLOCK(gpmc_mem_lock); 153static DEFINE_SPINLOCK(gpmc_mem_lock);
148static unsigned int gpmc_cs_map; /* flag for cs which are initialized */ 154/* Define chip-selects as reserved by default until probe completes */
155static unsigned int gpmc_cs_map = ((1 << GPMC_CS_NUM) - 1);
149static struct device *gpmc_dev; 156static struct device *gpmc_dev;
150static int gpmc_irq; 157static int gpmc_irq;
151static resource_size_t phys_base, mem_size; 158static resource_size_t phys_base, mem_size;
@@ -1118,9 +1125,216 @@ int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
1118 /* TODO: remove, see function definition */ 1125 /* TODO: remove, see function definition */
1119 gpmc_convert_ps_to_ns(gpmc_t); 1126 gpmc_convert_ps_to_ns(gpmc_t);
1120 1127
1128 /* Now the GPMC is initialised, unreserve the chip-selects */
1129 gpmc_cs_map = 0;
1130
1121 return 0; 1131 return 0;
1122} 1132}
1123 1133
1134#ifdef CONFIG_OF
1135static struct of_device_id gpmc_dt_ids[] = {
1136 { .compatible = "ti,omap2420-gpmc" },
1137 { .compatible = "ti,omap2430-gpmc" },
1138 { .compatible = "ti,omap3430-gpmc" }, /* omap3430 & omap3630 */
1139 { .compatible = "ti,omap4430-gpmc" }, /* omap4430 & omap4460 & omap543x */
1140 { .compatible = "ti,am3352-gpmc" }, /* am335x devices */
1141 { }
1142};
1143MODULE_DEVICE_TABLE(of, gpmc_dt_ids);
1144
1145static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
1146 struct gpmc_timings *gpmc_t)
1147{
1148 u32 val;
1149
1150 memset(gpmc_t, 0, sizeof(*gpmc_t));
1151
1152 /* minimum clock period for syncronous mode */
1153 if (!of_property_read_u32(np, "gpmc,sync-clk", &val))
1154 gpmc_t->sync_clk = val;
1155
1156 /* chip select timtings */
1157 if (!of_property_read_u32(np, "gpmc,cs-on", &val))
1158 gpmc_t->cs_on = val;
1159
1160 if (!of_property_read_u32(np, "gpmc,cs-rd-off", &val))
1161 gpmc_t->cs_rd_off = val;
1162
1163 if (!of_property_read_u32(np, "gpmc,cs-wr-off", &val))
1164 gpmc_t->cs_wr_off = val;
1165
1166 /* ADV signal timings */
1167 if (!of_property_read_u32(np, "gpmc,adv-on", &val))
1168 gpmc_t->adv_on = val;
1169
1170 if (!of_property_read_u32(np, "gpmc,adv-rd-off", &val))
1171 gpmc_t->adv_rd_off = val;
1172
1173 if (!of_property_read_u32(np, "gpmc,adv-wr-off", &val))
1174 gpmc_t->adv_wr_off = val;
1175
1176 /* WE signal timings */
1177 if (!of_property_read_u32(np, "gpmc,we-on", &val))
1178 gpmc_t->we_on = val;
1179
1180 if (!of_property_read_u32(np, "gpmc,we-off", &val))
1181 gpmc_t->we_off = val;
1182
1183 /* OE signal timings */
1184 if (!of_property_read_u32(np, "gpmc,oe-on", &val))
1185 gpmc_t->oe_on = val;
1186
1187 if (!of_property_read_u32(np, "gpmc,oe-off", &val))
1188 gpmc_t->oe_off = val;
1189
1190 /* access and cycle timings */
1191 if (!of_property_read_u32(np, "gpmc,page-burst-access", &val))
1192 gpmc_t->page_burst_access = val;
1193
1194 if (!of_property_read_u32(np, "gpmc,access", &val))
1195 gpmc_t->access = val;
1196
1197 if (!of_property_read_u32(np, "gpmc,rd-cycle", &val))
1198 gpmc_t->rd_cycle = val;
1199
1200 if (!of_property_read_u32(np, "gpmc,wr-cycle", &val))
1201 gpmc_t->wr_cycle = val;
1202
1203 /* only for OMAP3430 */
1204 if (!of_property_read_u32(np, "gpmc,wr-access", &val))
1205 gpmc_t->wr_access = val;
1206
1207 if (!of_property_read_u32(np, "gpmc,wr-data-mux-bus", &val))
1208 gpmc_t->wr_data_mux_bus = val;
1209}
1210
1211#ifdef CONFIG_MTD_NAND
1212
1213static const char * const nand_ecc_opts[] = {
1214 [OMAP_ECC_HAMMING_CODE_DEFAULT] = "sw",
1215 [OMAP_ECC_HAMMING_CODE_HW] = "hw",
1216 [OMAP_ECC_HAMMING_CODE_HW_ROMCODE] = "hw-romcode",
1217 [OMAP_ECC_BCH4_CODE_HW] = "bch4",
1218 [OMAP_ECC_BCH8_CODE_HW] = "bch8",
1219};
1220
1221static int gpmc_probe_nand_child(struct platform_device *pdev,
1222 struct device_node *child)
1223{
1224 u32 val;
1225 const char *s;
1226 struct gpmc_timings gpmc_t;
1227 struct omap_nand_platform_data *gpmc_nand_data;
1228
1229 if (of_property_read_u32(child, "reg", &val) < 0) {
1230 dev_err(&pdev->dev, "%s has no 'reg' property\n",
1231 child->full_name);
1232 return -ENODEV;
1233 }
1234
1235 gpmc_nand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_nand_data),
1236 GFP_KERNEL);
1237 if (!gpmc_nand_data)
1238 return -ENOMEM;
1239
1240 gpmc_nand_data->cs = val;
1241 gpmc_nand_data->of_node = child;
1242
1243 if (!of_property_read_string(child, "ti,nand-ecc-opt", &s))
1244 for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++)
1245 if (!strcasecmp(s, nand_ecc_opts[val])) {
1246 gpmc_nand_data->ecc_opt = val;
1247 break;
1248 }
1249
1250 val = of_get_nand_bus_width(child);
1251 if (val == 16)
1252 gpmc_nand_data->devsize = NAND_BUSWIDTH_16;
1253
1254 gpmc_read_timings_dt(child, &gpmc_t);
1255 gpmc_nand_init(gpmc_nand_data, &gpmc_t);
1256
1257 return 0;
1258}
1259#else
1260static int gpmc_probe_nand_child(struct platform_device *pdev,
1261 struct device_node *child)
1262{
1263 return 0;
1264}
1265#endif
1266
1267#ifdef CONFIG_MTD_ONENAND
1268static int gpmc_probe_onenand_child(struct platform_device *pdev,
1269 struct device_node *child)
1270{
1271 u32 val;
1272 struct omap_onenand_platform_data *gpmc_onenand_data;
1273
1274 if (of_property_read_u32(child, "reg", &val) < 0) {
1275 dev_err(&pdev->dev, "%s has no 'reg' property\n",
1276 child->full_name);
1277 return -ENODEV;
1278 }
1279
1280 gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data),
1281 GFP_KERNEL);
1282 if (!gpmc_onenand_data)
1283 return -ENOMEM;
1284
1285 gpmc_onenand_data->cs = val;
1286 gpmc_onenand_data->of_node = child;
1287 gpmc_onenand_data->dma_channel = -1;
1288
1289 if (!of_property_read_u32(child, "dma-channel", &val))
1290 gpmc_onenand_data->dma_channel = val;
1291
1292 gpmc_onenand_init(gpmc_onenand_data);
1293
1294 return 0;
1295}
1296#else
1297static int gpmc_probe_onenand_child(struct platform_device *pdev,
1298 struct device_node *child)
1299{
1300 return 0;
1301}
1302#endif
1303
1304static int gpmc_probe_dt(struct platform_device *pdev)
1305{
1306 int ret;
1307 struct device_node *child;
1308 const struct of_device_id *of_id =
1309 of_match_device(gpmc_dt_ids, &pdev->dev);
1310
1311 if (!of_id)
1312 return 0;
1313
1314 for_each_node_by_name(child, "nand") {
1315 ret = gpmc_probe_nand_child(pdev, child);
1316 if (ret < 0) {
1317 of_node_put(child);
1318 return ret;
1319 }
1320 }
1321
1322 for_each_node_by_name(child, "onenand") {
1323 ret = gpmc_probe_onenand_child(pdev, child);
1324 if (ret < 0) {
1325 of_node_put(child);
1326 return ret;
1327 }
1328 }
1329 return 0;
1330}
1331#else
1332static int gpmc_probe_dt(struct platform_device *pdev)
1333{
1334 return 0;
1335}
1336#endif
1337
1124static int gpmc_probe(struct platform_device *pdev) 1338static int gpmc_probe(struct platform_device *pdev)
1125{ 1339{
1126 int rc; 1340 int rc;
@@ -1174,6 +1388,14 @@ static int gpmc_probe(struct platform_device *pdev)
1174 if (IS_ERR_VALUE(gpmc_setup_irq())) 1388 if (IS_ERR_VALUE(gpmc_setup_irq()))
1175 dev_warn(gpmc_dev, "gpmc_setup_irq failed\n"); 1389 dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
1176 1390
1391 rc = gpmc_probe_dt(pdev);
1392 if (rc < 0) {
1393 clk_disable_unprepare(gpmc_l3_clk);
1394 clk_put(gpmc_l3_clk);
1395 dev_err(gpmc_dev, "failed to probe DT parameters\n");
1396 return rc;
1397 }
1398
1177 return 0; 1399 return 0;
1178} 1400}
1179 1401
@@ -1191,6 +1413,7 @@ static struct platform_driver gpmc_driver = {
1191 .driver = { 1413 .driver = {
1192 .name = DEVICE_NAME, 1414 .name = DEVICE_NAME,
1193 .owner = THIS_MODULE, 1415 .owner = THIS_MODULE,
1416 .of_match_table = of_match_ptr(gpmc_dt_ids),
1194 }, 1417 },
1195}; 1418};
1196 1419
@@ -1214,6 +1437,13 @@ static int __init omap_gpmc_init(void)
1214 struct platform_device *pdev; 1437 struct platform_device *pdev;
1215 char *oh_name = "gpmc"; 1438 char *oh_name = "gpmc";
1216 1439
1440 /*
1441 * if the board boots up with a populated DT, do not
1442 * manually add the device from this initcall
1443 */
1444 if (of_have_populated_dt())
1445 return -ENODEV;
1446
1217 oh = omap_hwmod_lookup(oh_name); 1447 oh = omap_hwmod_lookup(oh_name);
1218 if (!oh) { 1448 if (!oh) {
1219 pr_err("Could not look up %s\n", oh_name); 1449 pr_err("Could not look up %s\n", oh_name);
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 0002d5e94f0d..1d333497cfcb 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1332,6 +1332,7 @@ static int omap_nand_probe(struct platform_device *pdev)
1332 dma_cap_mask_t mask; 1332 dma_cap_mask_t mask;
1333 unsigned sig; 1333 unsigned sig;
1334 struct resource *res; 1334 struct resource *res;
1335 struct mtd_part_parser_data ppdata = {};
1335 1336
1336 pdata = pdev->dev.platform_data; 1337 pdata = pdev->dev.platform_data;
1337 if (pdata == NULL) { 1338 if (pdata == NULL) {
@@ -1557,7 +1558,8 @@ static int omap_nand_probe(struct platform_device *pdev)
1557 goto out_release_mem_region; 1558 goto out_release_mem_region;
1558 } 1559 }
1559 1560
1560 mtd_device_parse_register(&info->mtd, NULL, NULL, pdata->parts, 1561 ppdata.of_node = pdata->of_node;
1562 mtd_device_parse_register(&info->mtd, NULL, &ppdata, pdata->parts,
1561 pdata->nr_parts); 1563 pdata->nr_parts);
1562 1564
1563 platform_set_drvdata(pdev, &info->mtd); 1565 platform_set_drvdata(pdev, &info->mtd);
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 065f3fe02a2f..eec2aedb4ab8 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -637,6 +637,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
637 struct onenand_chip *this; 637 struct onenand_chip *this;
638 int r; 638 int r;
639 struct resource *res; 639 struct resource *res;
640 struct mtd_part_parser_data ppdata = {};
640 641
641 pdata = pdev->dev.platform_data; 642 pdata = pdev->dev.platform_data;
642 if (pdata == NULL) { 643 if (pdata == NULL) {
@@ -767,7 +768,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
767 if ((r = onenand_scan(&c->mtd, 1)) < 0) 768 if ((r = onenand_scan(&c->mtd, 1)) < 0)
768 goto err_release_regulator; 769 goto err_release_regulator;
769 770
770 r = mtd_device_parse_register(&c->mtd, NULL, NULL, 771 ppdata.of_node = pdata->of_node;
772 r = mtd_device_parse_register(&c->mtd, NULL, &ppdata,
771 pdata ? pdata->parts : NULL, 773 pdata ? pdata->parts : NULL,
772 pdata ? pdata->nr_parts : 0); 774 pdata ? pdata->nr_parts : 0);
773 if (r) 775 if (r)
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h
index 24d32ca34bef..6bf9ef43ddb1 100644
--- a/include/linux/platform_data/mtd-nand-omap2.h
+++ b/include/linux/platform_data/mtd-nand-omap2.h
@@ -60,6 +60,8 @@ struct omap_nand_platform_data {
60 int devsize; 60 int devsize;
61 enum omap_ecc ecc_opt; 61 enum omap_ecc ecc_opt;
62 struct gpmc_nand_regs reg; 62 struct gpmc_nand_regs reg;
63};
64 63
64 /* for passing the partitions */
65 struct device_node *of_node;
66};
65#endif 67#endif
diff --git a/include/linux/platform_data/mtd-onenand-omap2.h b/include/linux/platform_data/mtd-onenand-omap2.h
index 685af7e8b120..e9a9fb188f97 100644
--- a/include/linux/platform_data/mtd-onenand-omap2.h
+++ b/include/linux/platform_data/mtd-onenand-omap2.h
@@ -29,5 +29,8 @@ struct omap_onenand_platform_data {
29 u8 flags; 29 u8 flags;
30 u8 regulator_can_sleep; 30 u8 regulator_can_sleep;
31 u8 skip_initial_unlocking; 31 u8 skip_initial_unlocking;
32
33 /* for passing the partitions */
34 struct device_node *of_node;
32}; 35};
33#endif 36#endif