Skip to content

Commit e7b11dc

Browse files
committed
ARM: OMAP2+: Fix onenand rate detection to avoid filesystem corruption
Commit 63aa945 ("memory: omap-gpmc: Add Kconfig option for debug") unified the GPMC debug for the SoCs with GPMC. The commit also left out the option for HWMOD_INIT_NO_RESET as we now require proper timings for GPMC to be able to remap GPMC devices out of address 0. Unfortunately on Nokia N900, onenand now only partially works with the device tree provided timings. It works enough to get detected but the clock rate supported by the onenand chip gets misdetected. This in turn causes the GPMC timings to be miscalculated and this leads into file system corruption on N900. Looks like onenand needs CS_CONFIG1 bit 27 WRITETYPE set for for sync write. This is needed also for async timings when we write to onenand with omap2_onenand_set_async_mode(). Without sync write bit set, the async read for the onenand ONENAND_REG_VERSION_ID will return 0xfff. Let's exit with an error if onenand rate is not detected. And let's remove the extra call to omap2_onenand_set_async_mode() as we only need to do this once at the end of omap2_onenand_setup_async(). Fixes: 63aa945 ("memory: omap-gpmc: Add Kconfig option for debug") Cc: stable@vger.kernel.org # v4.2+ Reported-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com> Tested-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com> Tested-by: Aaro Koskinen <aaro.koskinen@iki.fi> Signed-off-by: Tony Lindgren <tony@atomide.com>
1 parent 0b4d697 commit e7b11dc

1 file changed

Lines changed: 9 additions & 5 deletions

File tree

arch/arm/mach-omap2/gpmc-onenand.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
149149
freq = 104;
150150
break;
151151
default:
152-
freq = 54;
153-
break;
152+
pr_err("onenand rate not detected, bad GPMC async timings?\n");
153+
freq = 0;
154154
}
155155

156156
return freq;
@@ -271,6 +271,11 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
271271
struct gpmc_timings t;
272272
int ret;
273273

274+
/*
275+
* Note that we need to keep sync_write set for the call to
276+
* omap2_onenand_set_async_mode() to work to detect the onenand
277+
* supported clock rate for the sync timings.
278+
*/
274279
if (gpmc_onenand_data->of_node) {
275280
gpmc_read_settings_dt(gpmc_onenand_data->of_node,
276281
&onenand_async);
@@ -281,12 +286,9 @@ static int omap2_onenand_setup_async(void __iomem *onenand_base)
281286
else
282287
gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
283288
onenand_async.sync_read = false;
284-
onenand_async.sync_write = false;
285289
}
286290
}
287291

288-
omap2_onenand_set_async_mode(onenand_base);
289-
290292
omap2_onenand_calc_async_timings(&t);
291293

292294
ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async);
@@ -310,6 +312,8 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
310312
if (!freq) {
311313
/* Very first call freq is not known */
312314
freq = omap2_onenand_get_freq(gpmc_onenand_data, onenand_base);
315+
if (!freq)
316+
return -ENODEV;
313317
set_onenand_cfg(onenand_base);
314318
}
315319

0 commit comments

Comments
 (0)