Hi! On Mon, Oct 09, 2017 at 10:24:01PM +0800, kbuild test robot wrote: > Hi Ladislav, > > [auto build test WARNING on linus/master] > [also build test WARNING on v4.14-rc4 next-20170929] > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] > > url: https://github.com/0day-ci/linux/commits/Ladislav-Michl/memory-omap-gpmc-use-OneNAND-base-address-from-FDT/20171009-164338 > config: arm-allyesconfig (attached as .config) > compiler: arm-linux-gnueabi-gcc (Debian 6.1.1-9) 6.1.1 20160705 > reproduce: > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross > chmod +x ~/bin/make.cross > # save the attached .config to linux build tree > make.cross ARCH=arm > > Note: it may well be a FALSE warning. FWIW you are at least aware of it now. > http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings > > All warnings (new ones prefixed by >>): > > drivers/memory/omap-gpmc.c: In function 'gpmc_probe': > >> drivers/memory/omap-gpmc.c:1952:3: warning: 'cs' may be used uninitialized in this function [-Wmaybe-uninitialized] > dev_err(&pdev->dev, "cannot request GPMC CS %d\n", cs); > ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > drivers/memory/omap-gpmc.c:1929:6: note: 'cs' was declared here > u32 cs, val; > ^~ > > vim +/cs +1952 drivers/memory/omap-gpmc.c Fair enough kbuild test robot, what about a bit different approach? It boots to userland on OneNAND with the patch bellow, but it certainly needs some more testing. Releasing early to get some feedback :-) From: Ladislav Michl <ladis@xxxxxxxxxxxxxx> Subject: memory: omap-gpmc: use OneNAND base address from FDT OneNAND base address from FDT is ignored, so driver only works for bootloader configured chipselect. Let gpmc_probe_(generic_)child handle also onenand node and let it store FDT properties in platform data. Signed-off-by: Ladislav Michl <ladis@xxxxxxxxxxxxxx> diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c index 2944af820558..c1522f412aa0 100644 --- a/arch/arm/mach-omap2/gpmc-onenand.c +++ b/arch/arm/mach-omap2/gpmc-onenand.c @@ -35,17 +35,6 @@ static unsigned latency; static struct omap_onenand_platform_data *gpmc_onenand_data; -static struct resource gpmc_onenand_resource = { - .flags = IORESOURCE_MEM, -}; - -static struct platform_device gpmc_onenand_device = { - .name = "omap2-onenand", - .id = -1, - .num_resources = 1, - .resource = &gpmc_onenand_resource, -}; - static struct gpmc_settings onenand_async = { .device_width = GPMC_DEVWIDTH_16BIT, .mux_add_data = GPMC_MUX_AD, @@ -348,13 +337,12 @@ static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr) static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr) { - struct device *dev = &gpmc_onenand_device.dev; unsigned l = ONENAND_SYNC_READ | ONENAND_SYNC_READWRITE; int ret; ret = omap2_onenand_setup_async(onenand_base); if (ret) { - dev_err(dev, "unable to set to async mode\n"); + pr_err("OneNAND: unable to set to async mode\n"); return ret; } @@ -363,22 +351,18 @@ static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr) ret = omap2_onenand_setup_sync(onenand_base, freq_ptr); if (ret) - dev_err(dev, "unable to set to sync mode\n"); + pr_err("OneNAND: unable to set to sync mode\n"); return ret; } -int gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) +void gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) { - int err; - struct device *dev = &gpmc_onenand_device.dev; - gpmc_onenand_data = _onenand_data; gpmc_onenand_data->onenand_setup = gpmc_onenand_setup; - gpmc_onenand_device.dev.platform_data = gpmc_onenand_data; if (cpu_is_omap24xx() && (gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) { - dev_warn(dev, "OneNAND using only SYNC_READ on 24xx\n"); + pr_warn("OneNAND: using only SYNC_READ on 24xx\n"); gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE; gpmc_onenand_data->flags |= ONENAND_SYNC_READ; } @@ -387,23 +371,4 @@ int gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) gpmc_onenand_data->flags |= ONENAND_IN_OMAP34XX; else gpmc_onenand_data->flags &= ~ONENAND_IN_OMAP34XX; - - err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE, - (unsigned long *)&gpmc_onenand_resource.start); - if (err < 0) { - dev_err(dev, "Cannot request GPMC CS %d, error %d\n", - gpmc_onenand_data->cs, err); - return err; - } - - gpmc_onenand_resource.end = gpmc_onenand_resource.start + - ONENAND_IO_SIZE - 1; - - err = platform_device_register(&gpmc_onenand_device); - if (err) { - dev_err(dev, "Unable to register OneNAND device\n"); - gpmc_cs_free(gpmc_onenand_data->cs); - } - - return err; } diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 7059bbda2fac..9f416ee94324 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -1922,50 +1922,15 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, of_property_read_bool(np, "gpmc,time-para-granularity"); } -#if IS_ENABLED(CONFIG_MTD_ONENAND) -static int gpmc_probe_onenand_child(struct platform_device *pdev, - struct device_node *child) -{ - u32 val; - struct omap_onenand_platform_data *gpmc_onenand_data; - - if (of_property_read_u32(child, "reg", &val) < 0) { - dev_err(&pdev->dev, "%pOF has no 'reg' property\n", - child); - return -ENODEV; - } - - gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data), - GFP_KERNEL); - if (!gpmc_onenand_data) - return -ENOMEM; - - gpmc_onenand_data->cs = val; - gpmc_onenand_data->of_node = child; - gpmc_onenand_data->dma_channel = -1; - - if (!of_property_read_u32(child, "dma-channel", &val)) - gpmc_onenand_data->dma_channel = val; - - return gpmc_onenand_init(gpmc_onenand_data); -} -#else -static int gpmc_probe_onenand_child(struct platform_device *pdev, - struct device_node *child) -{ - return 0; -} -#endif - /** - * gpmc_probe_generic_child - configures the gpmc for a child device + * gpmc_probe_child - configures the gpmc for a child device * @pdev: pointer to gpmc platform device * @child: pointer to device-tree node for child device * * Allocates and configures a GPMC chip-select for a child device. * Returns 0 on success and appropriate negative error code on failure. */ -static int gpmc_probe_generic_child(struct platform_device *pdev, +static int gpmc_probe_child(struct platform_device *pdev, struct device_node *child) { struct gpmc_settings gpmc_s; @@ -2080,6 +2045,51 @@ static int gpmc_probe_generic_child(struct platform_device *pdev, /* disable write protect */ gpmc_configure(GPMC_CONFIG_WP, 0); gpmc_s.device_nand = true; + } else if (of_device_is_compatible(child, "ti,omap2-onenand")) { + struct platform_device *onenand_pdev; + struct omap_onenand_platform_data *gpmc_onenand_data = + devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data), + GFP_KERNEL); + + if (!gpmc_onenand_data) { + ret = -ENOMEM; + goto err; + } + + if (!of_property_read_u32(child, "dma-channel", &val)) + gpmc_onenand_data->dma_channel = val; + else + gpmc_onenand_data->dma_channel = -1; + + gpmc_onenand_data->cs = cs; + gpmc_onenand_data->of_node = child; + + onenand_pdev = platform_device_alloc("omap2-onenand", cs); + if (!onenand_pdev) { + ret = -ENOMEM; + goto err; + } + + ret = platform_device_add_resources(onenand_pdev, &res, 1); + if (ret) { + platform_device_put(onenand_pdev); + goto err; + } + + onenand_pdev->dev.platform_data = gpmc_onenand_data; + + ret = platform_device_add(onenand_pdev); + if (ret) { + platform_device_put(onenand_pdev); + goto err; + } + + /* Enable CS region */ + gpmc_cs_enable_mem(cs); + + gpmc_onenand_init(gpmc_onenand_data); + + return 0; } else { ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width); @@ -2194,11 +2204,7 @@ static void gpmc_probe_dt_children(struct platform_device *pdev) if (!child->name) continue; - if (of_node_cmp(child->name, "onenand") == 0) - ret = gpmc_probe_onenand_child(pdev, child); - else - ret = gpmc_probe_generic_child(pdev, child); - + ret = gpmc_probe_child(pdev, child); if (ret) { dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n", child->name, ret); diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h index fd0de00c0d77..4c4d8856f443 100644 --- a/include/linux/omap-gpmc.h +++ b/include/linux/omap-gpmc.h @@ -77,11 +77,7 @@ struct omap_nand_platform_data; struct omap_onenand_platform_data; #if IS_ENABLED(CONFIG_MTD_ONENAND_OMAP2) -extern int gpmc_onenand_init(struct omap_onenand_platform_data *d); +extern void gpmc_onenand_init(struct omap_onenand_platform_data *d); #else -#define board_onenand_data NULL -static inline int gpmc_onenand_init(struct omap_onenand_platform_data *d) -{ - return 0; -} +static inline void gpmc_onenand_init(struct omap_onenand_platform_data *d) { } #endif -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html