Skip to content

Commit b027274

Browse files
jkrzysztDavid Woodhouse
authored andcommitted
mtd: ams-delta: fix request_mem_region() failure
A call to request_mem_region() has been introduced in the omap-gpio driver recently (commit 96751fc, "gpio/omap: Use devm_ API and add request_mem_region"). This change prevented the Amstrad Delta NAND driver, which was doing the same in order to take control over OMAP MPU I/O lines that the NAND device hangs off, from loading successfully. The I/O lines and corresponding registers used by the NAND driver are a subset of those used for the GPIO function. Then, to avoid run time collisions, all MPUIO GPIO lines should be marked as requested while initializing the NAND driver, and vice versa, a single MPUIO GPIO line already requested before the NAND driver initialization is attempted should prevent the NAND device from being started successfully. There is another driver, omap-keypad, which also manipulates MPUIO registers, but has never been calling request_mem_region() on startup, so it's not affected by the change in the gpio-omap and works correctly. It uses the depreciated omap_read/write functions for accessing MPUIO registers. Unlike the NAND driver, these I/O lines and registers are separate from those used by the GPIO driver. However, both register sets are non-contiguous and overlapping, so it would be impractical to request the two sets separately, one from the gpio-omap, the other form the omap-keypad driver. In order to solve all these issues correctly, a solution first suggested by Artem Bityutskiy, then closer specified by Tony Lindgren while they commented the initial version of this fix, should be implemented. The gpio-omap driver should export a few functions which would allow the other two drivers to access MPUIO registers in a safe manner instead of trying to manage them in parallel to the GPIO driver. However, such a big change, affecting 3 drivers all together, is not suitable for the rc cycle, and should be prepared for the merge window. Then, an alternative solution is proposed as a regression fix. For the ams-delta NAND driver to initialize correctly in coexistence with the changed GPIO driver, drop the request_mem_region() call from the former, especially as this call is going to be removed while the long-term solution is implemented. Tested on Amstrad Delta. Signed-off-by: Janusz Krzysztofik <[email protected]> Acked-by: Tony Lindgren <[email protected]> Signed-off-by: Artem Bityutskiy <[email protected]> Signed-off-by: David Woodhouse <[email protected]>
1 parent 226bb7d commit b027274

File tree

1 file changed

+6
-11
lines changed

1 file changed

+6
-11
lines changed

drivers/mtd/nand/ams-delta.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -212,18 +212,17 @@ static int __devinit ams_delta_init(struct platform_device *pdev)
212212
/* Link the private data with the MTD structure */
213213
ams_delta_mtd->priv = this;
214214

215-
if (!request_mem_region(res->start, resource_size(res),
216-
dev_name(&pdev->dev))) {
217-
dev_err(&pdev->dev, "request_mem_region failed\n");
218-
err = -EBUSY;
219-
goto out_free;
220-
}
215+
/*
216+
* Don't try to request the memory region from here,
217+
* it should have been already requested from the
218+
* gpio-omap driver and requesting it again would fail.
219+
*/
221220

222221
io_base = ioremap(res->start, resource_size(res));
223222
if (io_base == NULL) {
224223
dev_err(&pdev->dev, "ioremap failed\n");
225224
err = -EIO;
226-
goto out_release_io;
225+
goto out_free;
227226
}
228227

229228
this->priv = io_base;
@@ -271,8 +270,6 @@ static int __devinit ams_delta_init(struct platform_device *pdev)
271270
platform_set_drvdata(pdev, NULL);
272271
gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB);
273272
iounmap(io_base);
274-
out_release_io:
275-
release_mem_region(res->start, resource_size(res));
276273
out_free:
277274
kfree(ams_delta_mtd);
278275
out:
@@ -285,15 +282,13 @@ static int __devinit ams_delta_init(struct platform_device *pdev)
285282
static int __devexit ams_delta_cleanup(struct platform_device *pdev)
286283
{
287284
void __iomem *io_base = platform_get_drvdata(pdev);
288-
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
289285

290286
/* Release resources, unregister device */
291287
nand_release(ams_delta_mtd);
292288

293289
gpio_free_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio));
294290
gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB);
295291
iounmap(io_base);
296-
release_mem_region(res->start, resource_size(res));
297292

298293
/* Free the MTD device structure */
299294
kfree(ams_delta_mtd);

0 commit comments

Comments
 (0)