Messages in this thread | | | Date | Tue, 20 Sep 2016 18:25:39 +0200 | From | Boris Brezillon <> | Subject | Re: [PATCH v5] mtd: spi-nor: Add support for S3AN spi-nor devices |
| |
On Fri, 16 Sep 2016 21:33:52 +0200 Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> wrote:
> Xilinx Spartan-3AN FPGAs contain an In-System Flash where they keep > their configuration data and (optionally) some user data. > > The protocol of this flash follows most of the spi-nor standard. With > the following differences: > > - Page size might not be a power of two. > - The address calculation (default addressing mode). > - The spi nor commands used. > > Protocol is described on Xilinx User Guide UG333 > > Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> > --- > v5: > -Rebase on top of l2-mtd/master > Suggested by: Cyrille Pitchen <cyrille.pitchen@atmel.com>: > -Fix to+1 bug > -Move all address conversions to spi-nor > -Replace pr_dev with dev_err > > v4: > -Rebase on top of l2-mtd/master > > v3: > -Rebase on top of mtd-next > -Rename ADDR_NATIVE to ADDR_DEFAULT to follow UG333 naming > -Fix bug on probe > > v2: Suggested by Brian Norris <computersforpeace@gmail.com> > > -Remove inline qualifier > -Improve documentation of Default Addressing Mode > -Convert function callbacks into SNOR_F_ > -Fix missmatch braces > -Improve documentation of SPI_S3AN flag > drivers/mtd/spi-nor/spi-nor.c | 122 ++++++++++++++++++++++++++++++++++++++++-- > include/linux/mtd/spi-nor.h | 12 +++++ > 2 files changed, 129 insertions(+), 5 deletions(-) > > diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c > index d0fc165d7d66..94c5fd870058 100644 > --- a/drivers/mtd/spi-nor/spi-nor.c > +++ b/drivers/mtd/spi-nor/spi-nor.c
[...]
> /* > + * This code converts an address to the Default Address Mode, that has non > + * power of two page sizes. We must support this mode because it is the default > + * mode supported by Xilinx tools, it can access the whole flash area and > + * changing over to the Power-of-two mode is irreversible and corrupts the > + * original data. > + */ > +static loff_t spi_nor_s3an_addr_convert(struct spi_nor *nor, unsigned int addr) > +{ > + unsigned int offset; > + > + offset = (nor->page_size == 264) ? (addr % 264) : (addr % 528); > + > + return ((addr - offset) << 1) | offset; > +}
[...]
> > @@ -1049,7 +1111,12 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, > return ret; > > while (len) { > - ret = nor->read(nor, from, len, buf); > + loff_t addr = from; > + > + if (nor->flags & SNOR_F_S3AN_ADDR_DEFAULT) > + addr = spi_nor_s3an_addr_convert(nor, addr);
Don't know if that's important since NOR flashes are unlikely to be larger than 4GB, but you're casting a loff_t (unsigned long long) type to an unsigned int (spi_nor_s3an_addr_convert() is taking an unsigned int).
| |