Skip to content

Commit 1da8869

Browse files
ndreyscomputersforpeace
authored andcommitted
mtd: dataflash: Make use of "extened device information"
In anticipation of supporting chips that need it, extend the size of struct flash_info's 'jedec_id' field to make room 2 byte of extended device information as well as add code to fetch this data during jedec_probe(). Cc: [email protected] Cc: David Woodhouse <[email protected]> Cc: Brian Norris <[email protected]> Cc: Boris Brezillon <[email protected]> Cc: Marek Vasut <[email protected]> Cc: Richard Weinberger <[email protected]> Cc: Cyrille Pitchen <[email protected]> Cc: [email protected] Acked-by: Marek Vasut <[email protected]> Tested-by: Chris Healy <[email protected]> Signed-off-by: Andrey Smirnov <[email protected]> Signed-off-by: Brian Norris <[email protected]>
1 parent a296a1b commit 1da8869

File tree

1 file changed

+57
-31
lines changed

1 file changed

+57
-31
lines changed

drivers/mtd/devices/mtd_dataflash.c

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@
8484

8585
#define CFI_MFR_ATMEL 0x1F
8686

87+
#define DATAFLASH_SHIFT_EXTID 24
88+
#define DATAFLASH_SHIFT_ID 40
89+
8790
struct dataflash {
8891
u8 command[4];
8992
char name[24];
@@ -687,14 +690,15 @@ struct flash_info {
687690
/* JEDEC id has a high byte of zero plus three data bytes:
688691
* the manufacturer id, then a two byte device id.
689692
*/
690-
u32 jedec_id;
693+
u64 jedec_id;
691694

692695
/* The size listed here is what works with OP_ERASE_PAGE. */
693696
unsigned nr_pages;
694697
u16 pagesize;
695698
u16 pageoffset;
696699

697700
u16 flags;
701+
#define SUP_EXTID 0x0004 /* supports extended ID data */
698702
#define SUP_POW2PS 0x0002 /* supports 2^N byte pages */
699703
#define IS_POW2PS 0x0001 /* uses 2^N byte pages */
700704
};
@@ -734,42 +738,18 @@ static struct flash_info dataflash_data[] = {
734738
{ "at45db642d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS},
735739
};
736740

737-
static struct flash_info *jedec_probe(struct spi_device *spi)
741+
static struct flash_info *jedec_lookup(struct spi_device *spi,
742+
u64 jedec, bool use_extid)
738743
{
739-
int ret;
740-
u8 code = OP_READ_ID;
741-
u8 id[3];
742-
u32 jedec;
743744
struct flash_info *info;
744745
int status;
745746

746-
/*
747-
* JEDEC also defines an optional "extended device information"
748-
* string for after vendor-specific data, after the three bytes
749-
* we use here. Supporting some chips might require using it.
750-
*
751-
* If the vendor ID isn't Atmel's (0x1f), assume this call failed.
752-
* That's not an error; only rev C and newer chips handle it, and
753-
* only Atmel sells these chips.
754-
*/
755-
ret = spi_write_then_read(spi, &code, 1, id, 3);
756-
if (ret < 0) {
757-
dev_dbg(&spi->dev, "error %d reading JEDEC ID\n", ret);
758-
return ERR_PTR(ret);
759-
}
760-
761-
if (id[0] != CFI_MFR_ATMEL)
762-
return NULL;
763-
764-
jedec = id[0];
765-
jedec = jedec << 8;
766-
jedec |= id[1];
767-
jedec = jedec << 8;
768-
jedec |= id[2];
769-
770747
for (info = dataflash_data;
771748
info < dataflash_data + ARRAY_SIZE(dataflash_data);
772749
info++) {
750+
if (use_extid && !(info->flags & SUP_EXTID))
751+
continue;
752+
773753
if (info->jedec_id == jedec) {
774754
dev_dbg(&spi->dev, "OTP, sector protect%s\n",
775755
(info->flags & SUP_POW2PS) ?
@@ -793,12 +773,58 @@ static struct flash_info *jedec_probe(struct spi_device *spi)
793773
}
794774
}
795775

776+
return ERR_PTR(-ENODEV);
777+
}
778+
779+
static struct flash_info *jedec_probe(struct spi_device *spi)
780+
{
781+
int ret;
782+
u8 code = OP_READ_ID;
783+
u64 jedec;
784+
u8 id[sizeof(jedec)] = {0};
785+
const unsigned int id_size = 5;
786+
struct flash_info *info;
787+
788+
/*
789+
* JEDEC also defines an optional "extended device information"
790+
* string for after vendor-specific data, after the three bytes
791+
* we use here. Supporting some chips might require using it.
792+
*
793+
* If the vendor ID isn't Atmel's (0x1f), assume this call failed.
794+
* That's not an error; only rev C and newer chips handle it, and
795+
* only Atmel sells these chips.
796+
*/
797+
ret = spi_write_then_read(spi, &code, 1, id, id_size);
798+
if (ret < 0) {
799+
dev_dbg(&spi->dev, "error %d reading JEDEC ID\n", ret);
800+
return ERR_PTR(ret);
801+
}
802+
803+
if (id[0] != CFI_MFR_ATMEL)
804+
return NULL;
805+
806+
jedec = be64_to_cpup((__be64 *)id);
807+
808+
/*
809+
* First, try to match device using extended device
810+
* information
811+
*/
812+
info = jedec_lookup(spi, jedec >> DATAFLASH_SHIFT_EXTID, true);
813+
if (!IS_ERR(info))
814+
return info;
815+
/*
816+
* If that fails, make another pass using regular ID
817+
* information
818+
*/
819+
info = jedec_lookup(spi, jedec >> DATAFLASH_SHIFT_ID, false);
820+
if (!IS_ERR(info))
821+
return info;
796822
/*
797823
* Treat other chips as errors ... we won't know the right page
798824
* size (it might be binary) even when we can tell which density
799825
* class is involved (legacy chip id scheme).
800826
*/
801-
dev_warn(&spi->dev, "JEDEC id %06x not handled\n", jedec);
827+
dev_warn(&spi->dev, "JEDEC id %016llx not handled\n", jedec);
802828
return ERR_PTR(-ENODEV);
803829
}
804830

0 commit comments

Comments
 (0)