From patchwork Tue Oct 14 05:42:07 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 399352 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 4924A14007D for ; Tue, 14 Oct 2014 16:46:19 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id AD104A77F9; Tue, 14 Oct 2014 07:45:13 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2HwrgIuhWf2z; Tue, 14 Oct 2014 07:45:13 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 55CE7A780A; Tue, 14 Oct 2014 07:44:12 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 38D55A751F for ; Tue, 14 Oct 2014 07:43:20 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id rsaR5YYNxxsf for ; Tue, 14 Oct 2014 07:43:20 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-oi0-f73.google.com (mail-oi0-f73.google.com [209.85.218.73]) by theia.denx.de (Postfix) with ESMTPS id 4F58BA7516 for ; Tue, 14 Oct 2014 07:43:15 +0200 (CEST) Received: by mail-oi0-f73.google.com with SMTP id u20so2857954oif.2 for ; Mon, 13 Oct 2014 22:43:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=UP/nMnqbEGdT1DTC/w1YWpcTRfkuHGSlaqzKWUq0gks=; b=Nt6TNmXc9XfsbhMk1QpMo1zsGlsuFU3vpIUYz7FgHdQXDGbB0+GcoP4m6vD2Gm/MYy ypMMyLeokj/Z683QVA9G4Njr3zuUg19zEkGPhlW6i4gEypkiX3PKgpYjgxihUjvl9+V+ QHVl+e5nhthlQgaibODi6YsbNcFe5QYDjZAEYeF3daWyWU0zKLDUgy5Hq5a0nwHhdCbe l+RnTcOdNdqrbzKPab+u0BJ2XeI2rbwb6w7Z+FlfUUkuiDAB1lBI7DIC5S8SJwyXmxnv nUn938c0487vRfzmORynkVgxrh+7kLehTc4QHvGmujPTWNps0/gB5xw8FsqHyYHWdQO3 oMvQ== X-Gm-Message-State: ALoCoQlTcoYXpfrGWAj5N/TX1RxXA0a+CWbs3Jp9avpnagyApXdsVuaAYLY7ZARysTUM7ZeR445i X-Received: by 10.43.155.13 with SMTP id lg13mr2161692icc.31.1413265394207; Mon, 13 Oct 2014 22:43:14 -0700 (PDT) Received: from corpmail-nozzle1-1.hot.corp.google.com ([100.108.1.104]) by gmr-mx.google.com with ESMTPS id t28si807977yhb.4.2014.10.13.22.43.13 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Oct 2014 22:43:14 -0700 (PDT) Received: from kaki.bld.corp.google.com ([172.29.216.32]) by corpmail-nozzle1-1.hot.corp.google.com with ESMTP id UK3byWnA.2; Mon, 13 Oct 2014 22:43:14 -0700 Received: by kaki.bld.corp.google.com (Postfix, from userid 121222) id 5B20722126E; Mon, 13 Oct 2014 23:43:13 -0600 (MDT) From: Simon Glass To: U-Boot Mailing List Date: Mon, 13 Oct 2014 23:42:07 -0600 Message-Id: <1413265336-9571-21-git-send-email-sjg@chromium.org> X-Mailer: git-send-email 2.1.0.rc2.206.gedb03e5 In-Reply-To: <1413265336-9571-1-git-send-email-sjg@chromium.org> References: <1413265336-9571-1-git-send-email-sjg@chromium.org> Cc: u-boot-review@google.com, Jagannadha Sutradharudu Teki Subject: [U-Boot] [PATCH v4 20/29] dm: Convert spi_flash_probe() and 'sf probe' to use driver model X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.13 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de We want the SPI flash probing feature to operate as a standard driver. Add a driver for the basic probing feature used by most boards. This will be activated by device_probe() as with any other driver. The 'sf probe' command currently keeps track of the SPI slave that it last used. This doesn't work with driver model, since some other driver or system may have probed the device and have access to it too. On the other hand, if we try to probe a device twice the second probe is a nop with driver model. Fix this by searching for the matching device, removing it, and then probing it again. This should work as expected regardless of other device activity. Signed-off-by: Simon Glass Reviewed-by: Jagannadha Sutradharudu Teki --- Changes in v4: None Changes in v3: - Add a debug() in the probe method - Make sure the old device is both removed and unbound in 'sf probe' Changes in v2: None common/cmd_sf.c | 25 ++++++++++++++++++ drivers/mtd/spi/sf_probe.c | 66 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/common/cmd_sf.c b/common/cmd_sf.c index 42d89d4..95a6f89 100644 --- a/common/cmd_sf.c +++ b/common/cmd_sf.c @@ -8,11 +8,13 @@ #include #include +#include #include #include #include #include +#include static struct spi_flash *flash; @@ -81,7 +83,12 @@ static int do_spi_flash_probe(int argc, char * const argv[]) unsigned int speed = CONFIG_SF_DEFAULT_SPEED; unsigned int mode = CONFIG_SF_DEFAULT_MODE; char *endp; +#ifdef CONFIG_DM_SPI_FLASH + struct udevice *new, *bus_dev; + int ret; +#else struct spi_flash *new; +#endif if (argc >= 2) { cs = simple_strtoul(argv[1], &endp, 0); @@ -109,6 +116,23 @@ static int do_spi_flash_probe(int argc, char * const argv[]) return -1; } +#ifdef CONFIG_DM_SPI_FLASH + /* Remove the old device, otherwise probe will just be a nop */ + ret = spi_find_bus_and_cs(bus, cs, &bus_dev, &new); + if (!ret) { + device_remove(new); + device_unbind(new); + } + flash = NULL; + ret = spi_flash_probe_bus_cs(bus, cs, speed, mode, &new); + if (ret) { + printf("Failed to initialize SPI flash at %u:%u (error %d)\n", + bus, cs, ret); + return 1; + } + + flash = new->uclass_priv; +#else new = spi_flash_probe(bus, cs, speed, mode); if (!new) { printf("Failed to initialize SPI flash at %u:%u\n", bus, cs); @@ -118,6 +142,7 @@ static int do_spi_flash_probe(int argc, char * const argv[]) if (flash) spi_flash_free(flash); flash = new; +#endif return 0; } diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 212a825..2636426 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -131,13 +132,15 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode, flash->dual_flash = flash->spi->option; /* Assign spi_flash ops */ +#ifndef CONFIG_DM_SPI_FLASH flash->write = spi_flash_cmd_write_ops; -#ifdef CONFIG_SPI_FLASH_SST +#if defined(CONFIG_SPI_FLASH_SST) if (params->flags & SST_WP) flash->write = sst_write_wp; #endif flash->erase = spi_flash_cmd_erase_ops; flash->read = spi_flash_cmd_read_ops; +#endif /* Compute the flash size */ flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0; @@ -398,7 +401,8 @@ err_read_id: return ret; } -static struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus) +#ifndef CONFIG_DM_SPI_FLASH +struct spi_flash *spi_flash_probe_tail(struct spi_slave *bus) { struct spi_flash *flash; @@ -443,3 +447,61 @@ void spi_flash_free(struct spi_flash *flash) spi_free_slave(flash->spi); free(flash); } + +#else /* defined CONFIG_DM_SPI_FLASH */ + +static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len, + void *buf) +{ + struct spi_flash *flash = dev->uclass_priv; + + return spi_flash_cmd_read_ops(flash, offset, len, buf); +} + +int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len, + const void *buf) +{ + struct spi_flash *flash = dev->uclass_priv; + + return spi_flash_cmd_write_ops(flash, offset, len, buf); +} + +int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len) +{ + struct spi_flash *flash = dev->uclass_priv; + + return spi_flash_cmd_erase_ops(flash, offset, len); +} + +int spi_flash_std_probe(struct udevice *dev) +{ + struct spi_slave *slave = dev_get_parentdata(dev); + struct spi_flash *flash; + + flash = dev->uclass_priv; + flash->dev = dev; + debug("%s: slave=%p, cs=%d\n", __func__, slave, slave->cs); + return spi_flash_probe_slave(slave, flash); +} + +static const struct dm_spi_flash_ops spi_flash_std_ops = { + .read = spi_flash_std_read, + .write = spi_flash_std_write, + .erase = spi_flash_std_erase, +}; + +static const struct udevice_id spi_flash_std_ids[] = { + { .compatible = "spi-flash" }, + { } +}; + +U_BOOT_DRIVER(spi_flash_std) = { + .name = "spi_flash_std", + .id = UCLASS_SPI_FLASH, + .of_match = spi_flash_std_ids, + .probe = spi_flash_std_probe, + .priv_auto_alloc_size = sizeof(struct spi_flash), + .ops = &spi_flash_std_ops, +}; + +#endif /* CONFIG_DM_SPI_FLASH */